simplesamlphp-1.19.1/0000755000000000000000000000000014042503574013163 5ustar rootrootsimplesamlphp-1.19.1/data/0000755000000000000000000000000014042503574014074 5ustar rootrootsimplesamlphp-1.19.1/metadata-templates/0000755000000000000000000000000014042503475016737 5ustar rootrootsimplesamlphp-1.19.1/metadata-templates/shib13-idp-remote.php0000644000000000000000000000073014042503475022604 0ustar rootroot 'https://idp.example.org/shibboleth-idp/SSO', 'certificate' => 'example.pem', ]; */ simplesamlphp-1.19.1/metadata-templates/shib13-idp-hosted.php0000644000000000000000000000136014042503475022577 0ustar rootroot '__DEFAULT__', // X.509 key and certificate. Relative to the cert directory. 'privatekey' => 'server.pem', 'certificate' => 'server.crt', /* * Authentication source to use. Must be one that is configured in * 'config/authsources.php'. */ 'auth' => 'example-userpass', ]; simplesamlphp-1.19.1/metadata-templates/shib13-sp-remote.php0000644000000000000000000000075514042503475022461 0ustar rootroot 'http://sp.shiblab.feide.no/Shibboleth.sso/SAML/POST', 'audience' => 'urn:mace:feide:shiblab', 'base64attributes' => false, ]; simplesamlphp-1.19.1/metadata-templates/adfs-idp-hosted.php0000644000000000000000000000046714042503475022432 0ustar rootroot '__DEFAULT__', 'privatekey' => 'server.pem', 'certificate' => 'server.crt', 'auth' => 'example-userpass', 'authproc' => [ // Convert LDAP names to WS-Fed Claims. 100 => ['class' => 'core:AttributeMap', 'name2claim'], ], ]; simplesamlphp-1.19.1/metadata-templates/adfs-sp-remote.php0000644000000000000000000000044714042503475022303 0ustar rootroot 'https://localhost/adfs/ls/', 'simplesaml.nameidattribute' => 'uid', 'authproc' => [ 50 => [ 'class' => 'core:AttributeLimit', 'cn', 'mail', 'uid', 'eduPersonAffiliation', ], ], ]; simplesamlphp-1.19.1/metadata-templates/wsfed-sp-hosted.php0000644000000000000000000000024614042503475022466 0ustar rootroot '__DEFAULT__', ]; simplesamlphp-1.19.1/metadata-templates/wsfed-idp-remote.php0000644000000000000000000000034314042503475022623 0ustar rootroot 'https://localhost:9031/idp/prp.wsf', 'certificate' => 'pingfed-localhost.pem', ]; simplesamlphp-1.19.1/metadata-templates/shib13-sp-hosted.php0000644000000000000000000000050614042503475022446 0ustar rootroot '__DEFAULT__', ]; simplesamlphp-1.19.1/metadata-templates/saml20-idp-remote.php0000644000000000000000000000032614042503475022612 0ustar rootroot 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'SingleLogoutService' => 'https://saml2sp.example.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp', ]; /* * This example shows an example config that works with Google Workspace (G Suite / Google Apps) for education. * What is important is that you have an attribute in your IdP that maps to the local part of the email address at * Google Workspace. In example, if your Google account is foo.com, and you have a user that has an email john@foo.com, then you * must set the simplesaml.nameidattribute to be the name of an attribute that for this user has the value of 'john'. */ $metadata['google.com'] = [ 'AssertionConsumerService' => 'https://www.google.com/a/g.feide.no/acs', 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', 'simplesaml.nameidattribute' => 'uid', 'simplesaml.attributes' => false, ]; $metadata['https://legacy.example.edu'] = [ 'AssertionConsumerService' => 'https://legacy.example.edu/saml/acs', /* * Currently, SimpleSAMLphp defaults to the SHA-256 hashing algorithm. * Uncomment the following option to use SHA-1 for signatures directed * at this specific service provider if it does not support SHA-256 yet. * * WARNING: SHA-1 is disallowed starting January the 1st, 2014. * Please refer to the following document for more information: * http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf */ //'signature.algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1', ]; simplesamlphp-1.19.1/metadata-templates/saml20-idp-hosted.php0000644000000000000000000000274414042503475022613 0ustar rootroot '__DEFAULT__', // X.509 key and certificate. Relative to the cert directory. 'privatekey' => 'server.pem', 'certificate' => 'server.crt', /* * Authentication source to use. Must be one that is configured in * 'config/authsources.php'. */ 'auth' => 'example-userpass', /* Uncomment the following to use the uri NameFormat on attributes. */ /* 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', 'authproc' => [ // Convert LDAP names to oids. 100 => ['class' => 'core:AttributeMap', 'name2oid'], ], */ /* * Uncomment the following to specify the registration information in the * exported metadata. Refer to: * http://docs.oasis-open.org/security/saml/Post2.0/saml-metadata-rpi/v1.0/cs01/saml-metadata-rpi-v1.0-cs01.html * for more information. */ /* 'RegistrationInfo' => [ 'authority' => 'urn:mace:example.org', 'instant' => '2008-01-17T11:28:03Z', 'policies' => [ 'en' => 'http://example.org/policy', 'es' => 'http://example.org/politica', ], ], */ ]; simplesamlphp-1.19.1/package.json0000644000000000000000000000206614042503475015455 0ustar rootroot{ "name": "simplesamlphp", "main": "index.js", "repository": "https://github.com/simplesamlphp/simplesamlphp", "author": "olimpiam", "license": "MIT", "engines": { "node": ">=10.0.0", "npm": ">=6.0.0" }, "scripts": { "post-intall": "minimum-node-version", "clean": "rm -rf www/assets/css/* && rm -rf www/assets/js/*", "build": "webpack -p" }, "dependencies": { "@fortawesome/fontawesome-free": "^5.15.3", "clipboard": "^2.0.8", "es6-shim": "^0.35.6", "highlight.js": "^10.7.2", "jquery": "^3.6.0", "jquery-ui": "^1.12.1", "minimum-node-version": "^3.0.0", "purecss": "^2.0.5", "reset-css": "^5.0.1", "selectize": "^0.12.6" }, "devDependencies": { "@babel/core": "^7.13.16", "babel-loader": "^8.2.2", "copy-webpack-plugin": "^6.4.1", "css-loader": "^3.6.0", "expose-loader": "^0.7.5", "mini-css-extract-plugin": "^0.10.1", "node-sass": "^4.14.1", "sass-loader": "^9.0.3", "style-loader": "^1.3.0", "webpack": "^4.46.0", "webpack-cli": "^3.3.12" } } simplesamlphp-1.19.1/tests/0000755000000000000000000000000014042503475014325 5ustar rootrootsimplesamlphp-1.19.1/tests/_autoload_modules.php0000644000000000000000000000253314042503475020540 0ustar rootroot\Auth\Process * * @param string $className Name of the class. * @return void */ function sspmodTestClassAutoloadPSR4(string $className): void { $elements = explode('\\', $className); if ($elements[0] === '') { // class name starting with /, ignore array_shift($elements); } if (count($elements) < 5) { return; // it can't be a module test class } if (array_shift($elements) !== 'SimpleSAML') { return; // the first element is not "SimpleSAML" } if (array_shift($elements) !== 'Test') { return; // the second element is not "test" } if (array_shift($elements) !== 'Module') { return; // the third element is not "module" } // this is a SimpleSAMLphp module test class following PSR-4 $module = array_shift($elements); $moduleTestDir = __DIR__ . '/modules/' . $module; $file = $moduleTestDir . '/lib/' . implode('/', $elements) . '.php'; if (file_exists($file)) { require_once($file); } } spl_autoload_register('sspmodTestClassAutoloadPSR4'); simplesamlphp-1.19.1/tests/routers/0000755000000000000000000000000014042503475016030 5ustar rootrootsimplesamlphp-1.19.1/tests/routers/configLoader.php0000644000000000000000000000343014042503475021135 0ustar rootrootstart(); * 3. Get the PID of the server once it has started: * $pid = $server->getPid(); * 4. Build the path to the file that this script will use: * $file = sys_get_temp_dir().'/'.$pid.'.lock'; * 5. Dump the configuration array to the file: * file_put_contents("get($query, $parameters); * 7. Remove the temporary file when done: * unlink($file); */ include_once(sys_get_temp_dir() . '/' . getmypid() . '.lock'); // load SimpleSAMLphp's autoloader require_once(dirname(dirname(dirname(__FILE__))) . '/vendor/autoload.php'); // initialize configuration if (isset($config)) { Configuration::loadFromArray($config, '[ARRAY]', 'simplesaml'); } // let the script proceed // see: http://php.net/manual/en/features.commandline.webserver.php return false; simplesamlphp-1.19.1/tests/BuiltInServer.php0000644000000000000000000001477214042503475017606 0ustar rootroot * @package SimpleSAMLphp */ class BuiltInServer { /** * The PID of the running server. * * @var int */ protected $pid = 0; /** * The address (host:port) where the server is listening for connections after being started. * * @var string */ protected $address = 'example.org'; /** * The name of a "router" file to run for every request performed to this server. * * @var string */ protected $router = ''; /** * The document root of the server. * * @var string */ protected $docroot; /** * BuiltInServer constructor. * * @param string|null $router The name of a "router" file to run first for every request performed to this server. * @param string|null $docroot The document root to use when starting the server. * * @see http://php.net/manual/en/features.commandline.webserver.php */ public function __construct($router = null, $docroot = null) { if (!is_null($router)) { $this->setRouter($router); } if (!is_null($docroot)) { $this->docroot = $docroot; } else { $this->docroot = dirname(dirname(__FILE__)) . '/www/'; } // Rationalize docroot $this->docroot = str_replace('\\', '/', $this->docroot); $this->docroot = rtrim($this->docroot, '/'); } /** * Start the built-in server in a random port. * * This method will wait up to 5 seconds for the server to start. When it returns an address, it is guaranteed that * the server has started and is listening for connections. If it returns the default value on the other hand, * there will be no guarantee that the server started properly. * * @return string The address where the server is listening for connections, or false if the server failed to start * for some reason. * * @todo This method should be resilient to clashes in the randomly-picked port number. */ public function start() { $port = mt_rand(1025, 65535); $this->address = 'localhost:' . $port; if (System::getOS() === System::WINDOWS) { $command = sprintf( 'powershell $proc = start-process php -ArgumentList (\'-S %s\', \'-t %s\', \'%s\') ' . '-Passthru; Write-output $proc.Id;', $this->address, $this->docroot, $this->router ); } else { $command = sprintf( 'php -S %s -t %s %s >> /dev/null 2>&1 & echo $!', $this->address, $this->docroot, $this->router ); } // execute the command and store the process ID $output = []; exec($command, $output); $this->pid = intval($output[0]); // wait until it's listening for connections to avoid race conditions $start = microtime(true); do { $sock = @fsockopen('localhost', $port, $errno, $errstr, 10); if ($sock === false) { // set a 5 secs timeout waiting for the server to start if (microtime(true) > $start + 5) { $this->pid = 0; // signal failure break; } } } while ($sock === false); if ($sock !== false) { fclose($sock); } return $this->address; } /** * Stop the built-in server. * @return void */ public function stop() { if ($this->pid === 0) { return; } elseif (System::getOS() === System::WINDOWS) { exec('taskkill /PID ' . $this->pid); } else { exec('kill ' . $this->pid); } $this->pid = 0; } /** * Get the PID of the running server. * * @return int The PID of the server, or 0 if the server was not started. */ public function getPid() { return $this->pid; } /** * Get the name of the "router" file. * * @return string The name of the "router" file. */ public function getRouter() { return $this->router; } /** * Set the "router" file. * * @param string $router The name of a "router" file to use when starting the server. * @return void */ public function setRouter($router) { $file = dirname(dirname(__FILE__)) . '/tests/routers/' . $router . '.php'; if (!file_exists($file)) { throw new \InvalidArgumentException('Unknown router "' . $router . '".'); } $this->router = $file; } /** * This function performs an HTTP GET request to the built-in server. * * @param string $query The query to perform. * @param array $parameters An array (can be empty) with parameters for the requested URI. * @param array $curlopts An array (can be empty) with options for cURL. * * @return array The response obtained from the built-in server. */ public function get($query, $parameters, $curlopts = []) { $ch = curl_init(); $url = 'http://' . $this->address . $query; $url .= (!empty($parameters)) ? '?' . http_build_query($parameters) : ''; curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => 1, CURLOPT_HEADER => 1, ]); curl_setopt_array($ch, $curlopts); /** @psalm-var array|false $resp RETURNTRANSFER was set to true */ $resp = curl_exec($ch); if ($resp === false) { throw new \Exception("Unable to contact: " . $url); } $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); list($header, $body) = explode("\r\n\r\n", $resp, 2); $raw_headers = explode("\r\n", $header); array_shift($raw_headers); $headers = []; foreach ($raw_headers as $header) { list($name, $value) = explode(':', $header, 2); $headers[trim($name)] = trim($value); } curl_close($ch); return [ 'code' => $code, 'headers' => $headers, 'body' => $body, ]; } } simplesamlphp-1.19.1/tests/lib/0000755000000000000000000000000014042503475015073 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/AutoloadModulesTest.php0000644000000000000000000000153114042503475021545 0ustar rootrootassertFalse(class_exists('NonExisting\\ClassThatHasNothing\\ToDoWithXMLSec\\Library', true)); } /** * @test * @return void */ public function autoloaderSubstitutesNamespacedXmlSecClassesWhereNonNamespacedClassWasUsed() { $this->assertTrue(class_exists('XMLSecEnc', true)); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/0000755000000000000000000000000014042503475017001 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/0000755000000000000000000000000014042503475017441 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/ValidatorTest.php0000644000000000000000000001535014042503475022743 0ustar rootrootloadXML('value'); $this->expectException(Exception::class); new Validator($doc); } /** * @return void */ public function testGetX509Certificate(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($node, $signature_parent); $validator = new Validator($doc, 'node'); $result = $validator->getX509Certificate(); // getX509Certificate returns a certificate with a newline $expected = $this->good_certificate . "\n"; $this->assertEquals($result, $expected); } /** * @return void */ public function testCertFingerprintSuccess(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new \DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($node, $signature_parent); $fingerprint = openssl_x509_fingerprint($this->good_certificate); $validator = new Validator( $doc, 'node', ['certFingerprint' => [$fingerprint]] ); $this->assertInstanceOf(Validator::class, $validator); } /** * @return void */ public function testCertFingerprintFailure(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new \DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($node, $signature_parent); $this->expectException(\Exception::class); new Validator($doc, 'node', ['certFingerprint' => []]); } /** * @return void */ public function testValidateFingerprintSuccess(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new \DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($node, $signature_parent); $fingerprint = openssl_x509_fingerprint($this->good_certificate); $validator = new Validator($doc, 'node'); $validator->validateFingerprint($fingerprint); $this->assertInstanceOf(Validator::class, $validator); } /** * @return void */ public function testValidateFingerprintFailure(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new \DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($node, $signature_parent); $fingerprint = 'BAD FINGERPRINT'; $validator = new Validator($doc, 'node'); $this->expectException(\Exception::class); $validator->validateFingerprint($fingerprint); } /** * @return void */ public function testIsNodeValidatedSuccess(): void { $doc = new DOMDocument(); $doc->loadXML('value'); /** @psalm-var DOMElement $node */ $node = $doc->getElementsByTagName('node')->item(0); $signature_parent = $doc->appendChild(new DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->sign($node, $signature_parent); $validator = new Validator( $doc, 'node', ['PEM' => $this->good_certificate] ); $result = $validator->isNodeValidated($node); $this->assertTrue($result); } /** * @return void */ public function testIsNodeValidatedFailure(): void { $doc = new DOMDocument(); $doc->loadXML('value1value2'); /** @psalm-var DOMElement $node1 */ $node1 = $doc->getElementsByTagName('node1')->item(0); /** @psalm-var DOMElement $node2 */ $node2 = $doc->getElementsByTagName('node2')->item(0); $signature_parent = $doc->appendChild(new DOMElement('signature_parent')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->sign($node1, $signature_parent); $validator = new Validator( $doc, 'node1', ['PEM' => $this->good_certificate] ); $result = $validator->isNodeValidated($node2); $this->assertFalse($result); } /** * @return void */ public function testValidateCertificateMissingCAFile() { $ca_file = $this->ca_certificate_file . 'NOT'; $this->expectException(\Exception::class); Validator::validateCertificate($this->good_certificate, $ca_file); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/ParserTest.php0000644000000000000000000000660514042503475022255 0ustar rootroot * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ class ParserTest extends TestCase { private const XMLDOC = <<< XML Hello, World! XML; /** @var Parser */ private $xml; /** * @return void */ protected function setUp() { $this->xml = new Parser(static::XMLDOC); } /** * @covers \SimpleSAML\XML\Parser::getValue * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getValue(): void { $result = $this->xml->getValue('/Root/Value', true); $this->assertEquals( 'Hello, World!', $result ); } /** * @covers \SimpleSAML\XML\Parser::getValue * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getEmptyValue(): void { $result = $this->xml->getValue('/Root/Foo', false); $this->assertEquals( null, $result ); } /** * @covers \SimpleSAML\XML\Parser::getValue * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getValueException(): void { $this->expectException(Exception::class); $this->xml->getValue('/Root/Foo', true); } /** * @covers \SimpleSAML\XML\Parser::getValueDefault * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getDefaultValue(): void { $result = $this->xml->getValueDefault('/Root/Other', 'Hello'); $this->assertEquals( 'Hello', $result ); } /** * @covers \SimpleSAML\XML\Parser::getValueAlternatives * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getValueAlternatives(): void { $result = $this ->xml ->getValueAlternatives([ '/Root/Other', '/Root/Value' ], true) ; $this->assertEquals( 'Hello, World!', $result ); } /** * @covers \SimpleSAML\XML\Parser::getValueAlternatives * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getEmptyValueAlternatives(): void { $result = $this ->xml ->getValueAlternatives([ '/Root/Foo', '/Root/Bar' ], false) ; $this->assertEquals( null, $result ); } /** * @covers \SimpleSAML\XML\Parser::getValueAlternatives * @covers \SimpleSAML\XML\Parser::__construct * @test * @return void */ public function getValueAlternativesException(): void { $this->expectException(Exception::class); $this->xml->getValueAlternatives( [ '/Root/Foo', '/Root/Bar' ], true ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/SignerTest.php0000644000000000000000000001465414042503475022253 0ustar rootroot $this->good_private_key, self::GOOD_CERTIFICATE => $this->good_certificate, self::OTHER_CERTIFICATE => $this->other_certificate, ]; } /** * @return void */ public function testSignerBasic(): void { $res = new Signer([]); $this->assertNotNull($res); } /** * @return void */ public function testSignBasic(): void { $node = new DOMDocument(); $node->loadXML('value'); /** @psalm-var DOMElement $element */ $element = $node->getElementsByTagName("node")->item(0); $doc = new DOMDocument(); $insertInto = $doc->appendChild(new DOMElement('insert')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->sign($element, $insertInto); $res = $doc->saveXML(); $this->assertContains('DigestValue', $res); $this->assertContains('SignatureValue', $res); } /** * @param string $certificate * @return string */ private static function getCertificateValue(string $certificate): string { $replacements = [ "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----", "\n", ]; return str_replace($replacements, "", $certificate); } /** * @return void */ public function testSignWithCertificate(): void { $node = new DOMDocument(); $node->loadXML('value'); /** @psalm-var DOMElement $element */ $element = $node->getElementsByTagName("node")->item(0); $doc = new DOMDocument(); $insertInto = $doc->appendChild(new DOMElement('insert')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($element, $insertInto); $res = $doc->saveXML(); $expected = self::getCertificateValue($this->good_certificate); $this->assertContains('X509Certificate', $res); $this->assertContains($expected, $res); } /** * @return void */ public function testSignWithMultiCertificate(): void { $this->other_certificate_file = $this->certdir . DIRECTORY_SEPARATOR . self::OTHER_CERTIFICATE; $node = new DOMDocument(); $node->loadXML('value'); /** @psalm-var DOMElement $element */ $element = $node->getElementsByTagName("node")->item(0); $doc = new DOMDocument(); $insertInto = $doc->appendChild(new DOMElement('insert')); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->addCertificate($this->other_certificate_file, true); $signer->sign($element, $insertInto); $res = $doc->saveXML(); $expected1 = self::getCertificateValue($this->good_certificate); $expected2 = self::getCertificateValue($this->other_certificate); $this->assertContains('X509Certificate', $res); $this->assertContains($expected1, $res); $this->assertContains($expected2, $res); } /** * @return void */ public function testSignMissingPrivateKey(): void { $node = new DOMDocument(); $node->loadXML('value'); /** @psalm-var DOMElement $element */ $element = $node->getElementsByTagName("node")->item(0); $doc = new DOMDocument(); $insertInto = $doc->appendChild(new DOMElement('insert')); $signer = new Signer([]); $this->expectException(Exception::class); $signer->sign($element, $insertInto); } /** * @param \SimpleSAML\Configuration $service * @param class-string $className * @param mixed|null $value * @return void */ protected function clearInstance(Configuration $service, string $className, $value = null): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, $value); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/Shib13/0000755000000000000000000000000014042503475020472 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/Shib13/AuthnResponseTest.php0000644000000000000000000000621014042503475024640 0ustar rootroot * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * @deprecated This class will be removed in a future release */ namespace SimpleSAML\Test\XML\Shib13; use PHPUnit\Framework\TestCase; use SimpleSAML\XML\Shib13\AuthnResponse; class AuthnResponseTest extends TestCase { const XMLDOC = <<< XML NameIdentifier XML; const BADXMLDOC = <<< XML NameIdentifier XML; /** @var AuthnResponse */ private $xml; /** * @return void */ protected function setUp() { $this->xml = new AuthnResponse(); $this->xml->setXML(static::XMLDOC); } /** * @covers \SimpleSAML\XML\Shib13\AuthnResponse::doXPathQuery * @covers \SimpleSAML\XML\Shib13\AuthnResponse::getIssuer * @covers \SimpleSAML\XML\Shib13\AuthnResponse::setXML * @test * @return void */ public function getIssuer() { $result = $this->xml->getIssuer(); $this->assertEquals( 'Issuer', $result ); } /** * @covers \SimpleSAML\XML\Shib13\AuthnResponse::getIssuer * @covers \SimpleSAML\XML\Shib13\AuthnResponse::setXML * @test * @return void */ public function getIssuerException() { $this->expectException(\Exception::class); $xml = new AuthnResponse(); $xml->setXML(static::BADXMLDOC); $xml->getIssuer(); } /** * @covers \SimpleSAML\XML\Shib13\AuthnResponse::getNameID * @covers \SimpleSAML\XML\Shib13\AuthnResponse::setXML * @test * @return void */ public function getNameID() { $result = $this->xml->getNameID(); $this->assertEquals( [ 'Value' => 'NameIdentifier', 'Format' => 'urn:mace:shibboleth:1.0:nameIdentifier', ], $result ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/XML/ErrorsTest.php0000644000000000000000000000312714042503475022271 0ustar rootroot * @package simplesamlphp/simplesamlphp */ class ErrorsTest extends TestCase { /** * @covers \SimpleSAML\XML\Errors::begin * @covers \SimpleSAML\XML\Errors::addErrors * @covers \SimpleSAML\XML\Errors::end * @test * @return void */ public function loggingErrors(): void { Errors::begin(); $xmlstr = "Test"; simplexml_load_string($xmlstr); $errors = Errors::end(); $errors = Errors::formatErrors($errors); $this->assertEquals( "level=3,code=76,line=1,col=18,msg=Opening and ending tag mismatch: Test line 1 and test\n", $errors ); } /** * @covers \SimpleSAML\XML\Errors::formatError * @covers \SimpleSAML\XML\Errors::formatErrors * @test * @return void */ public function formatErrors(): void { $error = new LibXMLError(); $error->level = 3; $error->code = 76; $error->line = 1; $error->column = 18; $error->message = ' msg '; $errors = Errors::formatErrors([$error, $error]); $this->assertEquals( "level=3,code=76,line=1,col=18,msg=msg\nlevel=3,code=76,line=1,col=18,msg=msg\n", $errors ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/DatabaseTest.php0000644000000000000000000002356514042503475022071 0ustar rootroot * @package SimpleSAMLphp */ class DatabaseTest extends TestCase { /** * @var \SimpleSAML\Configuration */ protected $config; /** * @var \SimpleSAML\Database */ protected $db; /** * Make protected functions available for testing * * @param string $getMethod The method to get. * @return mixed The method itself. */ protected static function getMethod($getMethod) { $class = new ReflectionClass(Database::class); $method = $class->getMethod($getMethod); $method->setAccessible(true); return $method; } /** * @covers SimpleSAML\Database::getInstance * @covers SimpleSAML\Database::generateInstanceId * @covers SimpleSAML\Database::__construct * @covers SimpleSAML\Database::connect * @return void */ public function setUp() { $config = [ 'database.dsn' => 'sqlite::memory:', 'database.username' => null, 'database.password' => null, 'database.prefix' => 'phpunit_', 'database.persistent' => true, 'database.slaves' => [], ]; $this->config = new Configuration($config, "test/SimpleSAML/DatabaseTest.php"); // Ensure that we have a functional configuration class $this->assertInstanceOf(Configuration::class, $this->config); $this->assertEquals($config['database.dsn'], $this->config->getString('database.dsn')); $this->db = Database::getInstance($this->config); // Ensure that we have a functional database class. $this->assertInstanceOf(Database::class, $this->db); } /** * @covers SimpleSAML\Database::getInstance * @covers SimpleSAML\Database::generateInstanceId * @covers SimpleSAML\Database::__construct * @covers SimpleSAML\Database::connect * @test * @return void */ public function connectionFailure(): void { $this->expectException(Exception::class); $config = [ 'database.dsn' => 'mysql:host=localhost;dbname=saml', 'database.username' => 'notauser', 'database.password' => 'notausersinvalidpassword', 'database.prefix' => 'phpunit_', 'database.persistent' => true, 'database.slaves' => [], ]; $this->config = new Configuration($config, "test/SimpleSAML/DatabaseTest.php"); Database::getInstance($this->config); } /** * @covers SimpleSAML\Database::getInstance * @covers SimpleSAML\Database::generateInstanceId * @covers SimpleSAML\Database::__construct * @covers SimpleSAML\Database::connect * @test * @return void */ public function instances(): void { $config = [ 'database.dsn' => 'sqlite::memory:', 'database.username' => null, 'database.password' => null, 'database.prefix' => 'phpunit_', 'database.persistent' => true, 'database.slaves' => [], ]; $config2 = [ 'database.dsn' => 'sqlite::memory:', 'database.username' => null, 'database.password' => null, 'database.prefix' => 'phpunit2_', 'database.persistent' => true, 'database.slaves' => [], ]; $config1 = new Configuration($config, "test/SimpleSAML/DatabaseTest.php"); $config2 = new Configuration($config2, "test/SimpleSAML/DatabaseTest.php"); $config3 = new Configuration($config, "test/SimpleSAML/DatabaseTest.php"); $db1 = Database::getInstance($config1); $db2 = Database::getInstance($config2); $db3 = Database::getInstance($config3); $generateInstanceId = self::getMethod('generateInstanceId'); $instance1 = $generateInstanceId->invokeArgs($db1, [$config1]); $instance2 = $generateInstanceId->invokeArgs($db2, [$config2]); $instance3 = $generateInstanceId->invokeArgs($db3, [$config3]); // Assert that $instance1 and $instance2 have different instance ids $this->assertNotEquals( $instance1, $instance2, "Database instances should be different, but returned the same id" ); // Assert that $instance1 and $instance3 have identical instance ids $this->assertEquals( $instance1, $instance3, "Database instances should have the same id, but returned different id" ); // Assert that $db1 and $db2 are different instances $this->assertNotEquals( spl_object_hash($db1), spl_object_hash($db2), "Database instances should be different, but returned the same spl_object_hash" ); // Assert that $db1 and $db3 are identical instances $this->assertEquals( spl_object_hash($db1), spl_object_hash($db3), "Database instances should be the same, but returned different spl_object_hash" ); } /** * @covers SimpleSAML\Database::getInstance * @covers SimpleSAML\Database::generateInstanceId * @covers SimpleSAML\Database::__construct * @covers SimpleSAML\Database::connect * @covers SimpleSAML\Database::getSlave * @test * @return void */ public function slaves(): void { $getSlave = self::getMethod('getSlave'); $master = spl_object_hash(\PHPUnit\Framework\Assert::readAttribute($this->db, 'dbMaster')); $slave = spl_object_hash($getSlave->invokeArgs($this->db, [])); $this->assertTrue(($master == $slave), "getSlave should have returned the master database object"); $config = [ 'database.dsn' => 'sqlite::memory:', 'database.username' => null, 'database.password' => null, 'database.prefix' => 'phpunit_', 'database.persistent' => true, 'database.slaves' => [ [ 'dsn' => 'sqlite::memory:', 'username' => null, 'password' => null, ], ], ]; $sspConfiguration = new Configuration($config, "test/SimpleSAML/DatabaseTest.php"); $msdb = Database::getInstance($sspConfiguration); $slaves = \PHPUnit\Framework\Assert::readAttribute($msdb, 'dbSlaves'); $gotSlave = spl_object_hash($getSlave->invokeArgs($msdb, [])); $this->assertEquals( spl_object_hash($slaves[0]), $gotSlave, "getSlave should have returned a slave database object" ); } /** * @covers SimpleSAML\Database::applyPrefix * @test * @return void */ public function prefix(): void { $prefix = $this->config->getString('database.prefix'); $table = "saml20_idp_hosted"; $pftable = $this->db->applyPrefix($table); $this->assertEquals($prefix . $table, $pftable, "Did not properly apply the table prefix"); } /** * @covers SimpleSAML\Database::write * @covers SimpleSAML\Database::read * @covers SimpleSAML\Database::exec * @covers SimpleSAML\Database::query * @test * @return void */ public function querying(): void { $table = $this->db->applyPrefix("sspdbt"); $this->assertEquals($this->config->getString('database.prefix') . "sspdbt", $table); $this->db->write( "CREATE TABLE IF NOT EXISTS $table (ssp_key INT(16) NOT NULL, ssp_value TEXT NOT NULL)" ); /** @var \PDOStatement $query1 */ $query1 = $this->db->read("SELECT * FROM $table"); $this->assertEquals(0, $query1->fetch(), "Table $table is not empty when it should be."); $ssp_key = time(); $ssp_value = md5(strval(rand(0, 10000))); $stmt = $this->db->write( "INSERT INTO $table (ssp_key, ssp_value) VALUES (:ssp_key, :ssp_value)", ['ssp_key' => [$ssp_key, PDO::PARAM_INT], 'ssp_value' => $ssp_value] ); $this->assertEquals(1, $stmt, "Could not insert data into $table."); /** @var \PDOStatement $query2 */ $query2 = $this->db->read("SELECT * FROM $table WHERE ssp_key = :ssp_key", ['ssp_key' => $ssp_key]); $data = $query2->fetch(); $this->assertEquals($data['ssp_value'], $ssp_value, "Inserted data doesn't match what is in the database"); } /** * @covers SimpleSAML\Database::read * @covers SimpleSAML\Database::query * @test * @return void */ public function readFailure(): void { $this->expectException(Exception::class); $table = $this->db->applyPrefix("sspdbt"); $this->assertEquals($this->config->getString('database.prefix') . "sspdbt", $table); $this->db->read("SELECT * FROM $table"); } /** * @covers SimpleSAML\Database::write * @covers SimpleSAML\Database::exec * @test * @return void */ public function noSuchTable(): void { $this->expectException(Exception::class); $this->db->write("DROP TABLE phpunit_nonexistent"); } /** * @return void */ public function tearDown() { $table = $this->db->applyPrefix("sspdbt"); $this->db->write("DROP TABLE IF EXISTS $table"); unset($this->config); unset($this->db); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/ConfigurationTest.php0000644000000000000000000010344414042503475023167 0ustar rootrootassertEquals($c->getVersion(), Configuration::VERSION); } /** * Test that the default instance fails to load even if we previously loaded another instance. * @return void */ public function testLoadDefaultInstance(): void { $this->expectException(Error\CriticalConfigurationError::class); Configuration::loadFromArray(['key' => 'value'], '', 'dummy'); Configuration::getInstance(); } /** * Test that after a \SimpleSAML\Error\CriticalConfigurationError exception, a basic, self-survival configuration * is loaded. * @return void */ public function testCriticalConfigurationError(): void { try { Configuration::getInstance(); $this->fail('Exception expected'); } catch (Error\CriticalConfigurationError $var) { // This exception is expected. } /* * After the above failure an emergency configuration is create to allow core SSP components to function and * possibly log/display the error. */ $c = Configuration::getInstance(); $this->assertNotEmpty($c->toArray()); } /** * Test \SimpleSAML\Configuration::getValue() * @return void */ public function testGetValue(): void { $c = Configuration::loadFromArray([ 'exists_true' => true, 'exists_null' => null, ]); $this->assertEquals($c->getValue('missing'), null); $this->assertEquals($c->getValue('missing', true), true); $this->assertEquals($c->getValue('missing', true), true); $this->assertEquals($c->getValue('exists_true'), true); $this->assertEquals($c->getValue('exists_null'), null); $this->assertEquals($c->getValue('exists_null', false), null); } /** * Test \SimpleSAML\Configuration::getValue(), REQUIRED_OPTION flag. * @return void */ public function testGetValueRequired(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([]); $c->getValue('missing', Configuration::REQUIRED_OPTION); } /** * Test \SimpleSAML\Configuration::hasValue() * @return void */ public function testHasValue(): void { $c = Configuration::loadFromArray([ 'exists_true' => true, 'exists_null' => null, ]); $this->assertEquals($c->hasValue('missing'), false); $this->assertEquals($c->hasValue('exists_true'), true); $this->assertEquals($c->hasValue('exists_null'), true); } /** * Test \SimpleSAML\Configuration::hasValue() * @return void */ public function testHasValueOneOf(): void { $c = Configuration::loadFromArray([ 'exists_true' => true, 'exists_null' => null, ]); $this->assertEquals($c->hasValueOneOf([]), false); $this->assertEquals($c->hasValueOneOf(['missing']), false); $this->assertEquals($c->hasValueOneOf(['exists_true']), true); $this->assertEquals($c->hasValueOneOf(['exists_null']), true); $this->assertEquals($c->hasValueOneOf(['missing1', 'missing2']), false); $this->assertEquals($c->hasValueOneOf(['exists_true', 'missing']), true); $this->assertEquals($c->hasValueOneOf(['missing', 'exists_true']), true); } /** * Test \SimpleSAML\Configuration::getBasePath() * @return void */ public function testGetBasePath(): void { $c = Configuration::loadFromArray([]); $this->assertEquals($c->getBasePath(), '/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => 'simplesaml/']); $this->assertEquals($c->getBasePath(), '/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => '/simplesaml/']); $this->assertEquals($c->getBasePath(), '/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => 'simplesaml']); $this->assertEquals($c->getBasePath(), '/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => '/simplesaml']); $this->assertEquals($c->getBasePath(), '/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => 'path/to/simplesaml/']); $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => '/path/to/simplesaml/']); $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => '/path/to/simplesaml']); $this->assertEquals($c->getBasePath(), '/path/to/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => 'https://example.org/ssp/']); $this->assertEquals($c->getBasePath(), '/ssp/'); $c = Configuration::loadFromArray(['baseurlpath' => 'https://example.org/']); $this->assertEquals($c->getBasePath(), '/'); $c = Configuration::loadFromArray(['baseurlpath' => 'http://example.org/ssp/']); $this->assertEquals($c->getBasePath(), '/ssp/'); $c = Configuration::loadFromArray(['baseurlpath' => 'http://example.org/ssp/simplesaml']); $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => 'http://example.org/ssp/simplesaml/']); $this->assertEquals($c->getBasePath(), '/ssp/simplesaml/'); $c = Configuration::loadFromArray(['baseurlpath' => '']); $this->assertEquals($c->getBasePath(), '/'); $c = Configuration::loadFromArray(['baseurlpath' => '/']); $this->assertEquals($c->getBasePath(), '/'); $c = Configuration::loadFromArray(['baseurlpath' => 'https://example.org:8443']); $this->assertEquals($c->getBasePath(), '/'); $c = Configuration::loadFromArray(['baseurlpath' => 'https://example.org:8443/']); $this->assertEquals($c->getBasePath(), '/'); } /** * Test \SimpleSAML\Configuration::resolvePath() * @return void */ public function testResolvePath(): void { $c = Configuration::loadFromArray([ 'basedir' => '/basedir/', ]); $this->assertEquals($c->resolvePath(null), null); $this->assertEquals($c->resolvePath('/otherdir'), '/otherdir'); $this->assertEquals($c->resolvePath('relativedir'), '/basedir/relativedir'); $this->assertEquals($c->resolvePath('slash/'), '/basedir/slash'); $this->assertEquals($c->resolvePath('slash//'), '/basedir/slash'); $this->assertEquals($c->resolvePath('C:\\otherdir'), 'C:/otherdir'); $this->assertEquals($c->resolvePath('C:/otherdir'), 'C:/otherdir'); } /** * Test \SimpleSAML\Configuration::getPathValue() * @return void */ public function testGetPathValue(): void { $c = Configuration::loadFromArray([ 'basedir' => '/basedir/', 'path_opt' => 'path', 'slashes_opt' => 'slashes//', ]); $this->assertEquals($c->getPathValue('missing'), null); $this->assertEquals($c->getPathValue('path_opt'), '/basedir/path/'); $this->assertEquals($c->getPathValue('slashes_opt'), '/basedir/slashes/'); } /** * Test \SimpleSAML\Configuration::getBaseDir() * @return void */ public function testGetBaseDir(): void { $c = Configuration::loadFromArray([]); $this->assertEquals($c->getBaseDir(), dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR); $c = Configuration::loadFromArray([ 'basedir' => DIRECTORY_SEPARATOR . 'basedir', ]); $this->assertEquals($c->getBaseDir(), DIRECTORY_SEPARATOR . 'basedir' . DIRECTORY_SEPARATOR); $c = Configuration::loadFromArray([ 'basedir' => DIRECTORY_SEPARATOR . 'basedir' . DIRECTORY_SEPARATOR, ]); $this->assertEquals($c->getBaseDir(), DIRECTORY_SEPARATOR . 'basedir' . DIRECTORY_SEPARATOR); } /** * Test \SimpleSAML\Configuration::getBoolean() * @return void */ public function testGetBoolean(): void { $c = Configuration::loadFromArray([ 'true_opt' => true, 'false_opt' => false, ]); $this->assertEquals($c->getBoolean('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getBoolean('true_opt', '--missing--'), true); $this->assertEquals($c->getBoolean('false_opt', '--missing--'), false); } /** * Test \SimpleSAML\Configuration::getBoolean() missing option * @return void */ public function testGetBooleanMissing(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([]); $c->getBoolean('missing_opt'); } /** * Test \SimpleSAML\Configuration::getBoolean() wrong option * @return void */ public function testGetBooleanWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'wrong' => 'true', ]); $c->getBoolean('wrong'); } /** * Test \SimpleSAML\Configuration::getString() * @return void */ public function testGetString(): void { $c = Configuration::loadFromArray([ 'str_opt' => 'Hello World!', ]); $this->assertEquals($c->getString('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getString('str_opt', '--missing--'), 'Hello World!'); } /** * Test \SimpleSAML\Configuration::getString() missing option * @return void */ public function testGetStringMissing(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([]); $c->getString('missing_opt'); } /** * Test \SimpleSAML\Configuration::getString() wrong option * @return void */ public function testGetStringWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'wrong' => false, ]); $c->getString('wrong'); } /** * Test \SimpleSAML\Configuration::getInteger() * @return void */ public function testGetInteger(): void { $c = Configuration::loadFromArray([ 'int_opt' => 42, ]); $this->assertEquals($c->getInteger('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getInteger('int_opt', '--missing--'), 42); } /** * Test \SimpleSAML\Configuration::getInteger() missing option * @return void */ public function testGetIntegerMissing(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([]); $c->getInteger('missing_opt'); } /** * Test \SimpleSAML\Configuration::getInteger() wrong option * @return void */ public function testGetIntegerWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'wrong' => '42', ]); $c->getInteger('wrong'); } /** * Test \SimpleSAML\Configuration::getIntegerRange() * @return void */ public function testGetIntegerRange(): void { $c = Configuration::loadFromArray([ 'int_opt' => 42, ]); $this->assertEquals($c->getIntegerRange('missing_opt', 0, 100, '--missing--'), '--missing--'); $this->assertEquals($c->getIntegerRange('int_opt', 0, 100), 42); } /** * Test \SimpleSAML\Configuration::getIntegerRange() below limit * @return void */ public function testGetIntegerRangeBelow(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'int_opt' => 9, ]); $this->assertEquals($c->getIntegerRange('int_opt', 10, 100), 42); } /** * Test \SimpleSAML\Configuration::getIntegerRange() above limit * @return void */ public function testGetIntegerRangeAbove(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'int_opt' => 101, ]); $this->assertEquals($c->getIntegerRange('int_opt', 10, 100), 42); } /** * Test \SimpleSAML\Configuration::getValueValidate() * @return void */ public function testGetValueValidate(): void { $c = Configuration::loadFromArray([ 'opt' => 'b', ]); $this->assertEquals($c->getValueValidate('missing_opt', ['a', 'b', 'c'], '--missing--'), '--missing--'); $this->assertEquals($c->getValueValidate('opt', ['a', 'b', 'c']), 'b'); } /** * Test \SimpleSAML\Configuration::getValueValidate() wrong option * @return void */ public function testGetValueValidateWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => 'd', ]); $c->getValueValidate('opt', ['a', 'b', 'c']); } /** * Test \SimpleSAML\Configuration::getArray() * @return void */ public function testGetArray(): void { $c = Configuration::loadFromArray([ 'opt' => ['a', 'b', 'c'], ]); $this->assertEquals($c->getArray('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getArray('opt'), ['a', 'b', 'c']); } /** * Test \SimpleSAML\Configuration::getArray() wrong option * @return void */ public function testGetArrayWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => 'not_an_array', ]); $c->getArray('opt'); } /** * Test \SimpleSAML\Configuration::getArrayize() * @return void */ public function testGetArrayize(): void { $c = Configuration::loadFromArray([ 'opt' => ['a', 'b', 'c'], 'opt_int' => 42, 'opt_str' => 'string', ]); $this->assertEquals($c->getArrayize('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getArrayize('opt'), ['a', 'b', 'c']); $this->assertEquals($c->getArrayize('opt_int'), [42]); $this->assertEquals($c->getArrayize('opt_str'), ['string']); } /** * Test \SimpleSAML\Configuration::getArrayizeString() * @return void */ public function testGetArrayizeString(): void { $c = Configuration::loadFromArray([ 'opt' => ['a', 'b', 'c'], 'opt_str' => 'string', ]); $this->assertEquals($c->getArrayizeString('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getArrayizeString('opt'), ['a', 'b', 'c']); $this->assertEquals($c->getArrayizeString('opt_str'), ['string']); } /** * Test \SimpleSAML\Configuration::getArrayizeString() option * with an array that contains something that isn't a string. * @return void */ public function testGetArrayizeStringWrongValue(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => ['a', 'b', 42], ]); $c->getArrayizeString('opt'); } /** * Test \SimpleSAML\Configuration::getConfigItem() * @return void */ public function testGetConfigItem(): void { $c = Configuration::loadFromArray([ 'opt' => ['a' => 42], ]); $this->assertNull($c->getConfigItem('missing_opt', null)); $opt = $c->getConfigItem('opt'); $notOpt = $c->getConfigItem('notOpt'); $this->assertInstanceOf(Configuration::class, $opt); $this->assertInstanceOf(Configuration::class, $notOpt); $this->assertEquals($opt->getValue('a'), 42); } /** * Test \SimpleSAML\Configuration::getConfigItem() wrong option * @return void */ public function testGetConfigItemWrong(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => 'not_an_array', ]); $c->getConfigItem('opt'); } /** * Test \SimpleSAML\Configuration::getConfigList() * @return void */ public function testGetConfigList() { $c = Configuration::loadFromArray([ 'opts' => [ 'a' => ['opt1' => 'value1'], 'b' => ['opt2' => 'value2'], ], ]); $this->assertEquals($c->getConfigList('missing_opt'), []); $opts = $c->getConfigList('opts'); $this->assertInternalType('array', $opts); $this->assertEquals(array_keys($opts), ['a', 'b']); $this->assertInstanceOf(Configuration::class, $opts['a']); $this->assertEquals($opts['a']->getValue('opt1'), 'value1'); $this->assertInstanceOf(Configuration::class, $opts['b']); $this->assertEquals($opts['b']->getValue('opt2'), 'value2'); } /** * Test \SimpleSAML\Configuration::getConfigList() wrong option * @return void */ public function testGetConfigListWrong() { $this->expectException(\Exception::class); $c = Configuration::loadFromArray([ 'opt' => 'not_an_array', ]); $c->getConfigList('opt'); } /** * Test \SimpleSAML\Configuration::getConfigList() with an array of wrong options. * @return void */ public function testGetConfigListWrongArrayValues() { $this->expectException(\Exception::class); $c = Configuration::loadFromArray([ 'opts' => [ 'a', 'b', ], ]); $c->getConfigList('opts'); } /** * Test \SimpleSAML\Configuration::getOptions() * @return void */ public function testGetOptions(): void { $c = Configuration::loadFromArray([ 'a' => true, 'b' => null, ]); $this->assertEquals($c->getOptions(), ['a', 'b']); } /** * Test \SimpleSAML\Configuration::toArray() * @return void */ public function testToArray(): void { $c = Configuration::loadFromArray([ 'a' => true, 'b' => null, ]); $this->assertEquals($c->toArray(), ['a' => true, 'b' => null]); } /** * Test \SimpleSAML\Configuration::getDefaultEndpoint(). * * Iterate over all different valid definitions of endpoints and check if the expected output is produced. * @return void */ public function testGetDefaultEndpoint(): void { /* * First we run the full set of tests covering all possible configurations for indexed endpoint types, * basically AssertionConsumerService and ArtifactResolutionService. Since both are the same, we just run the * tests for AssertionConsumerService. */ $acs_eps = [ // just a string with the location 'https://example.com/endpoint.php', // an array of strings with location of different endpoints [ 'https://www1.example.com/endpoint.php', 'https://www2.example.com/endpoint.php', ], // define location and binding [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], ], // define the ResponseLocation too [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, 'ResponseLocation' => 'https://example.com/endpoint.php', ], ], // make sure indexes are NOT taken into account (they just identify endpoints) [ [ 'index' => 1, 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, ], [ 'index' => 2, 'Location' => 'https://www2.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], ], // make sure isDefault has priority over indexes [ [ 'index' => 1, 'Location' => 'https://www2.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], [ 'index' => 2, 'isDefault' => true, 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, ], ], // make sure endpoints with invalid bindings are ignored and those marked as NOT default are still used [ [ 'index' => 1, 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => 'invalid_binding', ], [ 'index' => 2, 'isDefault' => false, 'Location' => 'https://www2.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], ], ]; $acs_expected_eps = [ // output should be completed with the default binding (HTTP-POST for ACS) [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], // we should just get the first endpoint with the default binding [ 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ], // if we specify the binding, we should get it back [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST ], // if we specify ResponseLocation, we should get it back too [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, 'ResponseLocation' => 'https://example.com/endpoint.php', ], // indexes must NOT be taken into account, order is the only thing that matters here [ 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, 'index' => 1, ], // isDefault must have higher priority than indexes [ 'Location' => 'https://www1.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, 'isDefault' => true, 'index' => 2, ], // the first valid enpoint should be used even if it's marked as NOT default [ 'index' => 2, 'isDefault' => false, 'Location' => 'https://www2.example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_POST, ] ]; $a = [ 'metadata-set' => 'saml20-sp-remote', 'ArtifactResolutionService' => 'https://example.com/ars', 'SingleSignOnService' => 'https://example.com/sso', 'SingleLogoutService' => [ 'Location' => 'https://example.com/slo', 'Binding' => 'valid_binding', // test unknown bindings if we don't specify a list of valid ones ], ]; $valid_bindings = [ Constants::BINDING_HTTP_POST, Constants::BINDING_HTTP_REDIRECT, Constants::BINDING_HOK_SSO, Constants::BINDING_HTTP_ARTIFACT, Constants::BINDING_SOAP, ]; // run all general tests with AssertionConsumerService endpoint type foreach ($acs_eps as $i => $ep) { $a['AssertionConsumerService'] = $ep; $c = Configuration::loadFromArray($a); $this->assertEquals($acs_expected_eps[$i], $c->getDefaultEndpoint( 'AssertionConsumerService', $valid_bindings )); } // now make sure SingleSignOnService, SingleLogoutService and ArtifactResolutionService works fine $a['metadata-set'] = 'shib13-idp-remote'; $c = Configuration::loadFromArray($a); $this->assertEquals( [ 'Location' => 'https://example.com/sso', 'Binding' => 'urn:mace:shibboleth:1.0:profiles:AuthnRequest', ], $c->getDefaultEndpoint('SingleSignOnService') ); $a['metadata-set'] = 'saml20-idp-remote'; $c = Configuration::loadFromArray($a); $this->assertEquals( [ 'Location' => 'https://example.com/ars', 'Binding' => Constants::BINDING_SOAP, ], $c->getDefaultEndpoint('ArtifactResolutionService') ); $this->assertEquals( [ 'Location' => 'https://example.com/slo', 'Binding' => Constants::BINDING_HTTP_REDIRECT, ], $c->getDefaultEndpoint('SingleLogoutService') ); // test for old shib1.3 AssertionConsumerService $a['metadata-set'] = 'shib13-sp-remote'; $a['AssertionConsumerService'] = 'https://example.com/endpoint.php'; $c = Configuration::loadFromArray($a); $this->assertEquals( [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post', ], $c->getDefaultEndpoint('AssertionConsumerService') ); // test for no valid endpoints specified $a['SingleLogoutService'] = [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => 'invalid_binding', 'isDefault' => true, ], ]; $c = Configuration::loadFromArray($a); try { $c->getDefaultEndpoint('SingleLogoutService', $valid_bindings); $this->fail('Failed to detect invalid endpoint binding.'); } catch (Exception $e) { $this->assertEquals( '[ARRAY][\'SingleLogoutService\']:Could not find a supported SingleLogoutService ' . 'endpoint.', $e->getMessage() ); } $a['metadata-set'] = 'foo'; $c = Configuration::loadFromArray($a); try { $c->getDefaultEndpoint('SingleSignOnService'); $this->fail('No valid metadata set specified.'); } catch (Exception $e) { $this->assertStringStartsWith('Missing default binding for', $e->getMessage()); } } /** * Test \SimpleSAML\Configuration::getEndpoints(). * @return void */ public function testGetEndpoints(): void { // test response location for old-style configurations $c = Configuration::loadFromArray([ 'metadata-set' => 'saml20-idp-remote', 'SingleSignOnService' => 'https://example.com/endpoint.php', 'SingleSignOnServiceResponse' => 'https://example.com/response.php', ]); $e = [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, 'ResponseLocation' => 'https://example.com/response.php', ] ]; $this->assertEquals($e, $c->getEndpoints('SingleSignOnService')); // test for input failures // define a basic configuration array $a = [ 'metadata-set' => 'saml20-idp-remote', 'SingleSignOnService' => null, ]; // define a set of tests $tests = [ // invalid endpoint definition 10, // invalid definition of endpoint inside the endpoints array [ 1234 ], // missing location [ [ 'foo' => 'bar', ], ], // invalid location [ [ 'Location' => 1234, ] ], // missing binding [ [ 'Location' => 'https://example.com/endpoint.php', ], ], // invalid binding [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => 1234, ], ], // invalid response location [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, 'ResponseLocation' => 1234, ], ], // invalid index [ [ 'Location' => 'https://example.com/endpoint.php', 'Binding' => Constants::BINDING_HTTP_REDIRECT, 'index' => 'string', ], ], ]; // define a set of exception messages to expect $msgs = [ 'Expected array or string.', 'Expected a string or an array.', 'Missing Location.', 'Location must be a string.', 'Missing Binding.', 'Binding must be a string.', 'ResponseLocation must be a string.', 'index must be an integer.', ]; // now run all the tests expecting the correct exception message foreach ($tests as $i => $test) { $a['SingleSignOnService'] = $test; $c = Configuration::loadFromArray($a); try { $c->getEndpoints('SingleSignOnService'); } catch (Exception $e) { $this->assertStringEndsWith($msgs[$i], $e->getMessage()); } } } /** * Test \SimpleSAML\Configuration::getLocalizedString() * @return void */ public function testGetLocalizedString(): void { $c = Configuration::loadFromArray([ 'str_opt' => 'Hello World!', 'str_array' => [ 'en' => 'Hello World!', 'no' => 'Hei Verden!', ], ]); $this->assertEquals($c->getLocalizedString('missing_opt', '--missing--'), '--missing--'); $this->assertEquals($c->getLocalizedString('str_opt'), ['en' => 'Hello World!']); $this->assertEquals($c->getLocalizedString('str_array'), ['en' => 'Hello World!', 'no' => 'Hei Verden!']); } /** * Test \SimpleSAML\Configuration::getLocalizedString() not array nor simple string * @return void */ public function testGetLocalizedStringNotArray(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => 42, ]); $c->getLocalizedString('opt'); } /** * Test \SimpleSAML\Configuration::getLocalizedString() not string key * @return void */ public function testGetLocalizedStringNotStringKey(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => [42 => 'text'], ]); $c->getLocalizedString('opt'); } /** * Test \SimpleSAML\Configuration::getLocalizedString() not string value * @return void */ public function testGetLocalizedStringNotStringValue(): void { $this->expectException(Exception::class); $c = Configuration::loadFromArray([ 'opt' => ['en' => 42], ]); $c->getLocalizedString('opt'); } /** * Test \SimpleSAML\Configuration::getConfig() nonexistent file * @return void */ public function testGetConfigNonexistentFile(): void { $this->expectException(Exception::class); Configuration::getConfig('nonexistent-nopreload.php'); } /** * Test \SimpleSAML\Configuration::getConfig() preloaded nonexistent file * @return void */ public function testGetConfigNonexistentFilePreload(): void { $c = Configuration::loadFromArray([ 'key' => 'value' ]); $virtualFile = 'nonexistent-preload.php'; Configuration::setPreLoadedConfig($c, $virtualFile); $nc = Configuration::getConfig($virtualFile); $this->assertEquals('value', $nc->getValue('key', null)); } /** * Test that Configuration objects can be initialized from an array. * * ATTENTION: this test must be kept the last. * @return void */ public function testLoadInstanceFromArray(): void { $c = [ 'key' => 'value' ]; // test loading a custom instance Configuration::loadFromArray($c, '', 'dummy'); $this->assertEquals('value', Configuration::getInstance('dummy')->getValue('key', null)); // test loading the default instance Configuration::loadFromArray($c, '', 'simplesaml'); $this->assertEquals('value', Configuration::getInstance()->getValue('key', null)); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/0000755000000000000000000000000014042503475020101 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/AttributesTest.php0000644000000000000000000001611214042503475023601 0ustar rootroot */ class AttributesTest extends TestCase { /** * Test the getExpectedAttribute() method with invalid attributes array. * @return void * @psalm-suppress InvalidArgument * @deprecated Can be removed as soon as the codebase is fully typehinted */ public function testGetExpectedAttributeInvalidAttributesArray() { // check with empty array as input $attributes = 'string'; $expected = 'string'; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'The attributes array is not an array, it is: ' . print_r($attributes, true) . '.' ); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test the getExpectedAttributeMethod() method with invalid expected attribute parameter. * @deprecated Remove this test as soon as the codebase is fully typehinted * @psalm-suppress PossiblyFalseArgument * @return void */ public function testGetExpectedAttributeInvalidAttributeName() { // check with invalid attribute name $attributes = []; $expected = false; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'The expected attribute is not a string, it is: ' . print_r($expected, true) . '.' ); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test the getExpectedAttributeMethod() method with a non-normalized attributes array. * @return void */ public function testGetExpectedAttributeNonNormalizedArray(): void { // check with non-normalized attributes array $attributes = [ 'attribute' => 'value', ]; $expected = 'attribute'; $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'The attributes array is not normalized, values should be arrays.' ); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test the getExpectedAttribute() method with valid input but missing expected attribute. * @return void */ public function testGetExpectedAttributeMissingAttribute(): void { // check missing attribute $attributes = [ 'attribute' => ['value'], ]; $expected = 'missing'; $this->expectException(Error\Exception::class); $this->expectExceptionMessage("No such attribute '" . $expected . "' found."); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test the getExpectedAttribute() method with an empty attribute. * @return void */ public function testGetExpectedAttributeEmptyAttribute(): void { // check empty attribute $attributes = [ 'attribute' => [], ]; $expected = 'attribute'; $this->expectException(Error\Exception::class); $this->expectExceptionMessage("Empty attribute '" . $expected . "'.'"); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test the getExpectedAttributeMethod() method with multiple values (not being allowed). * @return void */ public function testGetExpectedAttributeMultipleValues(): void { // check attribute with more than value, that being not allowed $attributes = [ 'attribute' => [ 'value1', 'value2', ], ]; $expected = 'attribute'; $this->expectException(Error\Exception::class); $this->expectExceptionMessage( 'More than one value found for the attribute, multiple values not allowed.' ); Attributes::getExpectedAttribute($attributes, $expected); } /** * Test that the getExpectedAttribute() method successfully obtains values from the attributes array. * @return void */ public function testGetExpectedAttribute(): void { // check one value $value = 'value'; $attributes = [ 'attribute' => [$value], ]; $expected = 'attribute'; $this->assertEquals($value, Attributes::getExpectedAttribute($attributes, $expected)); // check multiple (allowed) values $value = 'value'; $attributes = [ 'attribute' => [$value, 'value2', 'value3'], ]; $expected = 'attribute'; $this->assertEquals($value, Attributes::getExpectedAttribute($attributes, $expected, true)); } /** * Test the normalizeAttributesArray() function with input not being an array * @return void * @psalm-suppress InvalidArgument * @deprecated Can be removed as soon as the codebase is fully typehinted */ public function testNormalizeAttributesArrayBadInput() { $this->expectException(InvalidArgumentException::class); Attributes::normalizeAttributesArray('string'); } /** * Test the normalizeAttributesArray() function with an array with non-string attribute names. * @return void */ public function testNormalizeAttributesArrayBadKeys(): void { $this->expectException(InvalidArgumentException::class); Attributes::normalizeAttributesArray(['attr1' => 'value1', 1 => 'value2']); } /** * Test the normalizeAttributesArray() function with an array with non-string attribute values. * @return void */ public function testNormalizeAttributesArrayBadValues(): void { $this->expectException(InvalidArgumentException::class); Attributes::normalizeAttributesArray(['attr1' => 'value1', 'attr2' => 0]); } /** * Test the normalizeAttributesArray() function. * @return void */ public function testNormalizeAttributesArray(): void { $attributes = [ 'key1' => 'value1', 'key2' => ['value2', 'value3'], 'key3' => 'value1' ]; $expected = [ 'key1' => ['value1'], 'key2' => ['value2', 'value3'], 'key3' => ['value1'] ]; $this->assertEquals( $expected, Attributes::normalizeAttributesArray($attributes), 'Attribute array normalization failed' ); } /** * Test the getAttributeNamespace() function. * @return void */ public function testNamespacedAttributes(): void { // test for only the name $this->assertEquals( ['default', 'name'], Attributes::getAttributeNamespace('name', 'default') ); // test for a given namespace and multiple '/' $this->assertEquals( ['some/namespace', 'name'], Attributes::getAttributeNamespace('some/namespace/name', 'default') ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/TimeTest.php0000644000000000000000000001524514042503475022357 0ustar rootrootassertEquals('2016-03-03T14:48:05Z', Time::generateTimestamp(1457016485)); // test timestamp generation for current time $this->assertRegExp('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/', Time::generateTimestamp()); } /** * Test the SimpleSAML\Utils\Time::initTimezone() method. * * @covers SimpleSAML\Utils\Time::initTimezone * @return void */ public function testInitTimezone(): void { $tz = 'UTC'; $os = @date_default_timezone_get(); if ($os === 'UTC') { // avoid collisions $tz = 'Europe/Oslo'; } // test guessing timezone from the OS Configuration::loadFromArray(['timezone' => null], '[ARRAY]', 'simplesaml'); @Time::initTimezone(); $this->assertEquals($os, @date_default_timezone_get()); // clear initialization $c = new ReflectionProperty('\SimpleSAML\Utils\Time', 'tz_initialized'); $c->setAccessible(true); $c->setValue(false); // test unknown timezone Configuration::loadFromArray(['timezone' => 'INVALID'], '[ARRAY]', 'simplesaml'); try { @Time::initTimezone(); $this->fail('Failed to recognize an invalid timezone.'); } catch (Error\Exception $e) { $this->assertEquals('Invalid timezone set in the "timezone" option in config.php.', $e->getMessage()); } // test a valid timezone Configuration::loadFromArray(['timezone' => $tz], '[ARRAY]', 'simplesaml'); @Time::initTimezone(); $this->assertEquals($tz, @date_default_timezone_get()); // make sure initialization happens only once Configuration::loadFromArray(['timezone' => 'Europe/Madrid'], '[ARRAY]', 'simplesaml'); @Time::initTimezone(); $this->assertEquals($tz, @date_default_timezone_get()); } /** * Test the SimpleSAML\Utils\Time::parseDuration() method. * * @covers SimpleSAML\Utils\Time::parseDuration * @return void */ public function testParseDuration(): void { // set up base date and time, and fixed durations from there $base = gmmktime(0, 0, 0, 1, 1, 2000); $second = gmmktime(0, 0, 1, 1, 1, 2000); // +1 sec $minute = gmmktime(0, 1, 0, 1, 1, 2000); // +1 min $hour = gmmktime(1, 0, 0, 1, 1, 2000); // +1 hour $day = gmmktime(0, 0, 0, 1, 2, 2000); // +1 day $week = gmmktime(0, 0, 0, 1, 8, 2000); // +1 week $month = gmmktime(0, 0, 0, 2, 1, 2000); // +1 month $year = gmmktime(0, 0, 0, 1, 1, 2001); // +1 year // corner cases $manymonths = gmmktime(0, 0, 0, 3, 1, 2001); // +14 months = +1 year +2 months $negmonths = gmmktime(0, 0, 0, 10, 1, 1999); // -3 months = -1 year +9 months // test valid duration with timestamp and zeroes $this->assertEquals($base + (60 * 60) + 60 + 1, Time::parseDuration('P0Y0M0DT1H1M1S', $base)); // test seconds $this->assertEquals($second, Time::parseDuration('PT1S', $base), "Failure checking for 1 second duration."); // test minutes $this->assertEquals($minute, Time::parseDuration('PT1M', $base), "Failure checking for 1 minute duration."); // test hours $this->assertEquals($hour, Time::parseDuration('PT1H', $base), "Failure checking for 1 hour duration."); // test days $this->assertEquals($day, Time::parseDuration('P1D', $base), "Failure checking for 1 day duration."); // test weeks $this->assertEquals($week, Time::parseDuration('P1W', $base), "Failure checking for 1 week duration."); // test month $this->assertEquals($month, Time::parseDuration('P1M', $base), "Failure checking for 1 month duration."); // test year $this->assertEquals($year, Time::parseDuration('P1Y', $base), "Failure checking for 1 year duration."); // test months > 12 $this->assertEquals( $manymonths, Time::parseDuration('P14M', $base), "Failure checking for 14 months duration (1 year and 2 months)." ); // test negative months $this->assertEquals( $negmonths, Time::parseDuration('-P3M', $base), "Failure checking for -3 months duration (-1 year + 9 months)." ); // test from current time $now = time(); $this->assertGreaterThanOrEqual( $now + 60, Time::parseDuration('PT1M'), "Failure testing for 1 minute over current time." ); // test invalid input parameters try { // invalid duration /** * @deprecated This test becomes useless as soon as the codebase is fully typehinted * @psalm-suppress InvalidScalarArgument */ Time::parseDuration(0); $this->fail("Did not fail with invalid duration parameter."); } catch (\InvalidArgumentException $e) { $this->assertEquals('Invalid input parameters', $e->getMessage()); } try { // invalid timestamp /** * @deprecated This test becomes useless as soon as the codebase is fully typehinted * @psalm-suppress InvalidArgument */ Time::parseDuration('', []); $this->fail("Did not fail with invalid timestamp parameter."); } catch (\InvalidArgumentException $e) { $this->assertEquals('Invalid input parameters', $e->getMessage()); } // test invalid durations try { // invalid string Time::parseDuration('abcdefg'); $this->fail("Did not fail with invalid ISO 8601 duration."); } catch (InvalidArgumentException $e) { $this->assertStringStartsWith('Invalid ISO 8601 duration: ', $e->getMessage()); } try { // missing T delimiter Time::parseDuration('P1S'); $this->fail("Did not fail with duration missing T delimiter."); } catch (InvalidArgumentException $e) { $this->assertStringStartsWith('Invalid ISO 8601 duration: ', $e->getMessage()); } } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/ArraysTest.php0000644000000000000000000000712114042503475022714 0ustar rootrootassertEquals($array, Arrays::arrayize($array)); // check non-empty array as input $array = ['key' => 'value']; $this->assertEquals($array, Arrays::arrayize($array)); // check indexes are ignored when input is an array $this->assertArrayNotHasKey('invalid', Arrays::arrayize($array, 'invalid')); // check default index $expected = ['string']; $this->assertEquals($expected, Arrays::arrayize($expected[0])); // check string index $index = 'key'; $expected = [$index => 'string']; $this->assertEquals($expected, Arrays::arrayize($expected[$index], $index)); } /** * Test the transpose() function. * @return void */ public function testTranspose(): void { // check not array /** @psalm-suppress InvalidArgument Can be removed as soon as the codebase is fully typehinted */ $this->assertFalse(Arrays::transpose('string')); // check bad arrays $this->assertFalse( Arrays::transpose(['1', '2', '3']), 'Invalid two-dimensional array was accepted' ); $this->assertFalse( Arrays::transpose(['1' => 0, '2' => '0', '3' => [0]]), 'Invalid elements on a two-dimensional array were accepted' ); // check array with numerical keys $array = [ 'key1' => [ 'value1' ], 'key2' => [ 'value1', 'value2' ] ]; $transposed = [ [ 'key1' => 'value1', 'key2' => 'value1' ], [ 'key2' => 'value2' ] ]; $this->assertEquals( $transposed, Arrays::transpose($array), 'Unexpected result of transpose()' ); // check array with string keys $array = [ 'key1' => [ 'subkey1' => 'value1' ], 'key2' => [ 'subkey1' => 'value1', 'subkey2' => 'value2' ] ]; $transposed = [ 'subkey1' => [ 'key1' => 'value1', 'key2' => 'value1' ], 'subkey2' => [ 'key2' => 'value2' ] ]; $this->assertEquals( $transposed, Arrays::transpose($array), 'Unexpected result of transpose()' ); // check array with no keys in common between sub arrays $array = [ 'key1' => [ 'subkey1' => 'value1' ], 'key2' => [ 'subkey2' => 'value1', 'subkey3' => 'value2' ] ]; $transposed = [ 'subkey1' => [ 'key1' => 'value1', ], 'subkey2' => [ 'key2' => 'value1' ], 'subkey3' => [ 'key2' => 'value2' ] ]; $this->assertEquals( $transposed, Arrays::transpose($array), 'Unexpected result of transpose()' ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/ConfigTest.php0000644000000000000000000000454114042503475022663 0ustar rootrootassertEquals($configDir, dirname(dirname(dirname(dirname(__DIR__)))) . '/config'); } /** * Test valid dir specified by env var overrides default config dir * @return void */ public function testEnvVariableConfigDir(): void { putenv('SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__); $configDir = Config::getConfigDir(); $this->assertEquals($configDir, __DIR__); } /** * Test valid dir specified by env redirect var overrides default config dir * @return void */ public function testEnvRedirectVariableConfigDir(): void { putenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__); $configDir = Config::getConfigDir(); $this->assertEquals($configDir, __DIR__); } /** * Test which directory takes precedence * @return void */ public function testEnvRedirectPriorityVariableConfigDir(): void { putenv('SIMPLESAMLPHP_CONFIG_DIR=' . dirname(__DIR__)); putenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__); $configDir = Config::getConfigDir(); $this->assertEquals($configDir, dirname(__DIR__)); } /** * Test invalid dir specified by env var results in a thrown exception * @return void */ public function testInvalidEnvVariableConfigDirThrowsException(): void { // I used a random hash to ensure this test directory is always invalid $invalidDir = __DIR__ . '/e9826ad19cbc4f5bf20c0913ffcd2ce6'; putenv('SIMPLESAMLPHP_CONFIG_DIR=' . $invalidDir); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'Config directory specified by environment variable SIMPLESAMLPHP_CONFIG_DIR is not a directory. ' . 'Given: "' . $invalidDir . '"' ); Config::getConfigDir(); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/HTTPTest.php0000644000000000000000000006017714042503475022244 0ustar rootrootexpectException(\InvalidArgumentException::class); HTTP::addURLParameters([], []); } /** * Test SimpleSAML\Utils\HTTP::addURLParameters(). * @return void * @psalm-suppress InvalidArgument * @deprecated Can be removed in 2.0 when codebase if fully typehinted */ public function testAddURLParametersInvalidParameters() { $this->expectException(\InvalidArgumentException::class); HTTP::addURLParameters('string', 'string'); } /** * Test SimpleSAML\Utils\HTTP::addURLParameters(). * @return void */ public function testAddURLParameters(): void { $url = 'http://example.com/'; $params = [ 'foo' => 'bar', 'bar' => 'foo', ]; $this->assertEquals($url . '?foo=bar&bar=foo', HTTP::addURLParameters($url, $params)); $url = 'http://example.com/?'; $params = [ 'foo' => 'bar', 'bar' => 'foo', ]; $this->assertEquals($url . 'foo=bar&bar=foo', HTTP::addURLParameters($url, $params)); $url = 'http://example.com/?foo=bar'; $params = [ 'bar' => 'foo', ]; $this->assertEquals($url . '&bar=foo', HTTP::addURLParameters($url, $params)); } /** * Test SimpleSAML\Utils\HTTP::guessBasePath(). * @return void */ public function testGuessBasePath(): void { $original = $_SERVER; $_SERVER['REQUEST_URI'] = '/simplesaml/module.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/simplesaml/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/simplesaml/module.php/some/path/to/other/script.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/simplesaml/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/module.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/module.php/some/path/to/other/script.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/some/path/module.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/some/path/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/some/path/module.php/some/path/to/other/script.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php'; $this->assertEquals('/some/path/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/some/dir/in/www/script.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/some/dir/in/www/script.php'; $this->assertEquals('/', HTTP::guessBasePath()); $_SERVER['REQUEST_URI'] = '/simplesaml/some/dir/in/www/script.php'; $_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/some/dir/in/www/script.php'; $this->assertEquals('/simplesaml/', HTTP::guessBasePath()); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::getSelfHost() with and without custom port. * @return void */ public function testGetSelfHost(): void { $original = $_SERVER; Configuration::loadFromArray([ 'baseurlpath' => '', ], '[ARRAY]', 'simplesaml'); $_SERVER['SERVER_PORT'] = '80'; $this->assertEquals('localhost', HTTP::getSelfHost()); $_SERVER['SERVER_PORT'] = '3030'; $this->assertEquals('localhost', HTTP::getSelfHost()); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::getSelfHostWithPort(), with and without custom port. * @return void */ public function testGetSelfHostWithPort(): void { $original = $_SERVER; Configuration::loadFromArray([ 'baseurlpath' => '', ], '[ARRAY]', 'simplesaml'); // standard port for HTTP $_SERVER['SERVER_PORT'] = '80'; $this->assertEquals('localhost', HTTP::getSelfHostWithNonStandardPort()); // non-standard port $_SERVER['SERVER_PORT'] = '3030'; $this->assertEquals('localhost:3030', HTTP::getSelfHostWithNonStandardPort()); // standard port for HTTPS $_SERVER['HTTPS'] = 'on'; $_SERVER['SERVER_PORT'] = '443'; $this->assertEquals('localhost', HTTP::getSelfHostWithNonStandardPort()); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::getSelfURL(). * @return void */ public function testGetSelfURLMethods(): void { $original = $_SERVER; /* * Test a URL pointing to a script that's not part of the public interface. This allows us to test calls to * getSelfURL() from scripts outside of SimpleSAMLphp */ Configuration::loadFromArray([ 'baseurlpath' => 'http://example.com/simplesaml/', ], '[ARRAY]', 'simplesaml'); $url = 'https://example.com/app/script.php/some/path?foo=bar'; $this->setupEnvFromURL($url); $_SERVER['SCRIPT_FILENAME'] = '/var/www/app/script.php'; $this->assertEquals($url, HTTP::getSelfURL()); $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); $this->assertEquals('https://example.com/app/script.php/some/path', HTTP::getSelfURLNoQuery()); $this->assertTrue(HTTP::isHTTPS()); $this->assertEquals('https://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a request URI that doesn't match the current script $cfg = Configuration::loadFromArray([ 'baseurlpath' => 'https://example.org/simplesaml/', ], '[ARRAY]', 'simplesaml'); $baseDir = $cfg->getBaseDir(); $_SERVER['SCRIPT_FILENAME'] = $baseDir . 'www/module.php'; $this->setupEnvFromURL('http://www.example.com/protected/resource.asp?foo=bar'); $this->assertEquals('http://www.example.com/protected/resource.asp?foo=bar', HTTP::getSelfURL()); $this->assertEquals('http://www.example.com', HTTP::getSelfURLHost()); $this->assertEquals('http://www.example.com/protected/resource.asp', HTTP::getSelfURLNoQuery()); $this->assertFalse(HTTP::isHTTPS()); $this->assertEquals('example.org', HTTP::getSelfHostWithNonStandardPort()); $this->assertEquals('http://www.example.com', HTTP::getSelfURLHost()); // test a valid, full URL, based on a full URL in the configuration Configuration::loadFromArray([ 'baseurlpath' => 'https://example.com/simplesaml/', ], '[ARRAY]', 'simplesaml'); $this->setupEnvFromURL('http://www.example.org/module.php/module/file.php?foo=bar'); $this->assertEquals( 'https://example.com/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); $this->assertTrue(HTTP::isHTTPS()); $this->assertEquals('https://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a full URL *without* a trailing slash in the configuration Configuration::loadFromArray([ 'baseurlpath' => 'https://example.com/simplesaml', ], '[ARRAY]', 'simplesaml'); $this->assertEquals( 'https://example.com/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); $this->assertTrue(HTTP::isHTTPS()); $this->assertEquals('https://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a full URL *without* a path in the configuration Configuration::loadFromArray([ 'baseurlpath' => 'https://example.com', ], '[ARRAY]', 'simplesaml'); $this->assertEquals( 'https://example.com/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); $this->assertEquals('https://example.com/module.php/module/file.php', HTTP::getSelfURLNoQuery()); $this->assertTrue(HTTP::isHTTPS()); $this->assertEquals('https://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration Configuration::loadFromArray([ 'baseurlpath' => '/simplesaml/', ], '[ARRAY]', 'simplesaml'); $this->setupEnvFromURL('http://www.example.org/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( 'http://www.example.org/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('http://www.example.org', HTTP::getSelfURLHost()); $this->assertEquals('http://www.example.org/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); $this->assertFalse(HTTP::isHTTPS()); $this->assertEquals('http://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration and a non standard port Configuration::loadFromArray([ 'baseurlpath' => '/simplesaml/', ], '[ARRAY]', 'simplesaml'); $this->setupEnvFromURL('http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( 'http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('http://example.org:8080', HTTP::getSelfURLHost()); $this->assertEquals('http://example.org:8080/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); $this->assertFalse(HTTP::isHTTPS()); $this->assertEquals('http://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS Configuration::loadFromArray([ 'baseurlpath' => '/simplesaml/', ], '[ARRAY]', 'simplesaml'); $this->setupEnvFromURL('https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( 'https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); $this->assertEquals('https://example.org:8080', HTTP::getSelfURLHost()); $this->assertEquals( 'https://example.org:8080/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery() ); $this->assertTrue(HTTP::isHTTPS()); $this->assertEquals('https://' . HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), without regex. * @return void */ public function testCheckURLAllowedWithoutRegex(): void { $original = $_SERVER; Configuration::loadFromArray([ 'trusted.url.domains' => ['sp.example.com', 'app.example.com'], 'trusted.url.regex' => false, ], '[ARRAY]', 'simplesaml'); $_SERVER['REQUEST_URI'] = '/module.php'; $allowed = [ 'https://sp.example.com/', 'http://sp.example.com/', 'https://app.example.com/', 'http://app.example.com/', ]; foreach ($allowed as $url) { $this->assertEquals(HTTP::checkURLAllowed($url), $url); } $this->expectException(\SimpleSAML\Error\Exception::class); HTTP::checkURLAllowed('https://evil.com'); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with regex. * @return void */ public function testCheckURLAllowedWithRegex(): void { $original = $_SERVER; Configuration::loadFromArray([ 'trusted.url.domains' => ['.*\.example\.com'], 'trusted.url.regex' => true, ], '[ARRAY]', 'simplesaml'); $_SERVER['REQUEST_URI'] = '/module.php'; $allowed = [ 'https://sp.example.com/', 'http://sp.example.com/', 'https://app1.example.com/', 'http://app1.example.com/', 'https://app2.example.com/', 'http://app2.example.com/', ]; foreach ($allowed as $url) { $this->assertEquals(HTTP::checkURLAllowed($url), $url); } $this->expectException(\SimpleSAML\Error\Exception::class); HTTP::checkURLAllowed('https://evil.com'); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::getServerPort(). * @return void */ public function testGetServerPort(): void { $original = $_SERVER; // Test HTTP + non-standard port $_SERVER['HTTPS'] = 'off'; $_SERVER['SERVER_PORT'] = '3030'; $this->assertEquals(HTTP::getServerPort(), ':3030'); // Test HTTP + standard port $_SERVER['SERVER_PORT'] = '80'; $this->assertEquals(HTTP::getServerPort(), ''); // Test HTTP + standard integer port $_SERVER['SERVER_PORT'] = 80; $this->assertEquals(HTTP::getServerPort(), ''); // Test HTTP + without port unset($_SERVER['SERVER_PORT']); $this->assertEquals(HTTP::getServerPort(), ''); // Test HTTPS + non-standard port $_SERVER['HTTPS'] = 'on'; $_SERVER['SERVER_PORT'] = '3030'; $this->assertEquals(HTTP::getServerPort(), ':3030'); // Test HTTPS + non-standard integer port $_SERVER['SERVER_PORT'] = 3030; $this->assertEquals(HTTP::getServerPort(), ':3030'); // Test HTTPS + standard port $_SERVER['SERVER_PORT'] = '443'; $this->assertEquals(HTTP::getServerPort(), ''); // Test HTTPS + without port unset($_SERVER['SERVER_PORT']); $this->assertEquals(HTTP::getServerPort(), ''); $_SERVER = $original; } /** * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with the regex as a * subdomain of an evil domain. * @return void */ public function testCheckURLAllowedWithRegexWithoutDelimiters(): void { $original = $_SERVER; Configuration::loadFromArray([ 'trusted.url.domains' => ['app\.example\.com'], 'trusted.url.regex' => true, ], '[ARRAY]', 'simplesaml'); $_SERVER['REQUEST_URI'] = '/module.php'; $this->expectException(Error\Exception::class); HTTP::checkURLAllowed('https://app.example.com.evil.com'); $_SERVER = $original; } /** * @covers SimpleSAML\Utils\HTTP::getFirstPathElement() * @return void */ public function testGetFirstPathElement(): void { $original = $_SERVER; $_SERVER['SCRIPT_NAME'] = '/test/tmp.php'; $this->assertEquals(HTTP::getFirstPathElement(), '/test'); $this->assertEquals(HTTP::getFirstPathElement(false), 'test'); $_SERVER = $original; } /** * @covers SimpleSAML\Utils\HTTP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookie(): void { $original = $_SERVER; Configuration::loadFromArray([ 'baseurlpath' => 'https://example.com/simplesaml/', ], '[ARRAY]', 'simplesaml'); $url = 'https://example.com/a?b=c'; $this->setupEnvFromURL($url); HTTP::setCookie( 'TestCookie', 'value%20', [ 'expire' => 2147483640, 'path' => '/ourPath', 'domain' => 'example.com', 'secure' => true, 'httponly' => true ] ); HTTP::setCookie( 'RawCookie', 'value%20', [ 'lifetime' => 100, 'path' => '/ourPath', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'raw' => true ] ); $headers = xdebug_get_headers(); $this->assertContains('TestCookie=value%2520;', $headers[0]); $this->assertRegExp('/\b[Ee]xpires=[Tt]ue/', $headers[0]); $this->assertRegExp('/\b[Pp]ath=\/ourPath(;|$)/', $headers[0]); $this->assertRegExp('/\b[Dd]omain=example.com(;|$)/', $headers[0]); $this->assertRegExp('/\b[Ss]ecure(;|$)/', $headers[0]); $this->assertRegExp('/\b[Hh]ttp[Oo]nly(;|$)/', $headers[0]); $this->assertContains('RawCookie=value%20;', $headers[1]); $this->assertRegExp('/\b[Ee]xpires=([Mm]on|[Tt]ue|[Ww]ed|[Tt]hu|[Ff]ri|[Ss]at|[Ss]un)/', $headers[1]); $this->assertRegExp('/\b[Pp]ath=\/ourPath(;|$)/', $headers[1]); $this->assertRegExp('/\b[Dd]omain=example.com(;|$)/', $headers[1]); $this->assertRegExp('/\b[Ss]ecure(;|$)/', $headers[1]); $this->assertRegExp('/\b[Hh]ttp[Oo]nly(;|$)/', $headers[1]); $_SERVER = $original; } /** * @covers SimpleSAML\Utils\HTTP::setCookie() * @return void */ public function testSetCookieInsecure(): void { $this->expectException(Error\CannotSetCookie::class); $original = $_SERVER; Configuration::loadFromArray([ 'baseurlpath' => 'http://example.com/simplesaml/', ], '[ARRAY]', 'simplesaml'); $url = 'http://example.com/a?b=c'; $this->setupEnvFromURL($url); HTTP::setCookie('testCookie', 'value', ['secure' => true], true); $_SERVER = $original; } /** * @covers SimpleSAML\Utils\HTTP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookieSameSite(): void { HTTP::setCookie('SSNull', 'value', ['samesite' => null]); HTTP::setCookie('SSNone', 'value', ['samesite' => 'None']); HTTP::setCookie('SSLax', 'value', ['samesite' => 'Lax']); HTTP::setCookie('SSStrict', 'value', ['samesite' => 'Strict']); $headers = xdebug_get_headers(); $this->assertNotRegExp('/\b[Ss]ame[Ss]ite=/', $headers[0]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=None(;|$)/', $headers[1]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=Lax(;|$)/', $headers[2]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=Strict(;|$)/', $headers[3]); } /** * Test detecting if user agent supports None * @dataProvider detectSameSiteProvider * @param null|string $userAgent The user agent. Null means not set, like with CLI * @param bool $supportsNone None can be set as a SameSite flag */ public function testDetectSameSiteNoneBehavior(?string $userAgent, bool $supportsNone): void { if ($userAgent) { $_SERVER['HTTP_USER_AGENT'] = $userAgent; } $this->assertEquals($supportsNone, HTTP::canSetSameSiteNone(), $userAgent ?? 'No user agent set'); } public function detectSameSiteProvider(): array { // @codingStandardsIgnoreStart return [ [null, true], ['some-new-browser', true], //Browsers that can handle 'None' // Chrome ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36', true], // Chome on windows ['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', true], // Chrome linux ['Mozilla/5.0 (X11; HasCodingOs 1.0; Linux x64) AppleWebKit/637.36 (KHTML, like Gecko) Chrome/70.0.3112.101 Safari/637.36 HasBrowser/5.0', true], // Safari iOS 13 ['Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.2 Mobile/15E148 Safari/604.1', true], // Mac OS X with support ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15', true], // UC Browser with support ['Mozilla/5.0 (Linux; U; Android 9; en-US; SM-A705FN Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.2.1208 Mobile Safari/537.36', true], ['Mozilla/5.0 (Linux; U; Android 10; en-US; RMX2020 Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.5.1209 Mobile Safari/537.36', true], // Embedded Mac with support ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko)', true], // Browser without support // Old Safari on mac ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15', false], // Old Safari on iOS 12 (phone and ipad ['Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Mobile/15E148 Safari/604.1', false], ['Mozilla/5.0 (iPad; CPU OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/16A5288q Safari/605.1.15', false], // Chromium without support ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/65.0.3325.181 Chrome/65.0.3325.181 Safari/537.36', false], // UC Browser without support ['Mozilla/5.0 (Linux; U; Android 8.1.0; zh-CN; EML-AL00 Build/HUAWEIEML-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 baidu.sogo.uc.UCBrowser/11.9.4.974 UWS/2.13.1.48 Mobile Safari/537.36 AliApp(DingTalk/4.5.11) com.alibaba.android.rimet/10487439 Channel/227200 language/zh-CN', false], ['Mozilla/5.0 (Linux; U; Android 7.1.1; en-US; CPH1723 Build/N6F26Q) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.13.0.1207 Mobile Safari/537.36', false], // old embedded browser ['Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/605.1.15 (KHTML, like Gecko)', false] ]; // @codingStandardsIgnoreEnd } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/RandomTest.php0000644000000000000000000000121014042503475022664 0ustar rootrootassertStringStartsWith('_', Random::generateID()); // check the length $this->assertEquals(Random::ID_LENGTH, strlen(Random::generateID())); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/XMLTest.php0000644000000000000000000002400414042503475022112 0ustar rootrootassertTrue($res); } /** * @covers \SimpleSAML\Utils\XML::isDOMNodeOfType * @test * @return void */ public function testIsDomNodeOfTypeMissingNamespace(): void { $this->expectException(InvalidArgumentException::class); $name = 'name'; $namespace_uri = '@missing'; $element = new DOMElement($name, 'value', $namespace_uri); XML::isDOMNodeOfType($element, $name, $namespace_uri); } /** * @covers \SimpleSAML\Utils\XML::isDOMNodeOfType * @test * @return void */ public function testIsDomNodeOfTypeEmpty(): void { $name = 'name'; $namespace_uri = ''; $element = new DOMElement($name); $res = XML::isDOMNodeOfType($element, $name, $namespace_uri); $this->assertFalse($res); } /** * @covers \SimpleSAML\Utils\XML::isDOMNodeOfType * @test * @return void */ public function testIsDomNodeOfTypeShortcut(): void { $name = 'name'; $namespace_uri = 'urn:oasis:names:tc:SAML:2.0:metadata'; $short_namespace_uri = '@md'; $element = new DOMElement($name, 'value', $namespace_uri); $res = XML::isDOMNodeOfType($element, $name, $short_namespace_uri); $this->assertTrue($res); } /** * @covers \SimpleSAML\Utils\XML::isDOMNodeOfType * @test * @return void */ public function testIsDomNodeOfTypeIncorrectName(): void { $name = 'name'; $bad_name = 'bad name'; $namespace_uri = 'ns'; $element = new DOMElement($name, 'value', $namespace_uri); $res = XML::isDOMNodeOfType($element, $bad_name, $namespace_uri); $this->assertFalse($res); } /** * @covers \SimpleSAML\Utils\XML::isDOMNodeOfType * @test * @return void */ public function testIsDomNodeOfTypeIncorrectNamespace(): void { $name = 'name'; $namespace_uri = 'ns'; $bad_namespace_uri = 'bad name'; $element = new DOMElement($name, 'value', $namespace_uri); $res = XML::isDOMNodeOfType($element, $name, $bad_namespace_uri); $this->assertFalse($res); } /** * @covers \SimpleSAML\Utils\XML::getDOMText * @test * @return void */ public function testGetDomTextBasic(): void { $data = 'root value'; $dom = new DOMDocument(); $element = $dom->appendChild(new \DOMElement('root')); $element->appendChild(new DOMText($data)); $res = XML::getDOMText($element); $expected = $data; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::getDOMText * @test * @return void */ public function testGetDomTextMulti(): void { $data1 = 'root value 1'; $data2 = 'root value 2'; $dom = new DOMDocument(); $element = $dom->appendChild(new DOMElement('root')); $element->appendChild(new DOMText($data1)); $element->appendChild(new DOMText($data2)); $res = XML::getDOMText($element); $expected = $data1 . $data2 . $data1 . $data2; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::getDOMText * @test * @return void */ public function testGetDomTextIncorrectType(): void { $this->expectException(Error\Exception::class); $dom = new DOMDocument(); $element = $dom->appendChild(new DOMElement('root')); $element->appendChild(new DOMComment('')); XML::getDOMText($element); } /** * @covers \SimpleSAML\Utils\XML::getDOMChildren * @test * @return void */ public function testGetDomChildrenBasic(): void { $name = 'name'; $namespace_uri = 'ns'; $dom = new DOMDocument(); $element = new DOMElement($name, 'value', $namespace_uri); $dom->appendChild($element); $res = XML::getDOMChildren($dom, $name, $namespace_uri); $expected = [$element]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::getDOMChildren * @test * @return void */ public function testGetDomChildrenIncorrectType(): void { $dom = new DOMDocument(); $text = new DOMText('text'); $comment = new DOMComment('comment'); $dom->appendChild($text); $dom->appendChild($comment); $res = XML::getDOMChildren($dom, 'name', 'ns'); $this->assertEmpty($res); } /** * @covers \SimpleSAML\Utils\XML::getDOMChildren * @test * @return void */ public function testGetDomChildrenIncorrectName(): void { $name = 'name'; $bad_name = 'bad name'; $namespace_uri = 'ns'; $dom = new DOMDocument(); $element = new DOMElement($name, 'value', $namespace_uri); $dom->appendChild($element); $res = XML::getDOMChildren($dom, $bad_name, $namespace_uri); $this->assertEmpty($res); } /** * @covers \SimpleSAML\Utils\XML::formatDOMElement * @test * @return void */ public function testFormatDomElementBasic(): void { $dom = new DOMDocument(); $root = new DOMElement('root'); $dom->appendChild($root); $root->appendChild(new \DOMText('text')); XML::formatDOMElement($root); $res = $dom->saveXML(); $expected = <<<'NOWDOC' text NOWDOC; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::formatDOMElement * @test * @return void */ public function testFormatDomElementNested(): void { $dom = new DOMDocument(); $root = new DOMElement('root'); $nested = new DOMElement('nested'); $dom->appendChild($root); $root->appendChild($nested); $nested->appendChild(new DOMText('text')); XML::formatDOMElement($root); $res = $dom->saveXML(); $expected = <<<'NOWDOC' text NOWDOC; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::formatDOMElement * @test * @return void */ public function testFormatDomElementIndentBase(): void { $indent_base = 'base'; $dom = new DOMDocument(); $root = new DOMElement('root'); $nested = new DOMElement('nested'); $dom->appendChild($root); $root->appendChild($nested); $nested->appendChild(new DOMText('text')); XML::formatDOMElement($root, $indent_base); $res = $dom->saveXML(); $expected = << $indent_base text $indent_base HEREDOC; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::formatDOMElement * @test * @return void */ public function testFormatDomElementTextAndChild(): void { $dom = new DOMDocument(); $root = new DOMElement('root'); $dom->appendChild($root); $root->appendChild(new DOMText('text')); $root->appendChild(new DOMElement('child')); XML::formatDOMElement($root); $res = $dom->saveXML(); $expected = << text HEREDOC; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::formatXMLString * @test * @return void */ public function testFormatXmlStringBasic(): void { $xml = 'text'; $res = XML::formatXMLString($xml); $expected = <<<'NOWDOC' text NOWDOC; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::formatXMLString * @test * @return void */ public function testFormatXmlStringMalformedXml(): void { $this->expectException(DOMException::class); $xml = 'text'; XML::formatXMLString($xml); } /** * @covers \SimpleSAML\Utils\XML::isValid * @test * @return void */ public function testIsValidMalformedXml(): void { $xml = 'text'; $res = XML::isValid($xml, 'unused'); $this->assertIsString($res); $expected = 'Failed to parse XML string for schema validation'; $this->assertContains($expected, $res); } /** * @covers \SimpleSAML\Utils\XML::isValid * @return void */ public function testIsValidMetadata(): void { $schema = 'saml-schema-metadata-2.0.xsd'; $xml = file_get_contents(self::FRAMEWORK . '/metadata/xml/valid-metadata-selfsigned.xml'); $dom = new DOMDocument('1.0'); $dom->loadXML($xml, LIBXML_NONET); $res = XML::isValid($dom, $schema); $this->assertTrue($res === true); } /** * @covers \SimpleSAML\Utils\XML::checkSAMLMessage() * @return void */ public function testCheckSAMLMessageInvalidType(): void { $this->expectException(InvalidArgumentException::class); XML::checkSAMLMessage('', 'blub'); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/Config/0000755000000000000000000000000014042503475021306 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/Config/MetadataTest.php0000644000000000000000000002574514042503475024414 0ustar rootrootassertEquals('Invalid input parameters', $e->getMessage()); } // test missing type $contact = [ 'name' => 'John Doe' ]; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertStringStartsWith('"contactType" is mandatory and must be one of ', $e->getMessage()); } // test invalid type $contact = [ 'contactType' => 'invalid' ]; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertStringStartsWith('"contactType" is mandatory and must be one of ', $e->getMessage()); } // test all valid contact types foreach (Metadata::$VALID_CONTACT_TYPES as $type) { $contact = [ 'contactType' => $type ]; $parsed = Metadata::getContact($contact); $this->assertArrayHasKey('contactType', $parsed); $this->assertArrayNotHasKey('givenName', $parsed); $this->assertArrayNotHasKey('surName', $parsed); } // test basic name parsing $contact = [ 'contactType' => 'technical', 'name' => 'John Doe' ]; $parsed = Metadata::getContact($contact); $this->assertArrayNotHasKey('name', $parsed); $this->assertArrayHasKey('givenName', $parsed); $this->assertArrayHasKey('surName', $parsed); $this->assertEquals('John', $parsed['givenName']); $this->assertEquals('Doe', $parsed['surName']); // test comma-separated names $contact = [ 'contactType' => 'technical', 'name' => 'Doe, John' ]; $parsed = Metadata::getContact($contact); $this->assertArrayHasKey('givenName', $parsed); $this->assertArrayHasKey('surName', $parsed); $this->assertEquals('John', $parsed['givenName']); $this->assertEquals('Doe', $parsed['surName']); // test long names $contact = [ 'contactType' => 'technical', 'name' => 'John Fitzgerald Doe Smith' ]; $parsed = Metadata::getContact($contact); $this->assertArrayNotHasKey('name', $parsed); $this->assertArrayHasKey('givenName', $parsed); $this->assertArrayNotHasKey('surName', $parsed); $this->assertEquals('John Fitzgerald Doe Smith', $parsed['givenName']); // test comma-separated long names $contact = [ 'contactType' => 'technical', 'name' => 'Doe Smith, John Fitzgerald' ]; $parsed = Metadata::getContact($contact); $this->assertArrayNotHasKey('name', $parsed); $this->assertArrayHasKey('givenName', $parsed); $this->assertArrayHasKey('surName', $parsed); $this->assertEquals('John Fitzgerald', $parsed['givenName']); $this->assertEquals('Doe Smith', $parsed['surName']); // test givenName $contact = [ 'contactType' => 'technical', ]; $invalid_types = [0, [0], 0.1, true, false]; foreach ($invalid_types as $type) { $contact['givenName'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals('"givenName" must be a string and cannot be empty.', $e->getMessage()); } } // test surName $contact = [ 'contactType' => 'technical', ]; $invalid_types = [0, [0], 0.1, true, false]; foreach ($invalid_types as $type) { $contact['surName'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals('"surName" must be a string and cannot be empty.', $e->getMessage()); } } // test company $contact = [ 'contactType' => 'technical', ]; $invalid_types = [0, [0], 0.1, true, false]; foreach ($invalid_types as $type) { $contact['company'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals('"company" must be a string and cannot be empty.', $e->getMessage()); } } // test emailAddress $contact = [ 'contactType' => 'technical', ]; $invalid_types = [0, 0.1, true, false, []]; foreach ($invalid_types as $type) { $contact['emailAddress'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals( '"emailAddress" must be a string or an array and cannot be empty.', $e->getMessage() ); } } $invalid_types = [["string", true], ["string", 0]]; foreach ($invalid_types as $type) { $contact['emailAddress'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals( 'Email addresses must be a string and cannot be empty.', $e->getMessage() ); } } $valid_types = ['email@example.com', ['email1@example.com', 'email2@example.com']]; foreach ($valid_types as $type) { $contact['emailAddress'] = $type; $parsed = Metadata::getContact($contact); $this->assertEquals($type, $parsed['emailAddress']); } // test telephoneNumber $contact = [ 'contactType' => 'technical', ]; $invalid_types = [0, 0.1, true, false, []]; foreach ($invalid_types as $type) { $contact['telephoneNumber'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals( '"telephoneNumber" must be a string or an array and cannot be empty.', $e->getMessage() ); } } $invalid_types = [["string", true], ["string", 0]]; foreach ($invalid_types as $type) { $contact['telephoneNumber'] = $type; try { Metadata::getContact($contact); } catch (InvalidArgumentException $e) { $this->assertEquals('Telephone numbers must be a string and cannot be empty.', $e->getMessage()); } } $valid_types = ['1234', ['1234', '5678']]; foreach ($valid_types as $type) { $contact['telephoneNumber'] = $type; $parsed = Metadata::getContact($contact); $this->assertEquals($type, $parsed['telephoneNumber']); } // test completeness $contact = []; foreach (Metadata::$VALID_CONTACT_OPTIONS as $option) { $contact[$option] = 'string'; } $contact['contactType'] = 'technical'; $contact['name'] = 'to_be_removed'; $contact['attributes'] = ['test' => 'testval']; $parsed = Metadata::getContact($contact); foreach (array_keys($parsed) as $key) { $this->assertEquals($parsed[$key], $contact[$key]); } $this->assertArrayNotHasKey('name', $parsed); } /** * Test \SimpleSAML\Utils\Config\Metadata::isHiddenFromDiscovery(). * @return void */ public function testIsHiddenFromDiscovery(): void { // test for success $metadata = [ 'EntityAttributes' => [ Metadata::$ENTITY_CATEGORY => [ Metadata::$HIDE_FROM_DISCOVERY, ], ], ]; $this->assertTrue(Metadata::isHiddenFromDiscovery($metadata)); // test for failure $this->assertFalse(Metadata::isHiddenFromDiscovery([ 'EntityAttributes' => [ Metadata::$ENTITY_CATEGORY => [], ], ])); // test for failures $this->expectException(TypeError::class); Metadata::isHiddenFromDiscovery(['foo']); $this->assertFalse(Metadata::isHiddenFromDiscovery([ 'EntityAttributes' => 'bar', ])); $this->assertFalse(Metadata::isHiddenFromDiscovery([ 'EntityAttributes' => [], ])); $this->assertFalse(Metadata::isHiddenFromDiscovery([ 'EntityAttributes' => [ Metadata::$ENTITY_CATEGORY => '', ], ])); } /** * Test \SimpleSAML\Utils\Config\Metadata::parseNameIdPolicy(). * @return void */ public function testParseNameIdPolicy(): void { // Test null or unset $nameIdPolicy = null; $this->assertEquals( ['Format' => Constants::NAMEID_TRANSIENT, 'AllowCreate' => true], Metadata::parseNameIdPolicy($nameIdPolicy) ); // Test false $nameIdPolicy = false; $this->assertEquals(null, Metadata::parseNameIdPolicy($nameIdPolicy)); // Test string $nameIdPolicy = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'; $this->assertEquals( ['Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', 'AllowCreate' => true], Metadata::parseNameIdPolicy($nameIdPolicy) ); // Test array $nameIdPolicy = [ 'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:persistent', 'AllowCreate' => false ]; $this->assertEquals([ 'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:persistent', 'AllowCreate' => false ], Metadata::parseNameIdPolicy($nameIdPolicy)); $nameIdPolicy = [ 'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:persistent', 'AllowCreate' => false, 'SPNameQualifier' => 'TEST' ]; $this->assertEquals([ 'Format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:persistent', 'AllowCreate' => false, 'SPNameQualifier' => 'TEST' ], Metadata::parseNameIdPolicy($nameIdPolicy)); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/NetTest.php0000644000000000000000000000736714042503475022215 0ustar rootrootassertFalse(Net::ipCIDRcheck('127.0.0.0', '127.0.0.1')); // check wrong CIDR w/ mask $this->assertFalse(Net::ipCIDRcheck('127.0.0.256/24', '127.0.0.1')); // check wrong IP $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/24', '127.0.0')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.*')); // check limits for standard classes $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.0')); $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.255')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.256')); $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/16', '127.0.0.0')); $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/16', '127.0.255.255')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/16', '127.0.255.256')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/16', '127.0.256.255')); // check limits for non-standard classes $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/23', '127.0.0.0')); $this->assertTrue(Net::ipCIDRcheck('127.0.0.0/23', '127.0.1.255')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/23', '127.0.1.256')); $this->assertFalse(Net::ipCIDRcheck('127.0.0.0/23', '127.0.2.0')); } /** * Test IPv6 support in SimpleSAML\Utils\Net::ipCIDRcheck. * * @covers SimpleSAML\Utils\Net::ipCIDRcheck * @return void */ public function testIpv6CIDRcheck(): void { // check CIDR w/o mask $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::', '2001:0DB8::1')); // check wrong CIDR w/ mask $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/128', '2001:0DB8::1')); // check wrong IP $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/128', '2001:0DB8::Z')); // check limits for standard classes $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/128', '2001:0DB8:0000:0000:0000:0000:0000:0000')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/128', '2001:0DB8::0')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/128', '2001:0DB8::1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/112', '2001:0DB8::1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/112', '2001:0DB8::1:1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/112', '2001:0DB8::FFFF')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/112', '2001:0DB8::1:FFFF')); // check limits for non-standard classes $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/108', '2001:0DB8::1:1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/108', '2001:0DB8::F:1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/108', '2001:0DB8::FF:1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/108', '2001:0DB8::1FF:1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/108', '2001:0DB8::FFFF:1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/104', '2001:0DB8::1:1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/104', '2001:0DB8::F:1')); $this->assertTrue(Net::ipCIDRcheck('2001:0DB8::/104', '2001:0DB8::FF:1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/104', '2001:0DB8::1FF:1')); $this->assertFalse(Net::ipCIDRcheck('2001:0DB8::/104', '2001:0DB8::FFFF:1')); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/SystemTest.php0000644000000000000000000001737214042503475022750 0ustar rootrootroot = vfsStream::setup( self::ROOTDIRNAME, null, [ self::DEFAULTTEMPDIR => [], ] ); $this->root_directory = vfsStream::url(self::ROOTDIRNAME); } /** * @covers \SimpleSAML\Utils\System::getOS * @test * @return void */ public function testGetOSBasic(): void { $res = System::getOS(); $this->assertInternalType("int", $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathRemoveTrailingSlashes(): void { $base = "/base////"; $path = "test"; $res = System::resolvePath($path, $base); $expected = "/base/test"; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathPreferAbsolutePathToBase(): void { $base = "/base/"; $path = "/test"; $res = System::resolvePath($path, $base); $expected = "/test"; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathCurDirPath(): void { $base = "/base/"; $path = "/test/."; $res = System::resolvePath($path, $base); $expected = "/test"; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathParentPath(): void { $base = "/base/"; $path = "/test/child/.."; $res = System::resolvePath($path, $base); $expected = "/test"; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathAllowsStreamWrappers(): void { $base = '/base/'; $path = 'vfs://simplesaml'; $res = System::resolvePath($path, $base); $expected = $path; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::resolvePath * @test * @return void */ public function testResolvePathAllowsAwsS3StreamWrappers(): void { $base = '/base/'; $path = 's3://bucket-name/key-name'; $res = System::resolvePath($path, $base); $expected = $path; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\System::writeFile * @test * @deprecated Test becomes obsolete as soon as the codebase is fully type hinted * @return void */ public function testWriteFileInvalidArguments() { $this->expectException(InvalidArgumentException::class); /** @psalm-suppress NullArgument */ System::writeFile(null, null, null); } /** * @covers \SimpleSAML\Utils\System::writeFile * @test * @return void */ public function testWriteFileBasic(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTTEMPDIR; $config = $this->setConfigurationTempDir($tempdir); $filename = $this->root_directory . DIRECTORY_SEPARATOR . 'test'; System::writeFile($filename, ''); $this->assertFileExists($filename); $this->clearInstance($config, Configuration::class); } /** * @covers \SimpleSAML\Utils\System::writeFile * @test * @return void */ public function testWriteFileContents(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTTEMPDIR; $config = $this->setConfigurationTempDir($tempdir); $filename = $this->root_directory . DIRECTORY_SEPARATOR . 'test'; $contents = 'TEST'; System::writeFile($filename, $contents); $res = file_get_contents($filename); $expected = $contents; $this->assertEquals($expected, $res); $this->clearInstance($config, Configuration::class); } /** * @covers \SimpleSAML\Utils\System::writeFile * @test * @return void */ public function testWriteFileMode(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTTEMPDIR; $config = $this->setConfigurationTempDir($tempdir); $filename = $this->root_directory . DIRECTORY_SEPARATOR . 'test'; $mode = 0666; System::writeFile($filename, '', $mode); $res = $this->root->getChild('test')->getPermissions(); $expected = $mode; $this->assertEquals($expected, $res); $this->clearInstance($config, Configuration::class); } /** * @covers \SimpleSAML\Utils\System::getTempDir * @test * @return void */ public function testGetTempDirBasic(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTTEMPDIR; $config = $this->setConfigurationTempDir($tempdir); $res = System::getTempDir(); $expected = $tempdir; $this->assertEquals($expected, $res); $this->assertFileExists($res); $this->clearInstance($config, Configuration::class); } /** * @covers \SimpleSAML\Utils\System::getTempDir * @test * @return void */ public function testGetTempDirNonExistant(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . 'nonexistant'; $config = $this->setConfigurationTempDir($tempdir); $res = System::getTempDir(); $expected = $tempdir; $this->assertEquals($expected, $res); $this->assertFileExists($res); $this->clearInstance($config, Configuration::class); } /** * @covers \SimpleSAML\Utils\System::getTempDir * @test * @return void */ public function testGetTempDirBadPermissions(): void { $tempdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTTEMPDIR; $config = $this->setConfigurationTempDir($tempdir); chmod($tempdir, 0440); $this->expectException(Error\Exception::class); System::getTempDir(); $this->clearInstance($config, Configuration::class); } /** * @param string $directory * @return \SimpleSAML\Configuration */ private function setConfigurationTempDir(string $directory): Configuration { $config = Configuration::loadFromArray([ 'tempdir' => $directory, ], '[ARRAY]', 'simplesaml'); return $config; } /** * @param \SimpleSAML\Configuration $service * @param class-string $className * @return void */ protected function clearInstance(Configuration $service, string $className): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, null); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/EMailTest.php0000644000000000000000000001130014042503475022434 0ustar rootroot 'na@example.org', ], '[ARRAY]', 'simplesaml'); } /** * Test that an exception is thrown if using default configuration, * and no custom from address is specified. * @return void */ public function testMailFromDefaultConfigurationException(): void { $this->expectException(Exception::class); new EMail('test', null, 'phpunit@simplesamlphp.org'); } /** * Test that an exception is thrown if using an invalid "From"-address * @return void */ public function testInvalidFromAddressException(): void { $this->expectException(Exception::class); new EMail('test', "phpunit@simplesamlphp.org\nLorem Ipsum", 'phpunit@simplesamlphp.org'); } /** * Test that an exception is thrown if using an invalid "To"-address * @return void */ public function testInvalidToAddressException(): void { $this->expectException(Exception::class); new EMail('test', 'phpunit@simplesamlphp.org', "phpunit@simplesamlphp.org\nLorem Ipsum"); } /** * Test that the data given is visible in the resulting mail * @dataProvider mailTemplates * @param string $template * @return void */ public function testMailContents($template): void { $mail = new EMail( 'subject-subject-subject-subject-subject-subject-subject', 'phpunit@simplesamlphp.org', 'phpunit@simplesamlphp.org' ); $mail->setText('text-text-text-text-text-text-text'); $mail->setData(['key-key-key-key-key-key-key' => 'value-value-value-value-value-value-value']); $result = $mail->generateBody($template); $this->assertRegexp('/(subject-){6}/', $result); $this->assertRegexp('/(text-){6}/', $result); $this->assertRegexp('/(key-){6}/', $result); $this->assertRegexp('/(value-){6}/', $result); } /** * All templates that should be tested in #testMailContents($template) * @return array */ public static function mailTemplates(): array { return [['mailtxt.twig'], ['mailhtml.twig']]; } /** * @return void */ public function testInvalidTransportConfiguration(): void { // preserve the original configuration $originalTestConfiguration = Configuration::getInstance()->toArray(); // load the configuration with an invalid mail.transport.method Configuration::loadFromArray(array_merge($originalTestConfiguration, [ 'mail.transport.method' => 'foobar' ]), '[ARRAY]', 'simplesaml'); $this->expectException(InvalidArgumentException::class); new Email('Test', 'phpunit@simplesamlphp.org', 'phpunit@simplesamlphp.org'); // reset the configuration Configuration::loadFromArray($originalTestConfiguration, '[ARRAY]', 'simplesaml'); } /** * @return void */ public function testInvalidSMTPConfiguration(): void { // setup a new email $email = new Email('Test', 'phpunit@simplesamlphp.org', 'phpunit@simplesamlphp.org'); // set the transport option to smtp but don't set any transport options (invalid state) // NOTE: this is the same method that the constructor calls, so this should be logically equivalent // to setting it via the configuration file. $this->expectException(InvalidArgumentException::class); $email->setTransportMethod('smtp'); } /** * Test setting configuration. * * @return void */ public function testGetDefaultMailAddress(): void { Configuration::loadFromArray([ 'technicalcontact_email' => 'gamaarna@example.org', ], '[ARRAY]', 'simplesaml'); $mail = new EMail('test', null, 'phpunit@simplesamlphp.org'); $this->assertEquals('gamaarna@example.org', $mail->getDefaultMailAddress()); Configuration::loadFromArray([ 'technicalcontact_email' => 'mailto:gamaarna@example.org', ], '[ARRAY]', 'simplesaml'); $mail = new EMail('test', null, 'phpunit@simplesamlphp.org'); $this->assertEquals('gamaarna@example.org', $mail->getDefaultMailAddress()); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Utils/CryptoTest.php0000644000000000000000000004140114042503475022732 0ustar rootrootroot = vfsStream::setup( self::ROOTDIRNAME, null, [ self::DEFAULTCERTDIR => [], ] ); $this->root_directory = vfsStream::url(self::ROOTDIRNAME); $this->certdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTCERTDIR; } /** * Test that aesDecrypt() works properly, being able to decrypt some previously known (and correct) * ciphertext. * * @covers \SimpleSAML\Utils\Crypto::aesDecrypt * @return void */ public function testAesDecrypt(): void { if (!extension_loaded('openssl')) { $this->expectException(Error\Exception::class); } $secret = 'SUPER_SECRET_SALT'; $m = new ReflectionMethod('\SimpleSAML\Utils\Crypto', 'aesDecryptInternal'); $m->setAccessible(true); $plaintext = 'SUPER_SECRET_TEXT'; $ciphertext = 'uR2Yu0r4itInKx91D/l9y/08L5CIQyev9nAr27fh3Sshous4' . 'vbXRRcMcjqHDOrquD+2vqLyw7ygnbA9jA9TpB4hLZocvAWcTN8tyO82hiSY='; $this->assertEquals($plaintext, $m->invokeArgs(null, [base64_decode($ciphertext), $secret])); } /** * Test that aesEncrypt() produces ciphertexts that aesDecrypt() can decrypt. * * @covers \SimpleSAML\Utils\Crypto::aesDecrypt * @covers \SimpleSAML\Utils\Crypto::aesEncrypt * @return void */ public function testAesEncrypt(): void { if (!extension_loaded('openssl')) { $this->expectException(Error\Exception::class); } $secret = 'SUPER_SECRET_SALT'; $e = new ReflectionMethod('\SimpleSAML\Utils\Crypto', 'aesEncryptInternal'); $d = new ReflectionMethod('\SimpleSAML\Utils\Crypto', 'aesDecryptInternal'); $e->setAccessible(true); $d->setAccessible(true); $original_plaintext = 'SUPER_SECRET_TEXT'; $ciphertext = $e->invokeArgs(null, [$original_plaintext, $secret]); $decrypted_plaintext = $d->invokeArgs(null, [$ciphertext, $secret]); $this->assertEquals($original_plaintext, $decrypted_plaintext); } /** * Test that the pem2der() and der2pem() methods work correctly. * * @covers \SimpleSAML\Utils\Crypto::der2pem * @covers \SimpleSAML\Utils\Crypto::pem2der * @return void */ public function testFormatConversion(): void { $pem = <<assertEquals(trim($pem), trim(Crypto::der2pem(Crypto::pem2der($pem)))); } /** * @covers \SimpleSAML\Utils\Crypto::pwHash * @deprecated To be removed for 2.0 * @return void */ public function testGoodPwHash(): void { $pw = "password"; $algorithm = "SHA1"; $res = Crypto::pwHash($pw, $algorithm); /* * echo -n "password" | sha1sum | awk -F " " '{print $1}' | xxd -r -p | base64 * W6ph5Mm5Pz8GgiULbPgzG37mj9g= */ $expected = "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g="; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::pwHash * @deprecated To be removed for 2.0 * @return void */ public function testGoodSaltedPwHash(): void { $pw = "password"; $algorithm = "SSHA1"; $salt = "salt"; $res = Crypto::pwHash($pw, $algorithm, $salt); /* * echo -n "password""salt" | sha1sum | awk -v salt=$(echo -n "salt" | xxd -u -p) * -F " " '{print $1 salt}' | xxd -r -p | base64 yI6cZwQadOA1e+/f+T+H3eCQQhRzYWx0 */ $expected = "{SSHA}yI6cZwQadOA1e+/f+T+H3eCQQhRzYWx0"; $this->assertEquals($expected, $res); } /** * @deprecated To be removed for 2.0 * * @covers \SimpleSAML\Utils\Crypto::pwHash * @return void */ public function testBadHashAlgorithm(): void { $this->expectException(\SimpleSAML\Error\Exception::class); $pw = "password"; $algorithm = "wtf"; Crypto::pwHash($pw, $algorithm); } /** * @covers \SimpleSAML\Utils\Crypto::pwValid * @return void */ public function testGoodPwValid(): void { $pw = "password"; $hash = Crypto::pwHash($pw); $res = Crypto::pwValid($hash, $pw); $this->assertTrue($res); } /** * @covers \SimpleSAML\Utils\Crypto::pwValid * @return void */ public function testBadPwInvalid(): void { $pw = "password"; $pw2 = "password2"; $hash = Crypto::pwHash($pw); $res = Crypto::pwValid($hash, $pw2); $this->assertFalse($res); } /** * Check that hash cannot be used to authenticate ith. */ public function testHashAsPwInvalid(): void { $pw = "password"; $hash = Crypto::pwHash($pw); $this->expectException(Error\Exception::class); $res = Crypto::pwValid($hash, $hash); } /** * @covers \SimpleSAML\Utils\Crypto::pwValid * @deprecated To be removed for 2.0 * @return void */ public function testGoodPwValidOld() { $pw = "password"; $algorithm = "SHA1"; $hash = Crypto::pwHash($pw, $algorithm); $res = Crypto::pwValid($hash, $pw); $this->assertTrue($res); } /** * @covers \SimpleSAML\Utils\Crypto::pwValid * @deprecated To be removed for 2.0 * @return void */ public function testGoodSaltedPwValid() { $pw = "password"; $algorithm = "SSHA1"; $salt = "salt"; $hash = Crypto::pwHash($pw, $algorithm, $salt); $res = Crypto::pwValid($hash, $pw); $this->assertTrue($res); } /** * @deprecated To be removed for 2.0 * * @covers \SimpleSAML\Utils\Crypto::pwValid * @return void */ public function testBadHashAlgorithmValid() { $this->expectException(\SimpleSAML\Error\Exception::class); $algorithm = "wtf"; $hash = "{" . $algorithm . "}B64STRING"; Crypto::pwValid($hash, $algorithm); } /** * @covers \SimpleSAML\Utils\Crypto::secureCompare * @return void */ public function testSecureCompareEqual(): void { $res = Crypto::secureCompare("string", "string"); $this->assertTrue($res); } /** * @covers \SimpleSAML\Utils\Crypto::secureCompare * @return void */ public function testSecureCompareNotEqual(): void { $res = Crypto::secureCompare("string1", "string2"); $this->assertFalse($res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyRequiredMetadataMissing(): void { $this->expectException(Error\Exception::class); $config = new Configuration([], 'test'); $required = true; Crypto::loadPrivateKey($config, $required); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyNotRequiredMetadataMissing(): void { $config = new Configuration([], 'test'); $required = false; $res = Crypto::loadPrivateKey($config, $required); $this->assertNull($res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyMissingFile(): void { $this->expectException(Error\Exception::class); $config = new Configuration(['privatekey' => 'nonexistant'], 'test'); Crypto::loadPrivateKey($config, false, '', true); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyBasic(): void { $filename = $this->certdir . DIRECTORY_SEPARATOR . 'key'; $data = 'data'; $config = new Configuration(['privatekey' => $filename], 'test'); $full_path = true; file_put_contents($filename, $data); $res = Crypto::loadPrivateKey($config, false, '', $full_path); $expected = ['PEM' => $data, 'password' => null]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyPassword(): void { $password = 'password'; $filename = $this->certdir . DIRECTORY_SEPARATOR . 'key'; $data = 'data'; $config = new Configuration( [ 'privatekey' => $filename, 'privatekey_pass' => $password, ], 'test' ); $full_path = true; file_put_contents($filename, $data); $res = Crypto::loadPrivateKey($config, false, '', $full_path); $expected = ['PEM' => $data, 'password' => $password]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPrivateKey * @return void */ public function testLoadPrivateKeyPrefix(): void { $prefix = 'prefix'; $password = 'password'; $filename = $this->certdir . DIRECTORY_SEPARATOR . 'key'; $data = 'data'; $config = new Configuration( [ $prefix . 'privatekey' => $filename, $prefix . 'privatekey_pass' => $password, ], 'test' ); $full_path = true; file_put_contents($filename, $data); $res = Crypto::loadPrivateKey($config, false, $prefix, $full_path); $expected = ['PEM' => $data, 'password' => $password]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyRequiredMetadataMissing(): void { $this->expectException(Error\Exception::class); $config = new Configuration([], 'test'); $required = true; Crypto::loadPublicKey($config, $required); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyNotRequiredMetadataMissing(): void { $config = new Configuration([], 'test'); $required = false; $res = Crypto::loadPublicKey($config, $required); $this->assertNull($res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyFingerprintBasicString() { $fingerprint = 'fingerprint'; $config = new Configuration(['certFingerprint' => $fingerprint], 'test'); $res = Crypto::loadPublicKey($config); $expected = ['certFingerprint' => [$fingerprint]]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyFingerprintBasicArray() { $fingerprint1 = 'fingerprint1'; $fingerprint2 = 'fingerprint2'; $config = new Configuration( [ 'certFingerprint' => [ $fingerprint1, $fingerprint2 ], ], 'test' ); $res = Crypto::loadPublicKey($config); $expected = ['certFingerprint' => [$fingerprint1, $fingerprint2]]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyFingerprintLowercase() { $fingerprint = 'FINGERPRINT'; $config = new Configuration(['certFingerprint' => $fingerprint], 'test'); $res = Crypto::loadPublicKey($config); $expected = ['certFingerprint' => [strtolower($fingerprint)]]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyFingerprintRemoveColons() { $fingerprint = 'f:i:n:g:e:r:p:r:i:n:t'; $config = new Configuration(['certFingerprint' => $fingerprint], 'test'); $res = Crypto::loadPublicKey($config); $expected = ['certFingerprint' => [str_replace(':', '', $fingerprint)]]; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyNotX509Certificate(): void { $config = new Configuration( [ 'keys' => [ [ 'X509Certificate' => '', 'type' => 'NotX509Certificate', 'signing' => true ], ], ], 'test' ); $res = Crypto::loadPublicKey($config); $this->assertNull($res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyNotSigning(): void { $config = new Configuration( [ 'keys' => [ [ 'X509Certificate' => '', 'type' => 'X509Certificate', 'signing' => false ], ], ], 'test' ); $res = Crypto::loadPublicKey($config); $this->assertNull($res); } /** * @covers \SimpleSAML\Utils\Crypto::loadPublicKey * @return void */ public function testLoadPublicKeyBasic(): void { $x509certificate = 'x509certificate'; $config = new Configuration( [ 'keys' => [ [ 'X509Certificate' => $x509certificate, 'type' => 'X509Certificate', 'signing' => true ], ], ], 'test' ); /** @var array $pubkey */ $pubkey = Crypto::loadPublicKey($config); $res = $pubkey['certData']; $expected = $x509certificate; $this->assertEquals($expected, $res); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Locale/0000755000000000000000000000000014042503475020200 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Locale/LanguageTest.php0000644000000000000000000001262714042503475023304 0ustar rootrootassertEquals('en', $l->getDefaultLanguage()); // test defaults coming from configuration $c = Configuration::loadFromArray([ 'language.available' => ['en', 'es', 'nn'], 'language.default' => 'es', ]); $l = new Language($c); $this->assertEquals('es', $l->getDefaultLanguage()); } /** * Test SimpleSAML\Locale\Language::getLanguageCookie(). * @return void */ public function testGetLanguageCookie(): void { // test it works when no cookie is set Configuration::loadFromArray([], '', 'simplesaml'); $this->assertNull(Language::getLanguageCookie()); // test that it works fine with defaults Configuration::loadFromArray([], '', 'simplesaml'); $_COOKIE['language'] = 'en'; $this->assertEquals('en', Language::getLanguageCookie()); // test that it works with non-defaults Configuration::loadFromArray([ 'language.available' => ['en', 'es', 'nn'], 'language.cookie.name' => 'xyz' ], '', 'simplesaml'); $_COOKIE['xyz'] = 'Es'; // test values are converted to lowercase too $this->assertEquals('es', Language::getLanguageCookie()); } /** * Test SimpleSAML\Locale\Language::getLanguageList(). * @return void */ public function testGetLanguageListNoConfig(): void { // test default $c = Configuration::loadFromArray([], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('en'); $this->assertEquals(['en' => true], $l->getLanguageList()); } /** * Test SimpleSAML\Locale\Language::getLanguageList(). * @return void */ public function testGetLanguageListCorrectConfig(): void { // test langs from from language_names $c = Configuration::loadFromArray([ 'language.available' => ['en', 'nn', 'es'], ], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('es'); $this->assertEquals([ 'en' => false, 'es' => true, 'nn' => false, ], $l->getLanguageList()); } /** * Test SimpleSAML\Locale\Language::getLanguageList(). * @return void */ public function testGetLanguageListIncorrectConfig(): void { // test non-existent langs $c = Configuration::loadFromArray([ 'language.available' => ['foo', 'bar'], ], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('foo'); $this->assertEquals(['en' => true], $l->getLanguageList()); } /** * Test SimpleSAML\Locale\Language::getLanguageParameterName(). * @return void */ public function testGetLanguageParameterName(): void { // test for default configuration $c = Configuration::loadFromArray([], '', 'simplesaml'); $l = new Language($c); $this->assertEquals('language', $l->getLanguageParameterName()); // test for valid configuration $c = Configuration::loadFromArray([ 'language.parameter.name' => 'xyz' ], '', 'simplesaml'); $l = new Language($c); $this->assertEquals('xyz', $l->getLanguageParameterName()); } /** * Test SimpleSAML\Locale\Language::isLanguageRTL(). * @return void */ public function testIsLanguageRTL(): void { // test defaults $c = Configuration::loadFromArray([], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('en'); $this->assertFalse($l->isLanguageRTL()); // test non-defaults, non-RTL $c = Configuration::loadFromArray([ 'language.rtl' => ['foo', 'bar'], ], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('en'); $this->assertFalse($l->isLanguageRTL()); // test non-defaults, RTL $c = Configuration::loadFromArray([ 'language.available' => ['en', 'nn', 'es'], 'language.rtl' => ['nn', 'es'], ], '', 'simplesaml'); $l = new Language($c); $l->setLanguage('es'); $this->assertTrue($l->isLanguageRTL()); } /** * Test SimpleSAML\Locale\Language::setLanguage(). * @return void */ public function testSetLanguage(): void { // test with valid configuration, no cookies set $c = Configuration::loadFromArray([ 'language.available' => ['en', 'nn', 'es'], 'language.parameter.name' => 'xyz', 'language.parameter.setcookie' => false, ], '', 'simplesaml'); $_GET['xyz'] = 'Es'; // test also that lang code is transformed to lower caps $l = new Language($c); $this->assertEquals('es', $l->getLanguage()); // test with valid configuration, no cookies, language set unavailable $_GET['xyz'] = 'unavailable'; $l = new Language($c); $this->assertEquals('en', $l->getLanguage()); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Locale/LocalizationTest.php0000644000000000000000000000300314042503475024175 0ustar rootroot false] ); $l = new Localization($c); $this->assertTrue($l->isI18NBackendDefault()); $this->assertEquals(Localization::DEFAULT_DOMAIN, 'messages'); } /** * Test SimpleSAML\Locale\Localization::activateDomain(). * @return void */ public function testAddDomain(): void { $c = Configuration::loadFromArray( ['usenewui' => true] ); $l = new Localization($c); $newDomain = 'test'; $newDomainLocaleDir = $l->getLocaleDir(); $l->addDomain($newDomainLocaleDir, $newDomain); $registeredDomains = $l->getRegisteredDomains(); $this->assertArrayHasKey($newDomain, $registeredDomains); $this->assertEquals($registeredDomains[$newDomain], $newDomainLocaleDir); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Locale/TranslateTest.php0000644000000000000000000000207014042503475023505 0ustar rootrootassertEquals($testString, $t->noop($testString)); } /** * Test SimpleSAML\Locale\Translate::t(). * @return void */ public function testTFallback() { $c = \SimpleSAML\Configuration::loadFromArray([]); $t = new Translate($c); $testString = 'Blablabla'; // $fallbackdefault = true $result = 'not translated (' . $testString . ')'; $this->assertEquals($result, $t->t($testString)); // $fallbackdefault = false, should be a noop $this->assertEquals($testString, $t->t($testString, [], false)); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Store/0000755000000000000000000000000014042503475020075 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Store/RedisTest.php0000644000000000000000000001544614042503475022526 0ustar rootrootconfig = []; $this->mocked_redis = $this->getMockBuilder(Client::class) ->setMethods(['get', 'set', 'setex', 'del', 'disconnect']) ->disableOriginalConstructor() ->getMock(); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $this->mocked_redis->method('get') ->will($this->returnCallback([$this, 'getMocked'])); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $this->mocked_redis->method('set') ->will($this->returnCallback([$this, 'setMocked'])); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $this->mocked_redis->method('setex') ->will($this->returnCallback([$this, 'setexMocked'])); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $this->mocked_redis->method('del') ->will($this->returnCallback([$this, 'delMocked'])); $nop = /** @return void */ function () { return; }; /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $this->mocked_redis->method('disconnect') ->will($this->returnCallback($nop)); /** @var \Predis\Client $this->mocked_redis */ $this->redis = new Store\Redis($this->mocked_redis); } /** * @param string $key * @return string|null */ public function getMocked(string $key): ?string { return array_key_exists($key, $this->config) ? $this->config[$key] : null; } /** * @param string $key * @param mixed $value * @return void */ public function setMocked(string $key, $value): void { $this->config[$key] = $value; } /** * @param string $key * @param int $expire * @param mixed $value * @return void */ public function setexMocked(string $key, int $expire, $value): void { // Testing expiring data is more trouble than it's worth for now $this->setMocked($key, $value); } /** * @param string $key * @return void */ public function delMocked(string $key): void { unset($this->config[$key]); } /** * @covers \SimpleSAML\Store::getInstance * @covers \SimpleSAML\Store\Redis::__construct * @test * @return void */ public function testRedisInstance(): void { $config = Configuration::loadFromArray([ 'store.type' => 'redis', 'store.redis.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); /** @var \SimpleSAML\Store\Redis $store */ $store = Store::getInstance(); $this->assertInstanceOf(Store\Redis::class, $store); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * @covers \SimpleSAML\Store::getInstance * @covers \SimpleSAML\Store\Redis::__construct * @test * @return void */ public function testRedisInstanceWithPassword(): void { $config = Configuration::loadFromArray([ 'store.type' => 'redis', 'store.redis.prefix' => 'phpunit_', 'store.redis.password' => 'password', ], '[ARRAY]', 'simplesaml'); /** @var \SimpleSAML\Store\Redis $store */ $store = Store::getInstance(); $this->assertInstanceOf(Store\Redis::class, $store); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * @covers \SimpleSAML\Store\Redis::get * @covers \SimpleSAML\Store\Redis::set * @test * @return void */ public function testInsertData(): void { $value = 'TEST'; $this->redis->set('test', 'key', $value); $res = $this->redis->get('test', 'key'); $expected = $value; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Store\Redis::get * @covers \SimpleSAML\Store\Redis::set * @test * @return void */ public function testInsertExpiringData(): void { $value = 'TEST'; $this->redis->set('test', 'key', $value, $expire = 80808080); $res = $this->redis->get('test', 'key'); $expected = $value; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Store\Redis::get * @test * @return void */ public function testGetEmptyData(): void { $res = $this->redis->get('test', 'key'); $this->assertNull($res); } /** * @covers \SimpleSAML\Store\Redis::get * @covers \SimpleSAML\Store\Redis::set * @test * @return void */ public function testOverwriteData(): void { $value1 = 'TEST1'; $value2 = 'TEST2'; $this->redis->set('test', 'key', $value1); $this->redis->set('test', 'key', $value2); $res = $this->redis->get('test', 'key'); $expected = $value2; $this->assertEquals($expected, $res); } /** * @covers \SimpleSAML\Store\Redis::get * @covers \SimpleSAML\Store\Redis::set * @covers \SimpleSAML\Store\Redis::delete * @test * @return void */ public function testDeleteData(): void { $this->redis->set('test', 'key', 'TEST'); $this->redis->delete('test', 'key'); $res = $this->redis->get('test', 'key'); $this->assertNull($res); } /** * @param \SimpleSAML\Configuration|\SimpleSAML\Store $service * @param class-string $className * @return void */ protected function clearInstance($service, string $className): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, null); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Store/SQLTest.php0000644000000000000000000001266514042503475022117 0ustar rootroot * @package simplesamlphp/simplesamlphp */ class SQLTest extends TestCase { /** * @return void */ protected function setUp() { Configuration::loadFromArray([ 'store.type' => 'sql', 'store.sql.dsn' => 'sqlite::memory:', 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); } /** * @covers \SimpleSAML\Store::getInstance * @covers \SimpleSAML\Store\SQL::__construct * @test * @return void */ public function SQLInstance(): void { $store = Store::getInstance(); $this->assertInstanceOf('SimpleSAML\Store\SQL', $store); } /** * @covers \SimpleSAML\Store\SQL::initTableVersionTable * @covers \SimpleSAML\Store\SQL::initKVTable * @test * @return void */ public function kvstoreTableVersion(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $version = $store->getTableVersion('kvstore'); $this->assertEquals(2, $version); } /** * @covers \SimpleSAML\Store\SQL::getTableVersion * @test * @return void */ public function newTableVersion(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $version = $store->getTableVersion('test'); $this->assertEquals(0, $version); } /** * @covers \SimpleSAML\Store\SQL::setTableVersion * @covers \SimpleSAML\Store\SQL::insertOrUpdate * @test * @return void */ public function testSetTableVersion(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $store->setTableVersion('kvstore', 2); $version = $store->getTableVersion('kvstore'); $this->assertEquals(2, $version); } /** * @covers \SimpleSAML\Store\SQL::get * @test * @return void */ public function testGetEmptyData(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $value = $store->get('test', 'foo'); $this->assertNull($value); } /** * @covers \SimpleSAML\Store\SQL::get * @covers \SimpleSAML\Store\SQL::set * @covers \SimpleSAML\Store\SQL::insertOrUpdate * @test * @return void */ public function testInsertData(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $store->set('test', 'foo', 'bar'); $value = $store->get('test', 'foo'); $this->assertEquals('bar', $value); } /** * @covers \SimpleSAML\Store\SQL::get * @covers \SimpleSAML\Store\SQL::set * @covers \SimpleSAML\Store\SQL::insertOrUpdate * @test * @return void */ public function testOverwriteData(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $store->set('test', 'foo', 'bar'); $store->set('test', 'foo', 'baz'); $value = $store->get('test', 'foo'); $this->assertEquals('baz', $value); } /** * @covers \SimpleSAML\Store\SQL::get * @covers \SimpleSAML\Store\SQL::set * @covers \SimpleSAML\Store\SQL::insertOrUpdate * @covers \SimpleSAML\Store\SQL::delete * @test * @return void */ public function testDeleteData(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $store->set('test', 'foo', 'bar'); $store->delete('test', 'foo'); $value = $store->get('test', 'foo'); $this->assertNull($value); } /** * @covers \SimpleSAML\Store\SQL::get * @covers \SimpleSAML\Store\SQL::set * @covers \SimpleSAML\Store\SQL::insertOrUpdate * @covers \SimpleSAML\Store\SQL::delete * @test * @return void */ public function testVeryLongKey(): void { /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $key = str_repeat('x', 100); $store->set('test', $key, 'bar'); $store->delete('test', $key); $value = $store->get('test', $key); $this->assertNull($value); } /** * @return void */ protected function tearDown() { $config = Configuration::getInstance(); /** @var \SimpleSAML\Store\SQL $store */ $store = Store::getInstance(); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * @param \SimpleSAML\Configuration|\SimpleSAML\Store $service * @param class-string $className * @return void */ protected function clearInstance($service, string $className): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, null); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/StoreTest.php0000644000000000000000000000756714042503475021465 0ustar rootroot * @package simplesamlphp/simplesamlphp */ class StoreTest extends TestCase { /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function defaultStore(): void { Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); /** @var false $store */ $store = Store::getInstance(); $this->assertFalse($store); } /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function phpSessionStore(): void { Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); /** @var false $store */ $store = Store::getInstance(); $this->assertFalse($store); } /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function memcacheStore(): void { Configuration::loadFromArray([ 'store.type' => 'memcache', ], '[ARRAY]', 'simplesaml'); $store = Store::getInstance(); $this->assertInstanceOf(Store\Memcache::class, $store); } /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function sqlStore(): void { Configuration::loadFromArray([ 'store.type' => 'sql', 'store.sql.dsn' => 'sqlite::memory:', 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); $store = Store::getInstance(); $this->assertInstanceOf(Store\SQL::class, $store); } /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function pathStore(): void { Configuration::loadFromArray([ 'store.type' => '\SimpleSAML\Store\SQL', 'store.sql.dsn' => 'sqlite::memory:', 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); $store = Store::getInstance(); $this->assertInstanceOf(Store\SQL::class, $store); } /** * @covers \SimpleSAML\Store::getInstance * @test * @return void */ public function notFoundStoreException(): void { $this->expectException(CriticalConfigurationError::class); Configuration::loadFromArray([ 'store.type' => '\Test\SimpleSAML\Store\Dummy', 'store.sql.dsn' => 'sqlite::memory:', 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); Store::getInstance(); } /** * @return void */ protected function tearDown() { $config = Configuration::getInstance(); /** @var \SimpleSAML\Store $store */ $store = Store::getInstance(); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * @param \SimpleSAML\Configuration|\SimpleSAML\Store $service * @param class-string $className * @return void */ protected function clearInstance($service, string $className): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, null); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/SessionHandlerPHPTest.php0000644000000000000000000001335414042503475023651 0ustar rootroot 'SimpleSAMLSessionID', 'session.cookie.lifetime' => 100, 'session.cookie.path' => '/ourPath', 'session.cookie.domain' => 'example.com', 'session.cookie.secure' => true, 'session.phpsession.cookiename' => 'SimpleSAML', ]; /** @var array */ protected $original; /** * @return void */ protected function setUp() { $this->original = $_SERVER; $_SERVER['HTTP_HOST'] = 'example.com'; $_SERVER['SERVER_NAME'] = 'example.com'; $_SERVER['HTTPS'] = 'on'; $_SERVER['SERVER_PORT'] = 443; $_SERVER['REQUEST_URI'] = '/simplesaml'; } /** * @return void */ protected function tearDown() { $_SERVER = $this->original; } /** * @covers SimpleSAML\SessionHandlerPHP::__construct() * @covers SimpleSAML\SessionHandlerPHP::getSessionHandler() * @covers SimpleSAML\SessionHandler::getSessionHandler() * @return void */ public function testGetSessionHandler(): void { Configuration::loadFromArray($this->sessionConfig, '[ARRAY]', 'simplesaml'); $sh = SessionHandlerPHP::getSessionHandler(); $this->assertInstanceOf(SessionHandlerPHP::class, $sh); } /** * @covers SimpleSAML\SessionHandlerPHP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookie(): void { Configuration::loadFromArray($this->sessionConfig, '[ARRAY]', 'simplesaml'); $sh = SessionHandlerPHP::getSessionHandler(); $sh->setCookie('SimpleSAMLSessionID', '1'); $headers = xdebug_get_headers(); $this->assertContains('SimpleSAML=1;', $headers[0]); $this->assertRegExp('/\b[Ee]xpires=([Mm]on|[Tt]ue|[Ww]ed|[Tt]hu|[Ff]ri|[Ss]at|[Ss]un)/', $headers[0]); $this->assertRegExp('/\b[Pp]ath=\/ourPath(;|$)/', $headers[0]); $this->assertRegExp('/\b[Dd]omain=example.com(;|$)/', $headers[0]); $this->assertRegExp('/\b[Ss]ecure(;|$)/', $headers[0]); $this->assertRegExp('/\b[Hh]ttp[Oo]nly(;|$)/', $headers[0]); } /** * @covers SimpleSAML\SessionHandlerPHP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookieSameSiteNone(): void { Configuration::loadFromArray( array_merge($this->sessionConfig, ['session.cookie.samesite' => 'None']), '[ARRAY]', 'simplesaml' ); $sh = SessionHandlerPHP::getSessionHandler(); $sh->setCookie('SimpleSAMLSessionID', 'None'); $headers = xdebug_get_headers(); $this->assertContains('SimpleSAML=None;', $headers[0]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=None(;|$)/', $headers[0]); } /** * @covers SimpleSAML\SessionHandlerPHP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookieSameSiteLax(): void { Configuration::loadFromArray( array_merge($this->sessionConfig, ['session.cookie.samesite' => 'Lax']), '[ARRAY]', 'simplesaml' ); $sh = SessionHandlerPHP::getSessionHandler(); $sh->setCookie('SimpleSAMLSessionID', 'Lax'); $headers = xdebug_get_headers(); $this->assertContains('SimpleSAML=Lax;', $headers[0]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=Lax(;|$)/', $headers[0]); } /** * @covers SimpleSAML\SessionHandlerPHP::setCookie() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testSetCookieSameSiteStrict(): void { Configuration::loadFromArray( array_merge($this->sessionConfig, ['session.cookie.samesite' => 'Strict']), '[ARRAY]', 'simplesaml' ); $sh = SessionHandlerPHP::getSessionHandler(); $sh->setCookie('SimpleSAMLSessionID', 'Strict'); $headers = xdebug_get_headers(); $this->assertContains('SimpleSAML=Strict;', $headers[0]); $this->assertRegExp('/\b[Ss]ame[Ss]ite=Strict(;|$)/', $headers[0]); } /** * @covers SimpleSAML\SessionHandlerPHP::restorePrevious() * @runInSeparateProcess * @requires extension xdebug * @return void */ public function testRestorePrevious(): void { session_name('PHPSESSID'); $sid = session_id(); session_start(); Configuration::loadFromArray($this->sessionConfig, '[ARRAY]', 'simplesaml'); /** @var SessionHandlerPHP $sh */ $sh = SessionHandlerPHP::getSessionHandler(); $sh->setCookie('SimpleSAMLSessionID', 'Restore'); $sh->restorePrevious(); $headers = xdebug_get_headers(); $this->assertContains('PHPSESSID=' . $sid, $headers[0]); $this->assertContains('SimpleSAML=Restore;', $headers[1]); $this->assertContains('PHPSESSID=' . $sid, $headers[2]); $this->assertEquals($headers[0], $headers[2]); } /** * @covers SimpleSAML\SessionHandlerPHP::newSessionId() * @return void */ public function testNewSessionId(): void { Configuration::loadFromArray($this->sessionConfig, '[ARRAY]', 'simplesaml'); $sh = SessionHandlerPHP::getSessionHandler(); $sid = $sh->newSessionId(); $this->assertStringMatchesFormat('%s', $sid); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Auth/0000755000000000000000000000000014042503475017702 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Auth/SourceTest.php0000644000000000000000000000177614042503475022526 0ustar rootrootgetMethod('parseAuthSource'); $method->setAccessible(true); // test direct instantiation of the auth source object $authSource = $method->invokeArgs(null, ['test', [TestAuthSource::class]]); $this->assertInstanceOf(TestAuthSource::class, $authSource); // test instantiation via an auth source factory $authSource = $method->invokeArgs(null, ['test', [TestAuthSourceFactory::class]]); $this->assertInstanceOf(TestAuthSource::class, $authSource); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Auth/TimeLimitedTokenTest.php0000644000000000000000000000470414042503475024467 0ustar rootroot 'random'], '[ARRAY]', 'simplesaml'); $token = new TimeLimitedToken(); $this->assertFalse($token->validate('malformed')); $this->assertFalse($token->validate('mal-for-med')); $this->assertFalse($token->validate('mal-formed')); } /** * Basic test to see if validation works for valid tokens. * @return void */ public function testValidToken() { \SimpleSAML\Configuration::loadFromArray(['secretsalt' => 'random'], '[ARRAY]', 'simplesaml'); $token = new TimeLimitedToken(); $t = $token->generate(); $this->assertTrue($token->validate($t)); } /** * Test that token validation takes the verification data into account. * @return void */ public function testValidTokenWithData() { \SimpleSAML\Configuration::loadFromArray(['secretsalt' => 'random'], '[ARRAY]', 'simplesaml'); $tokenWithData = new TimeLimitedToken(); $tokenWithData->addVerificationData('some more random data'); $t = $tokenWithData->generate(); $this->assertTrue($tokenWithData->validate($t)); $tokenWithoutData = new TimeLimitedToken(); $this->assertFalse($tokenWithoutData->validate($t)); } /** * Test that expired tokens are rejected. * @return void */ public function testExpiredToken() { \SimpleSAML\Configuration::loadFromArray(['secretsalt' => 'random'], '[ARRAY]', 'simplesaml'); $token = new TimeLimitedToken(); $this->assertFalse($token->validate('7-c0803e76fff1df0ceb222dee80aa1d73f35d84dd')); } /** * Test that a token that has been manipulated to extend its validity is rejected. * @return void */ public function testManipulatedToken() { \SimpleSAML\Configuration::loadFromArray(['secretsalt' => 'random'], '[ARRAY]', 'simplesaml'); $token = new TimeLimitedToken(1); $t = $token->generate(); list($offset, $hash) = explode('-', $t); sleep(1); $this->assertFalse($token->validate(dechex(hexdec($offset) + 1).'-'.$hash)); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Auth/StateTest.php0000644000000000000000000000477514042503475022350 0ustar rootroot [], 'Expire' => 1234, 'LogoutState' => 'logoutState', 'AuthInstant' => 123456, 'RememberMe' => true, 'saml:sp:NameID' => 'nameID', ]; // check just mandatory parameters $state = $mandatory; $expected = $mandatory; $this->assertEquals( $expected, Auth\State::getPersistentAuthData($state), 'Mandatory state attributes did not survive as expected' . print_r($expected, true) ); // check missing mandatory parameters unset($state['LogoutState']); unset($state['RememberMe']); $expected = $state; $this->assertEquals( $expected, Auth\State::getPersistentAuthData($state), 'Some error occurred with missing mandatory parameters' ); // check additional non-persistent parameters $additional = [ 'additional1' => 1, 'additional2' => 2, ]; $state = array_merge($mandatory, $additional); $expected = $mandatory; $this->assertEquals( $expected, Auth\State::getPersistentAuthData($state), 'Additional parameters survived' ); // check additional persistent parameters $additional['PersistentAuthData'] = ['additional1']; $state = array_merge($mandatory, $additional); $expected = $state; unset($expected['additional2']); unset($expected['PersistentAuthData']); $this->assertEquals( $expected, Auth\State::getPersistentAuthData($state), 'Some error occurred with additional, persistent parameters' ); // check only additional persistent parameters $state = $additional; $expected = $state; unset($expected['additional2']); unset($expected['PersistentAuthData']); $this->assertEquals( $expected, Auth\State::getPersistentAuthData($state), 'Some error occurred with additional, persistent parameters, and no mandatory ones' ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Auth/SimpleTest.php0000644000000000000000000000641014042503475022505 0ustar rootrootgetMethod('getProcessedURL'); $method->setAccessible(true); // fool the routines to make them believe we are running in a web server $_SERVER['REQUEST_URI'] = '/'; // test merging configuration option with passed URL Configuration::loadFromArray([ 'application' => [ 'baseURL' => 'https://example.org' ] ], '[ARRAY]', 'simplesaml'); $s = new Auth\Simple(''); $this->assertEquals('https://example.org/', $method->invokeArgs($s, [null])); // test a full URL passed as parameter $this->assertEquals( 'https://example.org/foo/bar?a=b#fragment', $method->invokeArgs( $s, ['http://some.overridden.host/foo/bar?a=b#fragment'] ) ); // test a full, current URL with no parameters $_SERVER['REQUEST_URI'] = '/foo/bar?a=b#fragment'; $this->assertEquals('https://example.org/foo/bar?a=b#fragment', $method->invokeArgs($s, [null])); // test ports are overridden by configuration $_SERVER['SERVER_PORT'] = '1234'; $this->assertEquals('https://example.org/foo/bar?a=b#fragment', $method->invokeArgs($s, [null])); // test config option with ending with / and port Configuration::loadFromArray([ 'application' => [ 'baseURL' => 'http://example.org:8080/' ] ], '[ARRAY]', 'simplesaml'); $s = new Auth\Simple(''); $this->assertEquals('http://example.org:8080/foo/bar?a=b#fragment', $method->invokeArgs($s, [null])); // test again with a relative URL as a parameter $this->assertEquals( 'http://example.org:8080/something?foo=bar#something', $method->invokeArgs($s, ['/something?foo=bar#something']) ); // now test with no configuration $_SERVER['SERVER_NAME'] = 'example.org'; Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); $s = new Auth\Simple(''); $this->assertEquals('http://example.org:1234/foo/bar?a=b#fragment', $method->invokeArgs($s, [null])); // no configuration, https and port $_SERVER['HTTPS'] = 'on'; $this->assertEquals('https://example.org:1234/foo/bar?a=b#fragment', $method->invokeArgs($s, [null])); // no configuration and a relative URL as a parameter $this->assertEquals( 'https://example.org:1234/something?foo=bar#something', $method->invokeArgs($s, ['/something?foo=bar#something']) ); // finally, no configuration and full URL as a parameter $this->assertEquals( 'https://example.org/one/two/three?foo=bar#fragment', $method->invokeArgs($s, ['https://example.org/one/two/three?foo=bar#fragment']) ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/0000755000000000000000000000000014042503475020521 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/0000755000000000000000000000000014042503475023256 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/0000755000000000000000000000000014042503475024640 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/0000755000000000000000000000000014042503475027647 5ustar rootroot././@LongLink0000644000000000000000000000017100000000000011602 Lustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/expiredInSrc1InSrc2.serializedsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/expiredInS0000644000000000000000000000065414042503475031651 0ustar rootroota:5:{s:8:"entityid";s:19:"expiredInSrc1InSrc2";s:6:"expire";i:3659688740;s:4:"name";a:1:{s:2:"en";s:35:"expiredInSrc1InSrc2 SP from source2";}s:12:"metadata-set";s:16:"saml20-sp-remote";s:24:"AssertionConsumerService";a:1:{i:0;a:4:{s:7:"Binding";s:46:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";s:8:"Location";s:65:"https://expiredInSrc1InSrc2.example.org/Shibboleth.sso/SAML2/POST";s:5:"index";i:1;s:9:"isDefault";b:1;}}} ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/entityInBoth.serializedsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/entityInBo0000644000000000000000000000057414042503475031664 0ustar rootroota:4:{s:8:"entityid";s:12:"entityInBoth";s:4:"name";a:1:{s:2:"en";s:28:"entityInBoth SP from source2";}s:12:"metadata-set";s:16:"saml20-sp-remote";s:24:"AssertionConsumerService";a:1:{i:0;a:4:{s:7:"Binding";s:46:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";s:8:"Location";s:58:"https://entityInBoth.example.org/Shibboleth.sso/SAML2/POST";s:5:"index";i:1;s:9:"isDefault";b:1;}}}././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/entityB.serializedsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source2/saml20-sp-remote/entityB.se0000644000000000000000000000055414042503475031622 0ustar rootroota:4:{s:8:"entityid";s:7:"entityB";s:4:"name";a:1:{s:2:"en";s:23:"entityB SP from source2";}s:12:"metadata-set";s:16:"saml20-sp-remote";s:24:"AssertionConsumerService";a:1:{i:0;a:4:{s:7:"Binding";s:46:"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";s:8:"Location";s:53:"https://entityB.example.org/Shibboleth.sso/SAML2/POST";s:5:"index";i:1;s:9:"isDefault";b:1;}}}simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source1/0000755000000000000000000000000014042503475024637 5ustar rootrootsimplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/test-metadata/source1/saml20-sp-remote.php0000644000000000000000000000342514042503475030363 0ustar rootroot 'entityA', 'name' => [ 'en' => 'entityA SP from source1', ], 'metadata-set' => 'saml20-sp-remote', 'AssertionConsumerService' => [ 0 => [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://entityA.example.org/Shibboleth.sso/SAML2/POST', 'index' => 1, 'isDefault' => true, ], ] ]; $metadata['entityInBoth'] = [ 'entityid' => 'entityInBoth', 'name' => [ 'en' => 'entityInBoth SP from source1', ], 'metadata-set' => 'saml20-sp-remote', 'AssertionConsumerService' => [ 0 => [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://entityInBoth.example.org/Shibboleth.sso/SAML2/POST', 'index' => 1, 'isDefault' => true, ], ] ]; $metadata['expiredInSrc1InSrc2'] = [ 'entityid' => 'expiredInSrc1InSrc2', // This entity is expired in src1 but unexpired in src2 'expire' => 1, 'name' => [ 'en' => 'expiredInSrc1InSrc2 SP from source1', ], 'metadata-set' => 'saml20-sp-remote', 'AssertionConsumerService' => [ 0 => [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://expiredInSrc1InSrc2.example.org/Shibboleth.sso/SAML2/POST', 'index' => 1, 'isDefault' => true, ], ] ]; simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php0000644000000000000000000002747714042503475024156 0ustar rootroot $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'urn:oid:0.9.2342.19200300.100.1.3', 'urn:oid:2.5.4.3', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); /** @psalm-var \DOMNodeList $acs */ $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); $this->assertEquals(1, $acs->length); /** @psalm-var \DOMElement $first */ $first = $acs->item(0); $attributes = $first->getElementsByTagName("RequestedAttribute"); $this->assertEquals(4, $attributes->length); for ($c = 0; $c < $attributes->length; $c++) { /** @psalm-var \DOMElement $curAttribute */ $curAttribute = $attributes->item($c); $this->assertTrue($curAttribute->hasAttribute("Name")); $this->assertFalse($curAttribute->hasAttribute("FriendlyName")); $this->assertEquals($metadata['attributes'][$c], $curAttribute->getAttribute("Name")); } // test SP20 array parsing, no friendly name $set = 'saml20-sp-remote'; $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'eduPersonOrgDN' => 'urn:oid:0.9.2342.19200300.100.1.3', 'cn' => 'urn:oid:2.5.4.3', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); /** @var \DOMNodeList $acs */ $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); $this->assertEquals(1, $acs->length); /** @psalm-var \DOMElement $first */ $first = $acs->item(0); $attributes = $first->getElementsByTagName("RequestedAttribute"); $this->assertEquals(4, $attributes->length); $keys = array_keys($metadata['attributes']); for ($c = 0; $c < $attributes->length; $c++) { /** @psalm-var \DOMElement $curAttribute */ $curAttribute = $attributes->item($c); $this->assertTrue($curAttribute->hasAttribute("Name")); $this->assertTrue($curAttribute->hasAttribute("FriendlyName")); $this->assertEquals($metadata['attributes'][$keys[$c]], $curAttribute->getAttribute("Name")); $this->assertEquals($keys[$c], $curAttribute->getAttribute("FriendlyName")); } // test SP13 array parsing, no friendly name $set = 'shib13-sp-remote'; $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'urn:oid:0.9.2342.19200300.100.1.3', 'urn:oid:2.5.4.3', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); /** @var \DOMNodeList $acs */ $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); $this->assertEquals(1, $acs->length); /** @psalm-var \DOMElement $first */ $first = $acs->item(0); $attributes = $first->getElementsByTagName("RequestedAttribute"); $this->assertEquals(4, $attributes->length); for ($c = 0; $c < $attributes->length; $c++) { /** @psalm-var \DOMElement $curAttribute */ $curAttribute = $attributes->item($c); $this->assertTrue($curAttribute->hasAttribute("Name")); $this->assertFalse($curAttribute->hasAttribute("FriendlyName")); $this->assertEquals($metadata['attributes'][$c], $curAttribute->getAttribute("Name")); } // test SP20 array parsing, no friendly name $set = 'shib13-sp-remote'; $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'eduPersonOrgDN' => 'urn:oid:0.9.2342.19200300.100.1.3', 'cn' => 'urn:oid:2.5.4.3', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); /** @var \DOMNodeList $acs */ $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); $this->assertEquals(1, $acs->length); /** @psalm-var \DOMElement $first */ $first = $acs->item(0); $attributes = $first->getElementsByTagName("RequestedAttribute"); $this->assertEquals(4, $attributes->length); $keys = array_keys($metadata['attributes']); for ($c = 0; $c < $attributes->length; $c++) { /** @psalm-var \DOMElement $curAttribute */ $curAttribute = $attributes->item($c); $this->assertTrue($curAttribute->hasAttribute("Name")); $this->assertTrue($curAttribute->hasAttribute("FriendlyName")); $this->assertEquals($metadata['attributes'][$keys[$c]], $curAttribute->getAttribute("Name")); $this->assertEquals($keys[$c], $curAttribute->getAttribute("FriendlyName")); } } /** * Test the working of the isDefault config option * @return void */ public function testAttributeConsumingServiceDefault(): void { $entityId = 'https://entity.example.com/id'; $set = 'saml20-sp-remote'; $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); /** @var \DOMNodeList $acs */ $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); /** @psalm-var \DOMElement $acs1 */ $acs1 = $acs->item(0); $this->assertFalse($acs1->hasAttribute("isDefault")); $metadata['attributes.isDefault'] = true; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); /** @var \DOMElement $acs1 */ $acs1 = $acs->item(0); $this->assertTrue($acs1->hasAttribute("isDefault")); $this->assertEquals("true", $acs1->getAttribute("isDefault")); $metadata['attributes.isDefault'] = false; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); /** @var \DOMElement $acs1 */ $acs1 = $acs->item(0); $this->assertTrue($acs1->hasAttribute("isDefault")); $this->assertEquals("false", $acs1->getAttribute("isDefault")); } /** * Test the index option is used correctly. * @return void */ public function testAttributeConsumingServiceIndex(): void { $entityId = 'https://entity.example.com/id'; $set = 'saml20-sp-remote'; $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test SP'], 'metadata-set' => $set, 'attributes' => [ 'eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); /** @var \DOMElement $acs1 */ $acs1 = $acs->item(0); $this->assertTrue($acs1->hasAttribute("index")); $this->assertEquals("0", $acs1->getAttribute("index")); $metadata['attributes.index'] = 15; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $spDesc = $samlBuilder->getEntityDescriptor(); $acs = $spDesc->getElementsByTagName("AttributeConsumingService"); /** @var \DOMElement $acs1 */ $acs1 = $acs->item(0); $this->assertTrue($acs1->hasAttribute("index")); $this->assertEquals("15", $acs1->getAttribute("index")); } /** * Test the required protocolSupportEnumeration in AttributeAuthorityDescriptor * @return void */ public function testProtocolSupportEnumeration(): void { $entityId = 'https://entity.example.com/id'; $set = 'attributeauthority-remote'; // without protocolSupportEnumeration fallback to default: urn:oasis:names:tc:SAML:2.0:protocol $metadata = [ 'entityid' => $entityId, 'name' => ['en' => 'Test AA'], 'metadata-set' => $set, 'AttributeService' => [ 0 => [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP', 'Location' => 'https://entity.example.com:8443/idp/profile/SAML2/SOAP/AttributeQuery', ], ], ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $entityDescriptorXml = $samlBuilder->getEntityDescriptorText(); $this->assertRegExp( '//', $entityDescriptorXml ); // explicit protocols $metadata['protocols'] = [ 0 => 'urn:oasis:names:tc:SAML:1.1:protocol', 1 => 'urn:oasis:names:tc:SAML:2.0:protocol', ]; $samlBuilder = new SAMLBuilder($entityId); $samlBuilder->addMetadata($set, $metadata); $entityDescriptorXml = $samlBuilder->getEntityDescriptorText(); $protocols = implode(' ', $metadata['protocols']); $this->assertRegExp( '//', $entityDescriptorXml ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/SAMLParserTest.php0000644000000000000000000004346114042503475024013 0ustar rootroot 'https://incommon.org', ]; $document = DOMDocumentFactory::fromString( << XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); // RegistrationInfo is accessible in the SP or IDP metadata accessors /** @var array $metadata */ $metadata = $entities['theEntityID']->getMetadata20SP(); $this->assertEquals($expected, $metadata['RegistrationInfo']); } /** * Test RegistrationInfo is inherited correctly from parent EntitiesDescriptor. * According to the spec overriding RegistrationInfo is not valid. We ignore attempts to override * @return void */ public function testRegistrationInfoInheritance(): void { $expected = [ 'registrationAuthority' => 'https://incommon.org', ]; $document = DOMDocumentFactory::fromString( << XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); $this->assertArrayHasKey('subEntityId', $entities); // RegistrationInfo is accessible in the SP or IDP metadata accessors /** @var array $metadata */ $metadata = $entities['theEntityID']->getMetadata20SP(); $this->assertEquals($expected, $metadata['RegistrationInfo']); /** @var array $metadata */ $metadata = $entities['subEntityId']->getMetadata20SP(); $this->assertEquals($expected, $metadata['RegistrationInfo']); /** @var array $metadata */ $metadata = $entities['subEntityIdOverride']->getMetadata20SP(); $this->assertEquals($expected, $metadata['RegistrationInfo']); } /** * Test AttributeConsumingService is parsed * @return void */ public function testAttributeConsumingServiceParsing(): void { $document = DOMDocumentFactory::fromString( << Example service Dit is een voorbeeld voor de unittest. XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); /** @var array $metadata */ $metadata = $entities['theEntityID']->getMetadata20SP(); $this->assertEquals("Example service", $metadata['name']['en']); $this->assertEquals("Dit is een voorbeeld voor de unittest.", $metadata['description']['nl']); $expected_a = [ "urn:mace:dir:attribute-def:eduPersonPrincipalName", "urn:mace:dir:attribute-def:mail", "urn:mace:dir:attribute-def:displayName" ]; $expected_r = ["urn:mace:dir:attribute-def:eduPersonPrincipalName"]; $this->assertEquals($expected_a, $metadata['attributes']); $this->assertEquals($expected_r, $metadata['attributes.required']); } /** * @return \DOMDocument */ public function makeTestDocument(): \DOMDocument { $doc = new DOMDocument(); $doc->loadXML( << XML ); /** @psalm-var \DOMElement $entities_root */ $entities_root = $doc->getElementsByTagName('EntitiesDescriptor')->item(0); $signer = new Signer([]); $signer->loadPrivateKey($this->good_private_key_file, null, true); $signer->loadCertificate($this->good_certificate_file, true); $signer->sign($entities_root, $entities_root); return $doc; } /** * @param string $algo * @param string $expected_fingerprint * @return void */ private function validateFingerprint(string $algo, string $expected_fingerprint) { $doc = $this->makeTestDocument(); $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($doc->documentElement); foreach ($entities as $entity) { $this->assertTrue( $entity->validateFingerprint($expected_fingerprint, $algo) ); } } /** * @return void */ public function testValidateFingerprintSHA1() { $this->validateFingerprint( XMLSecurityDSig::SHA1, 'A7:FB:75:22:57:88:A1:B0:D0:29:0A:4B:D1:EA:0C:01:F8:98:44:A0' ); } /** * @return void */ public function testValidateFingerprintSHA256() { $this->validateFingerprint( XMLSecurityDSig::SHA256, '3E:04:6B:2C:13:B5:02:FB:FC:93:66:EE:6C:A3:D1:BB:B8:9E:D8:38:03' . ':96:C5:C0:EC:95:D5:C9:F6:C1:D5:FC' ); } /** * @return void */ public function testValidateFingerprintSHA384() { $this->validateFingerprint( XMLSecurityDSig::SHA384, '38:87:CC:59:54:CF:ED:FC:71:B6:21:F3:8A:52:76:EF:30:C8:8C:A0:38' . ':48:77:87:58:14:A0:B3:55:EF:48:9C:B4:B3:44:1F:B7:BB:FC:28:65' . ':6E:93:83:52:C2:8E:A6' ); } /** * @return void */ public function testValidateFingerprintSHA512() { $this->validateFingerprint( XMLSecurityDSig::SHA512, '72:6C:51:01:A1:E9:76:D8:61:C4:B2:4F:AC:0B:64:7D:0D:4E:B7:DC:B3' . ':4A:92:23:51:A6:DC:A5:A1:9A:A5:DD:43:F5:05:6A:B7:7D:83:1F:B6:' . 'CC:68:54:54:54:37:1B:EC:E1:22:5A:48:C6:BC:67:4B:A6:78:EE:E0:C6:8C:59' ); } /** * @return void */ public function testValidateFingerprintUnknownAlgorithmThrows() { $doc = $this->makeTestDocument(); $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsElement($doc->documentElement); foreach ($entities as $entity) { try { $entity->validateFingerprint('unused', 'invalid_algorithm'); } catch (\UnexpectedValueException $e) { $this->assertEquals( 'Unsupported hashing function invalid_algorithm. Known options: [' . 'http://www.w3.org/2000/09/xmldsig#sha1, ' . 'http://www.w3.org/2001/04/xmlenc#sha256, ' . 'http://www.w3.org/2001/04/xmldsig-more#sha384, ' . 'http://www.w3.org/2001/04/xmlenc#sha512]', $e->getMessage() ); } } } /** * Test RoleDescriptor/Extensions is parsed * @return void */ public function testRoleDescriptorExtensions(): void { $expected = [ 'scope' => [ 'example.org', 'example.net', ], 'UIInfo' => [ 'DisplayName' => ['en' => 'DisplayName', 'af' => 'VertoonNaam'], 'Description' => ['en' => 'Description',], 'InformationURL' => ['en' => 'https://localhost/information',], 'PrivacyStatementURL' => ['en' => 'https://localhost/privacypolicy',], 'Logo' => [ [ 'url' => 'https://localhost/logo', 'height' => 16, 'width' => 17, ], [ 'url' => 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'height' => 2, 'width' => 1, ], ], ], 'DiscoHints' => [ 'IPHint' => ['127.0.0.1', '127.0.0.2',], 'DomainHint' => ['example.net', 'example.org',], 'GeolocationHint' => ['geo:-29.00000,24.00000;u=830000',], ], 'name' => ['en' => 'DisplayName', 'af' => 'VertoonNaam'], ]; $document = DOMDocumentFactory::fromString( << example.org example.net DisplayName VertoonNaam Description https://localhost/privacypolicy https://localhost/information https://localhost/logo data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw== 127.0.0.1 127.0.0.2 example.net example.org geo:-29.00000,24.00000;u=830000 XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); // Various MDUI elements are accessible /** @var array $metadata */ $metadata = $entities['theEntityID']->getMetadata20IdP(); $this->assertEquals( $expected['scope'], $metadata['scope'], 'shibmd:Scope elements not reflected in parsed metadata' ); $this->assertEquals( $expected['UIInfo'], $metadata['UIInfo'], 'mdui:UIInfo elements not reflected in parsed metadata' ); $this->assertEquals( $expected['DiscoHints'], $metadata['DiscoHints'], 'mdui:DiscoHints elements not reflected in parsed metadata' ); $this->assertEquals($expected['name'], $metadata['name']); } /** * Test entity category hidden from discovery is parsed * @return void */ public function testHiddenFromDiscovery(): void { $document = DOMDocumentFactory::fromString( << https://example.org/some-category http://refeds.org/category/hide-from-discovery XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); $metadata = $entities['theEntityID']->getMetadata20IdP(); $this->assertArrayHasKey('hide.from.discovery', $metadata); $this->assertTrue($metadata['hide.from.discovery']); } /** * Test entity category hidden from discovery is not returned when not present * @return void */ public function testHiddenFromDiscoveryNotHidden(): void { $document = DOMDocumentFactory::fromString( << https://safire.ac.za/safire/policy/mrps/v20190207.html https://example.org/some-category XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); $metadata = $entities['theEntityID']->getMetadata20IdP(); $this->assertArrayNotHasKey('hide.from.discovery', $metadata); } /** * Test entity category hidden from discovery is not returned when no mace dir entity categories present * @return void */ public function testHiddenFromDiscoveryNotHiddenNoMaceDirEC(): void { $document = DOMDocumentFactory::fromString( << https://example.org/some-supported-category XML ); $entities = SAMLParser::parseDescriptorsElement($document->documentElement); $this->assertArrayHasKey('theEntityID', $entities); $metadata = $entities['theEntityID']->getMetadata20IdP(); $this->assertArrayNotHasKey('hide.from.discovery', $metadata); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/MetaDataStorageSourceTest.php0000644000000000000000000001160714042503475026265 0ustar rootrootexpectException(Exception::class); MetaDataStorageSource::getSource(["type" => "xml", "foo" => "baa"]); } /** * Test \SimpleSAML\Metadata\MetaDataStorageSourceTest::getConfig invalid static XML source * @return void */ public function testInvalidStaticXMLSource(): void { $this->expectException(Exception::class); $strTestXML = " "; MetaDataStorageSource::getSource(["type" => "xml", "xml" => $strTestXML]); } /** * Test \SimpleSAML\Metadata\MetaDataStorageSourceTest::getConfig XML static XML source * @return void */ public function testStaticXMLSource(): void { $testEntityId = "https://saml.idp/entityid"; $strTestXML = self::generateIdpMetadataXml($testEntityId); // The primary test here is that - in contrast to the others above - this loads without error // As a secondary thing, check that the entity ID from the static source provided can be extracted $source = MetaDataStorageSource::getSource(["type" => "xml", "xml" => $strTestXML]); $idpSet = $source->getMetadataSet("saml20-idp-remote"); $this->assertArrayHasKey( $testEntityId, $idpSet, "Did not extract expected IdP entity ID from static XML source" ); // Finally verify that a different entity ID does not get loaded $this->assertCount(1, $idpSet, "Unexpectedly got metadata for an alternate entity than that defined"); } /** * Test loading multiple entities * @return void */ public function testLoadEntitiesStaticXMLSource(): void { $c = [ 'key' => 'value' ]; Configuration::loadFromArray($c, '', 'simplesaml'); $entityId1 = "https://example.com"; $xml1 = self::generateIdpMetadataXml($entityId1); $entityId2 = "https://saml.idp/entity"; $xml2 = self::generateIdpMetadataXml($entityId2); $strTestXML = " $xml1 $xml2 "; $source = MetaDataStorageSource::getSource(["type" => "xml", "xml" => $strTestXML]); // search that is a single entity $entities = $source->getMetaDataForEntities([$entityId2], "saml20-idp-remote"); $this->assertCount(1, $entities, 'Only 1 entity loaded'); $this->assertArrayHasKey($entityId2, $entities); // search for multiple entities $entities = $source->getMetaDataForEntities([$entityId1, 'no-such-entity', $entityId2], "saml20-idp-remote"); $this->assertCount(2, $entities, 'Only 2 of the entities are found'); $this->assertArrayHasKey($entityId1, $entities); $this->assertArrayHasKey($entityId2, $entities); // search for non-existant entities $entities = $source->getMetaDataForEntities(['no-such-entity'], "saml20-idp-remote"); $this->assertCount(0, $entities, 'no matches expected'); } /** * @param string $entityId * @return string */ public static function generateIdpMetadataXml(string $entityId): string { return " urn:oasis:names:tc:SAML:2.0:nameid-format:persistent "; } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/Metadata/MetaDataStorageHandlerTest.php0000644000000000000000000000330414042503475026375 0ustar rootroot [ ['type' => 'flatfile', 'directory' => __DIR__ . '/test-metadata/source1'], ['type' => 'serialize', 'directory' => __DIR__ . '/test-metadata/source2'], ], ]; Configuration::loadFromArray($c, '', 'simplesaml'); $handler = MetaDataStorageHandler::getMetadataHandler(); $entities = $handler->getMetaDataForEntities([ 'entityA', 'entityB', 'nosuchEntity', 'entityInBoth', 'expiredInSrc1InSrc2' ], 'saml20-sp-remote'); $this->assertCount(4, $entities); $this->assertEquals('entityA SP from source1', $entities['entityA']['name']['en']); $this->assertEquals('entityB SP from source2', $entities['entityB']['name']['en']); $this->assertEquals( 'entityInBoth SP from source1', $entities['entityInBoth']['name']['en'], "Entity is in both sources, but should get loaded from the first" ); $this->assertEquals( 'expiredInSrc1InSrc2 SP from source2', $entities['expiredInSrc1InSrc2']['name']['en'], "Entity is in both sources, expired in src1 and available from src2" ); } } simplesamlphp-1.19.1/tests/lib/SimpleSAML/ModuleTest.php0000644000000000000000000000725714042503475021612 0ustar rootrootassertTrue(Module::isModuleEnabled('core')); } /** * Test for SimpleSAML\Module::getModuleDir(). * @return void */ public function testGetModuleDir(): void { // test for the most basic functionality $this->assertEquals( dirname(dirname(dirname(dirname(__FILE__)))) . '/modules/module', Module::getModuleDir('module') ); } /** * Test for SimpleSAML\Module::getModuleURL(). * @return void */ public function testGetModuleURL(): void { Configuration::loadFromArray([ 'baseurlpath' => 'https://example.com/simplesaml/' ], '', 'simplesaml'); $this->assertEquals( 'https://example.com/simplesaml/module.php/module/script.php', Module::getModuleURL('module/script.php') ); $this->assertEquals( 'https://example.com/simplesaml/module.php/module/script.php?param1=value1¶m2=value2', Module::getModuleURL('module/script.php', [ 'param1' => 'value1', 'param2' => 'value2', ]) ); } /** * Test for SimpleSAML\Module::getModules(). * @return void */ public function testGetModules(): void { $this->assertGreaterThan(0, count(Module::getModules())); } /** * Test for SimpleSAML\Module::resolveClass(). It will make sure that an exception is thrown if we are not asking * for a class inside a module (that is, there is no colon separating the name of the module and the name of the * class). * @return void */ public function testResolveClassNoModule(): void { $this->expectException(Exception::class); Module::resolveClass('nomodule', ''); } /** * Test for SimpleSAML\Module::resolveClass(). It will make sure that an exception is thrown if the class we are * asking for cannot be found. * @return void */ public function testResolveClassNotFound(): void { $this->expectException(Exception::class); Module::resolveClass('core:Missing', ''); } /** * Test for SimpleSAML\Module::resolveClass(). It will make sure that an exception is thrown if the class we are * asking for can be resolved, but does not extend a given class. * @return void */ public function testResolveClassNotSubclass(): void { $this->expectException(Exception::class); Module::resolveClass('core:PHP', 'Auth_Process', '\Exception'); } /** * Test for SimpleSAML\Module::resolveClass(). It covers all the valid use cases. * @return void */ public function testResolveClass(): void { // most basic test $this->assertEquals('SimpleSAML\Module\cron\Cron', Module::resolveClass('cron:Cron', '')); // test for the $type parameter correctly translated into a path $this->assertEquals( 'SimpleSAML\Module\core\Auth\Process\PHP', Module::resolveClass('core:PHP', 'Auth\Process') ); // test for valid subclasses $this->assertEquals('SimpleSAML\Module\core\Auth\Process\PHP', Module::resolveClass( 'core:PHP', 'Auth\Process', '\SimpleSAML\Auth\ProcessingFilter' )); } } simplesamlphp-1.19.1/tests/SigningTestCase.php0000644000000000000000000002331514042503475020074 0ustar rootroot $this->ca_private_key, self::CA_CERTIFICATE => $this->ca_certificate, self::GOOD_PRIVATE_KEY => $this->good_private_key, self::GOOD_CERTIFICATE => $this->good_certificate, ]; } /** * @return void */ public function setUp() { $this->root = vfsStream::setup( self::ROOTDIRNAME, null, [ self::DEFAULTCERTDIR => $this->getCertDirContent(), ] ); $this->root_directory = vfsStream::url(self::ROOTDIRNAME); $this->certdir = $this->root_directory . DIRECTORY_SEPARATOR . self::DEFAULTCERTDIR; $this->ca_private_key_file = $this->certdir . DIRECTORY_SEPARATOR . self::CA_PRIVATE_KEY; $this->ca_certificate_file = $this->certdir . DIRECTORY_SEPARATOR . self::CA_CERTIFICATE; $this->good_private_key_file = $this->certdir . DIRECTORY_SEPARATOR . self::GOOD_PRIVATE_KEY; $this->good_certificate_file = $this->certdir . DIRECTORY_SEPARATOR . self::GOOD_CERTIFICATE; $this->config = Configuration::loadFromArray([ 'certdir' => $this->certdir, ], '[ARRAY]', 'simplesaml'); } /** * @return void */ public function tearDown() { $this->clearInstance($this->config, Configuration::class, []); } /** * @param \SimpleSAML\Configuration $service * @param class-string $className * @param mixed|null $value * @return void */ protected function clearInstance(Configuration $service, string $className, $value = null): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, $value); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/Utils/0000755000000000000000000000000014042503475015425 5ustar rootrootsimplesamlphp-1.19.1/tests/Utils/TestAuthSourceFactory.php0000644000000000000000000000053314042503475022411 0ustar rootrootbackupGlobals(); } } /** * @return void */ protected function setUp() { self::clearState(); } /** * @return void */ public static function tearDownAfterClass() { self::clearState(); } /** * Clear any SSP global state to reduce spill over between tests. * @return void */ public static function clearState(): void { self::$stateClearer->clearGlobals(); self::$stateClearer->clearSSPState(); } } simplesamlphp-1.19.1/tests/Utils/ReduceSpillOverTest.php0000644000000000000000000000237014042503475022047 0ustar rootroot 'b'], '[ARRAY]', 'simplesaml'); $this->assertEquals('b', Configuration::getInstance()->getString('a')); putenv('SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__); } /** * Confirm global state removed prior to next test * @return void * @throws \SimpleSAML\Error\ConfigurationError */ public function testStateRemoved(): void { $this->assertArrayNotHasKey('QUERY_STRING', $_SERVER); /** @var false $env */ $env = getenv('SIMPLESAMLPHP_CONFIG_DIR'); $this->assertFalse($env); try { Configuration::getInstance(); $this->fail('Expected config configured in other tests to no longer be valid'); } catch (Error\ConfigurationError $error) { // Expected error } } } simplesamlphp-1.19.1/tests/Utils/StateClearer.php0000644000000000000000000000467614042503475020531 0ustar rootrootbackups['$_COOKIE'] = $_COOKIE; $this->backups['$_ENV'] = $_ENV; $this->backups['$_FILES'] = $_FILES; $this->backups['$_GET'] = $_GET; $this->backups['$_POST'] = $_POST; $this->backups['$_SERVER'] = $_SERVER; /** @psalm-var array|null $_SESSION */ $this->backups['$_SESSION'] = isset($_SESSION) ? $_SESSION : []; $this->backups['$_REQUEST'] = $_REQUEST; } /** * Clear any global state. * @return void */ public function clearGlobals(): void { if (!empty($this->backups)) { $_COOKIE = $this->backups['$_COOKIE']; $_ENV = $this->backups['$_ENV']; $_FILES = $this->backups['$_FILES']; $_GET = $this->backups['$_GET']; $_POST = $this->backups['$_POST']; $_SERVER = $this->backups['$_SERVER']; $_SESSION = $this->backups['$_SESSION']; $_REQUEST = $this->backups['$_REQUEST']; } else { //TODO: what should this behavior be? } } /** * Clear any SSP specific state, such as SSP enviormental variables or cached internals. * @return void */ public function clearSSPState(): void { foreach ($this->clearableState as $var) { $var::clearInternalState(); } foreach ($this->vars_to_unset as $var) { putenv($var); } } } simplesamlphp-1.19.1/tests/Utils/SpTester.php0000644000000000000000000000262614042503475017715 0ustar rootrootgetMethod('startSSO2'); $method->setAccessible(true); $method->invoke($this, $idpMetadata, $state); } /** * override the method that sends the request to avoid sending anything * @return void */ public function sendSAML2AuthnRequest(array &$state, Binding $binding, AuthnRequest $ar) { // Exit test. Continuing would mean running into a assert(FALSE) throw new ExitTestException( [ 'state' => $state, 'binding' => $binding, 'ar' => $ar, ] ); } } simplesamlphp-1.19.1/tests/Utils/TestAuthSource.php0000644000000000000000000000034214042503475021057 0ustar rootroottestResult = $testResult; } /** * @return array */ public function getTestResult(): array { return $this->testResult; } } simplesamlphp-1.19.1/tests/www/0000755000000000000000000000000014042503475015151 5ustar rootrootsimplesamlphp-1.19.1/tests/www/IndexTest.php0000644000000000000000000000624414042503475017577 0ustar rootroot * @package SimpleSAMLphp */ class IndexTest extends TestCase { /** * @var \SimpleSAML\Test\BuiltInServer */ protected $server; /** * @var string */ protected $server_addr; /** * @var int */ protected $server_pid; /** * @var string */ protected $shared_file; /** * The setup method that is run before any tests in this class. * @return void */ protected function setup() { $this->server = new BuiltInServer('configLoader'); $this->server_addr = $this->server->start(); $this->server_pid = $this->server->getPid(); $this->shared_file = sys_get_temp_dir() . '/' . $this->server_pid . '.lock'; @unlink($this->shared_file); // remove it if it exists } /** * @param array $config * @return void */ protected function updateConfig(array $config) { @unlink($this->shared_file); $config = "shared_file, $config); } /** * A simple test to make sure the index.php file redirects appropriately to the right URL. * @return void */ public function testRedirection() { // test most basic redirection $this->updateConfig([ 'baseurlpath' => 'http://example.org/simplesaml/' ]); $resp = $this->server->get('/index.php', [], [ CURLOPT_FOLLOWLOCATION => 0, ]); $this->assertEquals('302', $resp['code']); $this->assertEquals( 'http://example.org/simplesaml/module.php/core/frontpage_welcome.php', $resp['headers']['Location'] ); // test non-default path and https $this->updateConfig([ 'baseurlpath' => 'https://example.org/' ]); $resp = $this->server->get('/index.php', [], [ CURLOPT_FOLLOWLOCATION => 0, ]); $this->assertEquals('302', $resp['code']); $this->assertEquals( 'https://example.org/module.php/core/frontpage_welcome.php', $resp['headers']['Location'] ); // test URL guessing $this->updateConfig([ 'baseurlpath' => '/simplesaml/' ]); $resp = $this->server->get('/index.php', [], [ CURLOPT_FOLLOWLOCATION => 0, ]); $this->assertEquals('302', $resp['code']); $this->assertEquals( 'http://' . $this->server_addr . '/simplesaml/module.php/core/frontpage_welcome.php', $resp['headers']['Location'] ); } /** * The tear down method that is executed after all tests in this class. * @return void */ protected function tearDown() { unlink($this->shared_file); $this->server->stop(); } } simplesamlphp-1.19.1/tests/modules/0000755000000000000000000000000014042503475015775 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/multiauth/0000755000000000000000000000000014042503475020011 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/multiauth/lib/0000755000000000000000000000000014042503475020557 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/multiauth/lib/Auth/0000755000000000000000000000000014042503475021460 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/multiauth/lib/Auth/Source/0000755000000000000000000000000014042503475022720 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/multiauth/lib/Auth/Source/MultiAuthTest.php0000644000000000000000000001577614042503475026225 0ustar rootrootconfig = Configuration::loadFromArray( ['module.enable' => ['multiauth' => true]], '[ARRAY]', 'simplesaml' ); Configuration::setPreLoadedConfig($this->config, 'config.php'); $this->sourceConfig = Configuration::loadFromArray(array( 'example-multi' => array( 'multiauth:MultiAuth', /* * The available authentication sources. * They must be defined in this authsources.php file. */ 'sources' => array( 'example-saml' => array( 'text' => array( 'en' => 'Log in using a SAML SP', 'es' => 'Entrar usando un SP SAML', ), 'css-class' => 'SAML', ), 'example-admin' => array( 'text' => array( 'en' => 'Log in using the admin password', 'es' => 'Entrar usando la contraseña de administrador', ), ), ), 'preselect' => 'example-saml', ), 'example-saml' => array( 'saml:SP', 'entityId' => 'my-entity-id', 'idp' => 'my-idp', ), 'example-admin' => array( 'core:AdminPassword', ), )); Configuration::setPreLoadedConfig($this->sourceConfig, 'authsources.php'); } /** * @return void */ public function testSourcesMustBePresent(): void { $this->expectException(Exception::class); $this->expectExceptionMessage('The required "sources" config option was not found'); $sourceConfig = Configuration::loadFromArray(array( 'example-multi' => array( 'multiauth:MultiAuth', ), )); Configuration::setPreLoadedConfig($sourceConfig, 'authsources.php'); new MultiAuth(['AuthId' => 'example-multi'], $sourceConfig->getArray('example-multi')); } /** * @return void */ public function testPreselectMustBeValid(): void { $this->expectException(Exception::class); $this->expectExceptionMessage('The optional "preselect" config option must be present in "sources"'); $sourceConfig = Configuration::loadFromArray(array( 'example-multi' => array( 'multiauth:MultiAuth', /* * The available authentication sources. * They must be defined in this authsources.php file. */ 'sources' => array( 'example-saml' => array( 'text' => array( 'en' => 'Log in using a SAML SP', 'es' => 'Entrar usando un SP SAML', ), 'css-class' => 'SAML', ), 'example-admin' => array( 'text' => array( 'en' => 'Log in using the admin password', 'es' => 'Entrar usando la contraseña de administrador', ), ), ), 'preselect' => 'other', ), 'example-saml' => array( 'saml:SP', 'entityId' => 'my-entity-id', 'idp' => 'my-idp', ), 'example-admin' => array( 'core:AdminPassword', ), )); Configuration::setPreLoadedConfig($sourceConfig, 'authsources.php'); new MultiAuth(['AuthId' => 'example-multi'], $sourceConfig->getArray('example-multi')); } /** * @return void */ public function testPreselectIsOptional(): void { $sourceConfig = Configuration::loadFromArray(array( 'example-multi' => array( 'multiauth:MultiAuth', /* * The available authentication sources. * They must be defined in this authsources.php file. */ 'sources' => array( 'example-saml' => array( 'text' => array( 'en' => 'Log in using a SAML SP', 'es' => 'Entrar usando un SP SAML', ), 'css-class' => 'SAML', ), 'example-admin' => array( 'text' => array( 'en' => 'Log in using the admin password', 'es' => 'Entrar usando la contraseña de administrador', ), ), ), ), 'example-saml' => array( 'saml:SP', 'entityId' => 'my-entity-id', 'idp' => 'my-idp', ), 'example-admin' => array( 'core:AdminPassword', ), )); Configuration::setPreLoadedConfig($sourceConfig, 'authsources.php'); $state = []; $source = new MultiAuth(['AuthId' => 'example-multi'], $sourceConfig->getArray('example-multi')); try { $source->authenticate($state); } catch (Error $e) { } catch (Exception $e) { } $this->assertArrayNotHasKey('multiauth:preselect', $state); } /** * @return void */ public function testPreselectCanBeConfigured(): void { $state = []; $source = new MultiAuth(['AuthId' => 'example-multi'], $this->sourceConfig->getArray('example-multi')); try { $source->authenticate($state); } catch (Exception $e) { } $this->assertArrayHasKey('multiauth:preselect', $state); $this->assertEquals('example-saml', $state['multiauth:preselect']); } /** * @return void */ public function testStatePreselectHasPriority(): void { $state = ['multiauth:preselect' => 'example-admin']; $source = new MultiAuth(['AuthId' => 'example-multi'], $this->sourceConfig->getArray('example-multi')); try { $source->authenticate($state); } catch (Exception $e) { } $this->assertArrayHasKey('multiauth:preselect', $state); $this->assertEquals('example-admin', $state['multiauth:preselect']); } } simplesamlphp-1.19.1/tests/modules/saml/0000755000000000000000000000000014042503475016731 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/0000755000000000000000000000000014042503475017477 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/IdP/0000755000000000000000000000000014042503475020153 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/IdP/SQLNameIDTest.php0000644000000000000000000000643514042503475023211 0ustar rootroot * @package SimpleSAMLphp */ class SQLNameIDTest extends TestCase { /** * @param array $config * @return void */ private function addGetDelete(array $config = []): void { SQLNameID::add('idp', 'sp', 'user', 'value', $config); $this->assertEquals('value', SQLNameID::get('idp', 'sp', 'user', $config)); SQLNameID::delete('idp', 'sp', 'user', $config); $this->assertNull(SQLNameID::get('idp', 'sp', 'user', $config)); } /** * Test Store. * @test * @return void */ public function testSQLStore(): void { Configuration::loadFromArray([ 'store.type' => 'sql', 'store.sql.dsn' => 'sqlite::memory:', 'store.sql.prefix' => 'phpunit_', ], '[ARRAY]', 'simplesaml'); $this->addGetDelete(); $config = Configuration::getInstance(); /** @var \SimpleSAML\Store $store */ $store = Store::getInstance(); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * Test incompatible Store. * @test * @return void */ public function testIncompatibleStore(): void { Configuration::loadFromArray([ 'store.type' => 'memcache', ], '[ARRAY]', 'simplesaml'); $store = Store::getInstance(); $this->assertInstanceOf(Store\Memcache::class, $store); $this->expectException(Error\Exception::class); $this->addGetDelete(); $config = Configuration::getInstance(); /** @var \SimpleSAML\Store $store */ $store = Store::getInstance(); $this->clearInstance($config, Configuration::class); $this->clearInstance($store, Store::class); } /** * Test Database. * @test * @return void */ public function testDatabase(): void { $config = [ 'database.dsn' => 'sqlite::memory:', 'database.username' => null, 'database.password' => null, 'database.prefix' => 'phpunit_', 'database.persistent' => true, 'database.slaves' => [ [ 'dsn' => 'sqlite::memory:', 'username' => null, 'password' => null, ], ], ]; $this->addGetDelete($config); } /** * @param \SimpleSAML\Configuration|\SimpleSAML\Store $service * @param class-string $className * @return void */ protected function clearInstance($service, string $className): void { $reflectedClass = new ReflectionClass($className); $reflectedInstance = $reflectedClass->getProperty('instance'); $reflectedInstance->setAccessible(true); $reflectedInstance->setValue($service, null); $reflectedInstance->setAccessible(false); } } simplesamlphp-1.19.1/tests/modules/saml/lib/IdP/SAML2Test.php0000644000000000000000000002274314042503475022352 0ustar rootroot ['\SimpleSAML\Module\saml\IdP\SAML2', 'sendResponse'], '\SimpleSAML\Auth\State.exceptionFunc' => ['\SimpleSAML\Module\saml\IdP\SAML2', 'handleAuthError'], 'saml:RelayState' => null, 'saml:RequestId' => null, 'saml:IDPList' => [], 'saml:ProxyCount' => null, 'saml:RequesterID' => null, 'ForceAuthn' => false, 'isPassive' => false, 'saml:ConsumerURL' => 'SP-specific', 'saml:Binding' => 'SP-specific', 'saml:NameIDFormat' => null, 'saml:AllowCreate' => true, 'saml:Extensions' => null, 'saml:RequestedAuthnContext' => null ]; /** * Test that invoking the idp initiated endpoint with the minimum necessary parameters works. * @return void */ public function testIdPInitiatedLoginMinimumParams(): void { $state = $this->idpInitiatedHelper(['spentityid' => 'https://some-sp-entity-id']); $this->assertEquals('https://some-sp-entity-id', $state['SPMetadata']['entityid']); $this->assertStringStartsWith( 'http://idp.examlple.com/saml2/idp/SSOService.php?spentityid=https%3A%2F%2Fsome-sp-entity-id&cookie', $state['\SimpleSAML\Auth\State.restartURL'] ); unset($state['saml:AuthnRequestReceivedAt']); // timestamp can't be tested in equality assertion unset($state['SPMetadata']); // entityid asserted above unset($state['\SimpleSAML\Auth\State.restartURL']); // url contains a cookie time which varies by test $expectedState = $this->defaultExpectedAuthState; $expectedState['saml:ConsumerURL'] = 'https://example.com/Shibboleth.sso/SAML2/POST'; $expectedState['saml:Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'; $this->assertEquals($expectedState, $state); } /** * Test that invoking the idp initiated endpoint with the optional parameters works. * @return void */ public function testIdPInitiatedLoginOptionalParams(): void { $state = $this->idpInitiatedHelper([ 'spentityid' => 'https://some-sp-entity-id', 'RelayState' => 'http://relay', 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS', 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', ]); $this->assertEquals('https://some-sp-entity-id', $state['SPMetadata']['entityid']); //currently only spentityid and relay state are used in the restart url. $this->assertStringStartsWith( 'http://idp.examlple.com/saml2/idp/SSOService.php?' . 'spentityid=https%3A%2F%2Fsome-sp-entity-id&RelayState=http%3A%2F%2Frelay&cookieTime', $state['\SimpleSAML\Auth\State.restartURL'] ); unset($state['saml:AuthnRequestReceivedAt']); // timestamp can't be tested in equality assertion unset($state['SPMetadata']); // entityid asserted above unset($state['\SimpleSAML\Auth\State.restartURL']); // url contains a cookie time which varies by test $expectedState = $this->defaultExpectedAuthState; $expectedState['saml:ConsumerURL'] = 'https://example.com/Shibboleth.sso/SAML2/ECP'; $expectedState['saml:Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS'; $expectedState['saml:NameIDFormat'] = 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'; $expectedState['saml:RelayState'] = 'http://relay'; $this->assertEquals($expectedState, $state); } /** * Test that invoking the idp initiated endpoint using minimum shib params works * @return void */ public function testIdPInitShibCompatyMinimumParams(): void { //https://wiki.shibboleth.net/confluence/display/IDP30/UnsolicitedSSOConfiguration // Shib uses the param providerId instead of spentityid $state = $this->idpInitiatedHelper(['providerId' => 'https://some-sp-entity-id']); $this->assertEquals('https://some-sp-entity-id', $state['SPMetadata']['entityid']); $this->assertStringStartsWith( 'http://idp.examlple.com/saml2/idp/SSOService.php?spentityid=https%3A%2F%2Fsome-sp-entity-id&cookie', $state['\SimpleSAML\Auth\State.restartURL'] ); unset($state['saml:AuthnRequestReceivedAt']); // timestamp can't be tested in equality assertion unset($state['SPMetadata']); // entityid asserted above unset($state['\SimpleSAML\Auth\State.restartURL']); // url contains a cookie time which varies by test $expectedState = $this->defaultExpectedAuthState; $expectedState['saml:ConsumerURL'] = 'https://example.com/Shibboleth.sso/SAML2/POST'; $expectedState['saml:Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'; $this->assertEquals($expectedState, $state); } /** * Test that invoking the idp initiated endpoint using minimum shib params works * @return void */ public function testIdPInitShibCompatOptionalParams(): void { $state = $this->idpInitiatedHelper([ 'providerId' => 'https://some-sp-entity-id', 'target' => 'http://relay', 'shire' => 'https://example.com/Shibboleth.sso/SAML2/ECP', ]); $this->assertEquals('https://some-sp-entity-id', $state['SPMetadata']['entityid']); //currently only spentityid and relay state are used in the restart url. $this->assertStringStartsWith( 'http://idp.examlple.com/saml2/idp/SSOService.php?' . 'spentityid=https%3A%2F%2Fsome-sp-entity-id&RelayState=http%3A%2F%2Frelay&cookieTime', $state['\SimpleSAML\Auth\State.restartURL'] ); unset($state['saml:AuthnRequestReceivedAt']); // timestamp can't be tested in equality assertion unset($state['SPMetadata']); // entityid asserted above unset($state['\SimpleSAML\Auth\State.restartURL']); // url contains a cookie time which varies by test $expectedState = $this->defaultExpectedAuthState; $expectedState['saml:ConsumerURL'] = 'https://example.com/Shibboleth.sso/SAML2/ECP'; $expectedState['saml:Binding'] = 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS'; $expectedState['saml:RelayState'] = 'http://relay'; $this->assertEquals($expectedState, $state); } /** * Invoke IDP initiated login with the given query parameters. * Callers should validate the return state array or confirm appropriate exceptions are returned. * * @param array $queryParams * @return array The state array used for handling the authentication request. */ private function idpInitiatedHelper(array $queryParams): array { /** @var \PHPUnit_Framework_MockObject_MockObject $idpStub */ $idpStub = $this->getMockBuilder(IdP::class) ->disableOriginalConstructor() ->getMock(); $idpMetadata = Configuration::loadFromArray([ 'entityid' => 'https://idp-entity.id', 'saml20.ecp' => true, //enable additional bindings so we can test selection logic ]); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $idpStub->method("getConfig") ->willReturn($idpMetadata); // phpcs:disable $spMetadataXml = <<< 'EOT' EOT; // phpcs:enable Configuration::loadFromArray([ 'baseurlpath' => 'https://idp.example.com/', 'metadata.sources' => [ ["type" => "xml", 'xml' => $spMetadataXml], ], ], '', 'simplesaml'); // Since we aren't really running on a webserver some of the url calculations done, such as for restart url // won't line up perfectly $_REQUEST = $_REQUEST + $queryParams; $_SERVER['HTTP_HOST'] = 'idp.examlple.com'; $_SERVER['REQUEST_URI'] = '/saml2/idp/SSOService.php?' . http_build_query($queryParams); $state = []; /** @psalm-suppress InvalidArgument Remove when PHPunit 8 is in place */ $idpStub->expects($this->once()) ->method('handleAuthenticationRequest') ->with($this->callback( /** * @param array $arg * @return bool */ function ($arg) use (&$state) { $state = $arg; return true; } )); /** @psalm-suppress InvalidArgument */ SAML2::receiveAuthnRequest($idpStub); return $state; } } simplesamlphp-1.19.1/tests/modules/saml/lib/Auth/0000755000000000000000000000000014042503475020400 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/Auth/Process/0000755000000000000000000000000014042503475022016 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/Auth/Process/FilterScopesTest.php0000644000000000000000000001060714042503475025775 0ustar rootroot * @package SimpleSAMLphp */ class FilterScopesTest extends TestCase { /** * Helper function to run the filter with a given configuration. * * @param array $config The filter configuration. * @param array $request The request state. * @return array The state array after processing. */ private function processFilter(array $config, array $request): array { $filter = new FilterScopes($config, null); $filter->process($request); return $request; } /** * Test valid scopes. * @return void */ public function testValidScopes(): void { // test declared scopes $config = []; $request = [ 'Source' => [ 'SingleSignOnService' => [ [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'https://example.org/saml2/idp/SSOService.php', ], ], 'scope' => [ 'example.com', 'example.net', ], ], 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], ], ]; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); // test multiple values $request['Attributes'] = [ 'eduPersonPrincipalName' => [ 'jdoe@example.com', 'jdoe@example.net', ], ]; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); // test implicit scope $request['Attributes'] = [ 'eduPersonPrincipalName' => ['jdoe@example.org'], ]; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); // test alternative attributes $config['attributes'] = [ 'mail', ]; $request['Attributes'] = [ 'mail' => ['john.doe@example.org'], ]; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); // test non-scoped attributes $request['Attributes']['givenName'] = 'John Doe'; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); } /** * Test invalid scopes. * @return void */ public function testInvalidScopes(): void { // test scope not matching anything, empty attribute $config = []; $request = [ 'Source' => [ 'SingleSignOnService' => [ [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'https://example.org/saml2/idp/SSOService.php', ], ], 'scope' => [ 'example.com', 'example.net', ], ], 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.edu'], ], ]; $result = $this->processFilter($config, $request); $this->assertEquals([], $result['Attributes']); // test some scopes allowed and some others not $request['Attributes']['eduPersonPrincipalName'][] = 'jdoe@example.com'; $result = $this->processFilter($config, $request); $this->assertEquals( [ 'eduPersonPrincipalName' => [ 'jdoe@example.com', ], ], $result['Attributes'] ); // test attribute missing scope $request['Attributes'] = [ 'eduPersonPrincipalName' => ['jdoe'], ]; $result = $this->processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); } } simplesamlphp-1.19.1/tests/modules/saml/lib/Auth/Process/NameIDAttributeTest.php0000644000000000000000000001515614042503475026360 0ustar rootroot * @package SimpleSAMLphp */ class NameIDAttributeTest extends TestCase { /** * Helper function to run the filter with a given configuration. * * @param array $config The filter configuration. * @param array $request The request state. * @return array The state array after processing. */ private function processFilter(array $config, array $request): array { $filter = new NameIDAttribute($config, null); $filter->process($request); return $request; } /** * Test minimal configuration. * @return void */ public function testMinimalConfig(): void { $config = []; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $nameId->setFormat(Constants::NAMEID_PERSISTENT); $nameId->setNameQualifier($idpId); $nameId->setSPNameQualifier($spId); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $result = $this->processFilter($config, $request); $this->assertEquals("{$idpId}!{$spId}!{$nameId->getValue()}", $result['Attributes']['nameid'][0]); } /** * Test custom attribute name. * @return void */ public function testCustomAttributeName(): void { $attributeName = 'eugeneNameIDAttribute'; $config = ['attribute' => $attributeName]; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $nameId->setFormat(Constants::NAMEID_PERSISTENT); $nameId->setNameQualifier($idpId); $nameId->setSPNameQualifier($spId); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $result = $this->processFilter($config, $request); $this->assertTrue(isset($result['Attributes'][$attributeName])); $this->assertEquals("{$idpId}!{$spId}!{$nameId->getValue()}", $result['Attributes'][$attributeName][0]); } /** * Test custom format. * @return void */ public function testFormat(): void { $config = ['format' => '%V!%%']; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $nameId->setFormat(Constants::NAMEID_PERSISTENT); $nameId->setNameQualifier($idpId); $nameId->setSPNameQualifier($spId); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $result = $this->processFilter($config, $request); $this->assertEquals("{$nameId->getValue()}!%", $result['Attributes']['nameid'][0]); } /** * Test invalid format throws an exception. * @return void */ public function testInvalidFormatThrowsException() { $config = ['format' => '%X']; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $this->expectException(Error\Exception::class); $this->expectExceptionMessage('NameIDAttribute: Invalid replacement: "%X"'); $this->processFilter($config, $request); } /** * Test invalid request silently continues, leaving the state untouched * @return void */ public function testInvalidRequestLeavesStateUntouched() { $config = ['format' => '%V!%F']; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], ]; $pre = $request; $this->processFilter($config, $request); $this->assertEquals($pre, $request); } /** * Test custom attribute name with format. * @return void */ public function testCustomAttributeNameAndFormat(): void { $attributeName = 'eugeneNameIDAttribute'; $config = ['attribute' => $attributeName, 'format' => '%V']; $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $nameId->setFormat(Constants::NAMEID_PERSISTENT); $nameId->setNameQualifier($idpId); $nameId->setSPNameQualifier($spId); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $result = $this->processFilter($config, $request); $this->assertTrue(isset($result['Attributes'][$attributeName])); $this->assertEquals("{$nameId->getValue()}", $result['Attributes'][$attributeName][0]); } /** * Test overriding NameID Format/NameQualifier/SPNameQualifier with defaults. * @return void */ public function testOverrideNameID() { $spId = 'eugeneSP'; $idpId = 'eugeneIdP'; $nameId = new NameID(); $nameId->setValue('eugene@oombaas'); $request = [ 'Source' => [ 'entityid' => $spId, ], 'Destination' => [ 'entityid' => $idpId, ], 'saml:sp:NameID' => $nameId, ]; $this->processFilter(array(), $request); $this->assertEquals("{$nameId->getFormat()}", Constants::NAMEID_UNSPECIFIED); $this->assertEquals("{$nameId->getNameQualifier()}", $idpId); $this->assertEquals("{$nameId->getSPNameQualifier()}", $spId); } } simplesamlphp-1.19.1/tests/modules/saml/lib/Auth/Source/0000755000000000000000000000000014042503475021640 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php0000644000000000000000000003265614042503475026207 0ustar rootrootidpMetadata) { $this->idpMetadata = new Configuration( $this->idpConfigArray, 'Auth_Source_SP_Test::getIdpMetadata()' ); } return $this->idpMetadata; } /** * @return void */ protected function setUp() { parent::setUp(); $this->idpConfigArray = [ 'metadata-set' => 'saml20-idp-remote', 'entityid' => 'https://engine.surfconext.nl/authentication/idp/metadata', 'SingleSignOnService' => [ [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'https://engine.surfconext.nl/authentication/idp/single-sign-on', ], ], 'keys' => [ [ 'encryption' => false, 'signing' => true, 'type' => 'X509Certificate', 'X509Certificate' => 'MIID3zCCAsegAwIBAgIJAMVC9xn1ZfsuMA0GCSqGSIb3DQEBCwUAMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXR' . 'yZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VSRm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MS' . 'YwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDUwNTAeFw0xNDA1MDUxNDIyMzVaFw0xOTA1MDUxNDIyM' . 'zVaMIGFMQswCQYDVQQGEwJOTDEQMA4GA1UECAwHVXRyZWNodDEQMA4GA1UEBwwHVXRyZWNodDEVMBMGA1UECgwMU1VS' . 'Rm5ldCBCLlYuMRMwEQYDVQQLDApTVVJGY29uZXh0MSYwJAYDVQQDDB1lbmdpbmUuc3VyZmNvbmV4dC5ubCAyMDE0MDU' . 'wNTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKthMDbB0jKHefPzmRu9t2h7iLP4wAXr42bHpjzTEk6gtt' . 'HFb4l/hFiz1YBI88TjiH6hVjnozo/YHA2c51us+Y7g0XoS7653lbUN/EHzvDMuyis4Xi2Ijf1A/OUQfH1iFUWttIgtW' . 'K9+fatXoGUS6tirQvrzVh6ZstEp1xbpo1SF6UoVl+fh7tM81qz+Crr/Kroan0UjpZOFTwxPoK6fdLgMAieKSCRmBGpb' . 'JHbQ2xxbdykBBrBbdfzIX4CDepfjE9h/40ldw5jRn3e392jrS6htk23N9BWWrpBT5QCk0kH3h/6F1Dm6TkyG9CDtt73' . '/anuRkvXbeygI4wml9bL3rE8CAwEAAaNQME4wHQYDVR0OBBYEFD+Ac7akFxaMhBQAjVfvgGfY8hNKMB8GA1UdIwQYMB' . 'aAFD+Ac7akFxaMhBQAjVfvgGfY8hNKMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAC8L9D67CxIhGo5aG' . 'Vu63WqRHBNOdo/FAGI7LURDFeRmG5nRw/VXzJLGJksh4FSkx7aPrxNWF1uFiDZ80EuYQuIv7bDLblK31ZEbdg1R9Lgi' . 'ZCdYSr464I7yXQY9o6FiNtSKZkQO8EsscJPPy/Zp4uHAnADWACkOUHiCbcKiUUFu66dX0Wr/v53Gekz487GgVRs8HEe' . 'T9MU1reBKRgdENR8PNg4rbQfLc3YQKLWK7yWnn/RenjDpuCiePj8N8/80tGgrNgK/6fzM3zI18sSywnXLswxqDb/J+j' . 'gVxnQ6MrsTf1urM8MnfcxG/82oHIwfMh/sXPCZpo+DTLkhQxctJ3M=', ], ], ]; $this->config = Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); } /** * Create a SAML AuthnRequest using \SimpleSAML\Module\saml\Auth\Source\SP * * @param array $state The state array to use in the test. This is an array of the parameters described in section * 2 of https://simplesamlphp.org/docs/development/saml:sp * * @return \SAML2\AuthnRequest The AuthnRequest generated. */ private function createAuthnRequest(array $state = []): AuthnRequest { $info = ['AuthId' => 'default-sp']; $config = []; $as = new SpTester($info, $config); /** @var \SAML2\AuthnRequest $ar */ $ar = null; try { $as->startSSO2Test($this->getIdpMetadata(), $state); $this->assertTrue(false, 'Expected ExitTestException'); } catch (ExitTestException $e) { $r = $e->getTestResult(); $ar = $r['ar']; } return $ar; } /** * Test generating an AuthnRequest * @test * @return void */ public function testAuthnRequest(): void { /** @var \SAML2\AuthnRequest $ar */ $ar = $this->createAuthnRequest(); // Assert values in the generated AuthnRequest /** @var \DOMElement $xml */ $xml = $ar->toSignedXML(); /** @var \DOMAttr[] $q */ $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/@Destination'); $this->assertEquals( $this->idpConfigArray['SingleSignOnService'][0]['Location'], $q[0]->value ); $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/saml:Issuer'); $this->assertEquals( 'http://localhost/simplesaml/module.php/saml/sp/metadata.php/default-sp', $q[0]->textContent ); } /** * Test setting a Subject * @test * @return void */ public function testNameID(): void { $state = [ 'saml:NameID' => ['Value' => 'user@example.org', 'Format' => Constants::NAMEID_UNSPECIFIED] ]; /** @var \SAML2\AuthnRequest $ar */ $ar = $this->createAuthnRequest($state); /** @var \SAML2\XML\saml\NameID $nameID */ $nameID = $ar->getNameId(); $this->assertEquals($state['saml:NameID']['Value'], $nameID->getValue()); $this->assertEquals($state['saml:NameID']['Format'], $nameID->getFormat()); /** @var \DOMElement $xml */ $xml = $ar->toSignedXML(); /** @var \DOMAttr[] $q */ $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/saml:Subject/saml:NameID/@Format'); $this->assertEquals( $state['saml:NameID']['Format'], $q[0]->value ); $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/saml:Subject/saml:NameID'); $this->assertEquals( $state['saml:NameID']['Value'], $q[0]->textContent ); } /** * Test setting an AuthnConextClassRef * @test * @return void */ public function testAuthnContextClassRef(): void { $state = [ 'saml:AuthnContextClassRef' => 'http://example.com/myAuthnContextClassRef' ]; /** @var \SAML2\AuthnRequest $ar */ $ar = $this->createAuthnRequest($state); /** @var array $a */ $a = $ar->getRequestedAuthnContext(); $this->assertEquals( $state['saml:AuthnContextClassRef'], $a['AuthnContextClassRef'][0] ); /** @var \DOMElement $xml */ $xml = $ar->toSignedXML(); $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/samlp:RequestedAuthnContext/saml:AuthnContextClassRef'); $this->assertEquals( $state['saml:AuthnContextClassRef'], $q[0]->textContent ); } /** * Test setting ForcedAuthn * @test * @return void */ public function testForcedAuthn(): void { /** @var bool $state['ForceAuthn'] */ $state = [ 'ForceAuthn' => true ]; /** @var \SAML2\AuthnRequest $ar */ $ar = $this->createAuthnRequest($state); $this->assertEquals( $state['ForceAuthn'], $ar->getForceAuthn() ); /** @var \DOMElement $xml */ $xml = $ar->toSignedXML(); /** @var \DOMAttr[] $q */ $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/@ForceAuthn'); $this->assertEquals( $state['ForceAuthn'] ? 'true' : 'false', $q[0]->value ); } /** * Test specifying an IDPList where no metadata found for those idps is an error * @return void */ public function testIdpListWithNoMatchingMetadata(): void { $this->expectException(NoSupportedIDP::class); $state = [ 'saml:IDPList' => ['noSuchIdp'] ]; $info = ['AuthId' => 'default-sp']; $config = []; $as = new SpTester($info, $config); $as->authenticate($state); } /** * Test specifying an IDPList where the list does not overlap with the Idp specified in SP config is an error * @return void */ public function testIdpListWithExplicitIdpNotMatch(): void { $this->expectException(NoAvailableIDP::class); $entityId = "https://example.com"; $xml = MetaDataStorageSourceTest::generateIdpMetadataXml($entityId); $c = [ 'metadata.sources' => [ ["type" => "xml", "xml" => $xml], ], ]; Configuration::loadFromArray($c, '', 'simplesaml'); $state = [ 'saml:IDPList' => ['noSuchIdp', $entityId] ]; $info = ['AuthId' => 'default-sp']; $config = [ 'idp' => 'https://engine.surfconext.nl/authentication/idp/metadata' ]; $as = new SpTester($info, $config); $as->authenticate($state); } /** * Test that IDPList overlaps with the IDP specified in SP config results in AuthnRequest * @return void */ public function testIdpListWithExplicitIdpMatch(): void { $entityId = "https://example.com"; $xml = MetaDataStorageSourceTest::generateIdpMetadataXml($entityId); $c = [ 'metadata.sources' => [ ["type" => "xml", "xml" => $xml], ], ]; Configuration::loadFromArray($c, '', 'simplesaml'); $state = [ 'saml:IDPList' => ['noSuchIdp', $entityId] ]; $info = ['AuthId' => 'default-sp']; $config = [ 'idp' => $entityId ]; $as = new SpTester($info, $config); try { $as->authenticate($state); $this->fail('Expected ExitTestException'); } catch (ExitTestException $e) { $r = $e->getTestResult(); /** @var AuthnRequest $ar */ $ar = $r['ar']; $xml = $ar->toSignedXML(); /** @var \DOMAttr[] $q */ $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/@Destination'); $this->assertEquals( 'https://saml.idp/sso/', $q[0]->value ); } } /** * Test that IDPList with a single valid idp and no SP config idp results in AuthnRequest to that idp * @return void */ public function testIdpListWithSingleMatch(): void { $entityId = "https://example.com"; $xml = MetaDataStorageSourceTest::generateIdpMetadataXml($entityId); $c = [ 'metadata.sources' => [ ["type" => "xml", "xml" => $xml], ], ]; Configuration::loadFromArray($c, '', 'simplesaml'); $state = [ 'saml:IDPList' => ['noSuchIdp', $entityId] ]; $info = ['AuthId' => 'default-sp']; $config = []; $as = new SpTester($info, $config); try { $as->authenticate($state); $this->fail('Expected ExitTestException'); } catch (ExitTestException $e) { $r = $e->getTestResult(); /** @var AuthnRequest $ar */ $ar = $r['ar']; $xml = $ar->toSignedXML(); /** @var \DOMAttr[] $q */ $q = Utils::xpQuery($xml, '/samlp:AuthnRequest/@Destination'); $this->assertEquals( 'https://saml.idp/sso/', $q[0]->value ); } } /** * Test that IDPList with multiple valid idp and no SP config idp results in discovery redirect * @return void */ public function testIdpListWithMultipleMatch(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid URL: smtp://invalidurl'); $entityId = "https://example.com"; $xml = MetaDataStorageSourceTest::generateIdpMetadataXml($entityId); $entityId1 = "https://example1.com"; $xml1 = MetaDataStorageSourceTest::generateIdpMetadataXml($entityId1); $c = [ 'metadata.sources' => [ ["type" => "xml", "xml" => $xml], ["type" => "xml", "xml" => $xml1], ], ]; Configuration::loadFromArray($c, '', 'simplesaml'); $state = [ 'saml:IDPList' => ['noSuchIdp', $entityId, $entityId1] ]; $info = ['AuthId' => 'default-sp']; $config = [ // Use a url that is invalid for http redirects so redirect code throws an error // otherwise it will call exit 'discoURL' => 'smtp://invalidurl' ]; // Http redirect util library requires a request_uri to be set. $_SERVER['REQUEST_URI'] = 'https://l.example.com/'; $as = new SpTester($info, $config); $as->authenticate($state); } } simplesamlphp-1.19.1/tests/modules/core/0000755000000000000000000000000014042503475016725 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/0000755000000000000000000000000014042503475017473 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/Controller/0000755000000000000000000000000014042503475021616 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/Controller/LoginTest.php0000644000000000000000000002231214042503475024237 0ustar rootrootauthSources = [ 'admin' => [ 'core:adminPassword' ], 'example-userpass' => [ 'exampleauth:UserPass', 'username:password' => [ 'uid' => ['test'] ] ] ]; $this->config = Configuration::loadFromArray( [ 'baseurlpath' => 'https://example.org/simplesaml', 'module.enable' => ['exampleauth' => true], 'usenewui' => true, ], '[ARRAY]', 'simplesaml' ); Configuration::setPreLoadedConfig($this->config, 'config.php'); } /** * Test that authentication is started immediately if we hit the login endpoint and there's only one non-admin * source configured. * @return void */ public function testAutomaticLoginWhenOnlyOneSource(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $request = new Request(); $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); /** @var \SimpleSAML\HTTP\RunnableResponse $response */ $response = $c->login($request); $this->assertInstanceOf(RunnableResponse::class, $response); $this->assertIsCallable($response->getCallable()); $arguments = $response->getArguments(); $this->assertArrayHasKey('ErrorURL', $arguments[0]); $this->assertArrayHasKey('ReturnTo', $arguments[0]); } /** * Test that the user can choose what auth source to use when there are multiple defined (admin excluded). * @return void */ public function testMultipleAuthSources(): void { $_SERVER['REQUEST_URI'] = '/'; $asConfig = Configuration::loadFromArray( array_merge( $this->authSources, [ 'example-static' => [ 'exampleauth:StaticSource', 'uid' => ['test'] ] ] ) ); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $request = new Request(); $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); /** @var \SimpleSAML\XHTML\Template $response */ $response = $c->login($request); $this->assertInstanceOf(Template::class, $response); $this->assertEquals('core:login.twig', $response->getTemplateName()); $this->assertArrayHasKey('sources', $response->data); $this->assertArrayHasKey('example-userpass', $response->data['sources']); $this->assertArrayHasKey('example-static', $response->data['sources']); } /** * Test that specifying an invalid auth source while trying to login raises an exception. * @return void */ public function testLoginWithInvalidAuthSource(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $request = new Request(); $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); $this->expectException(Exception::class); $c->login($request, 'invalid-auth-source'); } /** * Test that we get redirected to /account/authsource when accessing the login endpoint while being already * authenticated. * @return void */ public function testLoginWhenAlreadyAuthenticated(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $session = Session::getSessionFromRequest(); $session->setConfiguration($this->config); $class = new ReflectionClass($session); $authData = $class->getProperty('authData'); $authData->setAccessible(true); $authData->setValue($session, [ 'example-userpass' => [ 'exampleauth:UserPass', 'Attributes' => ['uid' => ['test']], 'Authority' => 'example-userpass', 'AuthnInstant' => time(), 'Expire' => time() + 8 * 60 * 60 ] ]); $factory = new AuthenticationFactory($this->config, $session); $request = new Request(); $c = new Controller\Login($this->config, $session, $factory); /** @var \Symfony\Component\HttpFoundation\RedirectResponse $response */ $response = $c->login($request); $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertEquals( 'https://example.org/simplesaml/module.php/core/account/example-userpass', $response->getTargetUrl() ); } /** * Test that triggering the logout controller actually proceeds to log out from the specified source. * @return void */ public function testLogout(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); $response = $c->logout('example-userpass'); $this->assertInstanceOf(RunnableResponse::class, $response); $this->assertIsCallable($response->getCallable()); $this->assertEquals('/simplesaml/', $response->getArguments()[0]); } /** * Test that accessing the "account" endpoint without being authenticated gets you redirected to the "login" * endpoint. * @return void */ public function testNotAuthenticated(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $session = Session::getSessionFromRequest(); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); /** @var RedirectResponse $response */ $response = $c->account('example-userpass'); $this->assertInstanceOf(RedirectResponse::class, $response); $this->assertEquals( 'https://example.org/simplesaml/module.php/core/login/example-userpass', $response->getTargetUrl() ); } /** * Test that we are presented with a regular page if we are authenticated and try to access the "account" endpoint. * @return void */ public function testAuthenticated(): void { $asConfig = Configuration::loadFromArray($this->authSources); Configuration::setPreLoadedConfig($asConfig, 'authsources.php'); $session = Session::getSessionFromRequest(); $class = new ReflectionClass($session); $authData = $class->getProperty('authData'); $authData->setAccessible(true); $authData->setValue($session, [ 'example-userpass' => [ 'exampleauth:UserPass', 'Attributes' => ['uid' => ['test']], 'Authority' => 'example-userpass', 'AuthnInstant' => time(), 'Expire' => time() + 8 * 60 * 60 ] ]); $factory = new AuthenticationFactory($this->config, $session); $c = new Controller\Login($this->config, $session, $factory); /** @var \SimpleSAML\XHTML\Template $response */ $response = $c->account('example-userpass'); $this->assertInstanceOf(Template::class, $response); $this->assertEquals('auth_status.twig', $response->getTemplateName()); } } simplesamlphp-1.19.1/tests/modules/core/lib/Storage/0000755000000000000000000000000014042503475021077 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/Storage/SQLPermanentStorageTest.php0000644000000000000000000000702614042503475026313 0ustar rootroot sys_get_temp_dir(), ]); self::$sql = new SQLPermanentStorage('test', $config); } /** * @return void */ public static function tearDownAfterClass() { self::$sql = null; unlink(sys_get_temp_dir() . '/sqllite/test.sqlite'); } /** * @return void */ public function testSet(): void { // Set a new value self::$sql->set('testtype', 'testkey1', 'testkey2', 'testvalue', 2); // Test getCondition /** @var array $result */ $result = self::$sql->get(); $this->assertEquals('testvalue', $result['value']); } /** * @return void */ public function testSetOverwrite(): void { // Overwrite existing value self::$sql->set('testtype', 'testkey1', 'testkey2', 'testvaluemodified', 2); // Test that the value was actually overwriten $result = self::$sql->getValue('testtype', 'testkey1', 'testkey2'); $this->assertEquals('testvaluemodified', $result); /** @var array $result */ $result = self::$sql->getList('testtype', 'testkey1', 'testkey2'); $this->assertEquals('testvaluemodified', $result[0]['value']); } /** * @return void */ public function testNonexistentKey(): void { // Test that getting some non-existing key will return null / empty array $result = self::$sql->getValue('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent'); $this->assertNull($result); $result = self::$sql->getList('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent'); $this->assertEmpty($result); $result = self::$sql->get('testtype_nonexistent', 'testkey1_nonexistent', 'testkey2_nonexistent'); $this->assertNull($result); } /** * @return void */ public function testExpiration(): void { // Make sure the earlier created entry has expired now sleep(3); // Make sure we can't get the expired entry anymore $result = self::$sql->getValue('testtype', 'testkey1', 'testkey2'); $this->assertNull($result); // Now add a second entry that never expires self::$sql->set('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring', 'testvalue_nonexpiring', null); // Expire entries and verify that only the second one is still there self::$sql->removeExpired(); $result = self::$sql->getValue('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring'); $this->assertEquals('testvalue_nonexpiring', $result); } /** * @return void */ public function testRemove(): void { // Now remove the nonexpiring entry and make sure it's gone self::$sql->remove('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring'); $result = self::$sql->getValue('testtype', 'testkey1_nonexpiring', 'testkey2_nonexpiring'); $this->assertNull($result); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/0000755000000000000000000000000014042503475020374 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/0000755000000000000000000000000014042503475022012 5ustar rootrootsimplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeRealmTest.php0000644000000000000000000000770514042503475026320 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic() { $config = [ ]; $request = [ 'Attributes' => [], 'UserID' => 'user2@example.org', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('realm', $attributes); $this->assertEquals($attributes['realm'], ['example.org']); } /** * Test no userid set * @return void */ public function testNoUserID() { $this->expectException(\Exception::class); $config = [ ]; $request = [ 'Attributes' => [], ]; self::processFilter($config, $request); } /** * Test with configuration. * @return void */ public function testAttributeNameConfig() { $config = [ 'attributename' => 'schacHomeOrganization', ]; $request = [ 'Attributes' => [ 'displayName' => 'Joe User', 'schacGender' => 9, ], 'UserID' => 'user2@example.org', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('schacHomeOrganization', $attributes); $this->assertArrayHasKey('displayName', $attributes); $this->assertEquals($attributes['schacHomeOrganization'], ['example.org']); } /** * When target attribute exists it will be overwritten * @return void */ public function testTargetAttributeOverwritten() { $config = [ 'attributename' => 'schacHomeOrganization', ]; $request = [ 'Attributes' => [ 'displayName' => 'Joe User', 'schacGender' => 9, 'schacHomeOrganization' => 'example.com', ], 'UserID' => 'user2@example.org', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('schacHomeOrganization', $attributes); $this->assertEquals($attributes['schacHomeOrganization'], ['example.org']); } /** * When source attribute has no "@" no realm is added * @return void */ public function testNoAtisNoOp() { $config = []; $request = [ 'Attributes' => [ 'displayName' => 'Joe User', ], 'UserID' => 'user2', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('realm', $attributes); } /** * When source attribute has more than one "@" no realm is added * @return void */ public function testMultiAtisNoOp() { $config = []; $request = [ 'Attributes' => [ 'displayName' => 'Joe User', ], 'UserID' => 'user2@home@example.org', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('realm', $attributes); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeValueMapTest.php0000644000000000000000000001655714042503475026777 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testBasic(): void { $config = [ 'sourceattribute' => 'memberOf', 'targetattribute' => 'eduPersonAffiliation', 'values' => [ 'member' => [ 'theGroup', 'otherGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('memberOf', $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); } /** * Test basic functionality, remove duplicates * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testNoDuplicates(): void { $config = [ 'sourceattribute' => 'memberOf', 'targetattribute' => 'eduPersonAffiliation', 'values' => [ 'member' => [ 'theGroup', 'otherGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup', 'otherGroup'], 'eduPersonAffiliation' => ['member', 'someValue'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('memberOf', $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member', 'someValue']); } /** * Test the %replace functionality. * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testReplace(): void { $config = [ 'sourceattribute' => 'memberOf', 'targetattribute' => 'eduPersonAffiliation', '%replace', 'values' => [ 'member' => [ 'theGroup', 'otherGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], 'eduPersonAffiliation' => ['someValue'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('memberOf', $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); } /** * Test the %keep functionality. * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testKeep(): void { $config = [ 'sourceattribute' => 'memberOf', 'targetattribute' => 'eduPersonAffiliation', '%keep', 'values' => [ 'member' => [ 'theGroup', 'otherGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], 'eduPersonAffiliation' => ['someValue'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('memberOf', $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['someValue', 'member']); } /** * Test unknown flag Exception * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testUnknownFlag(): void { $config = [ '%test', 'targetattribute' => 'affiliation', 'sourceattribute' => 'memberOf', 'values' => [ 'member' => [ 'theGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], ], ]; $result = self::processFilter($config, $request); $this->assertArrayHasKey('affiliation', $result['Attributes']); $this->assertArrayNotHasKey('memberOf', $result['Attributes']); $this->assertContains('member', $result['Attributes']['affiliation']); } /** * Test missing Source attribute * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testMissingSourceAttribute(): void { $this->expectException(Exception::class); $config = [ 'targetattribute' => 'affiliation', 'values' => [ 'member' => [ 'theGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], ], ]; self::processFilter($config, $request); } /** * Test missing Target attribute * * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::__construct * @covers SimpleSAML\Module\core\Auth\Process\AttributeValueMap::process * @return void */ public function testMissingTargetAttribute(): void { $this->expectException(Exception::class); $config = [ 'sourceattribute' => 'memberOf', 'values' => [ 'member' => [ 'theGroup', ], ], ]; $request = [ 'Attributes' => [ 'memberOf' => ['theGroup'], ], ]; self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php0000644000000000000000000002000014042503475026310 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], 'eduPersonAffiliation' => ['member'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('eduPersonScopedAffiliation', $attributes); $this->assertEquals($attributes['eduPersonScopedAffiliation'], ['member@example.com']); } /** * If target attribute already set, module must add, not overwrite. * @return void */ public function testNoOverwrite(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], 'eduPersonAffiliation' => ['member'], 'eduPersonScopedAffiliation' => ['library-walk-in@example.edu'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals( $attributes['eduPersonScopedAffiliation'], ['library-walk-in@example.edu', 'member@example.com'] ); } /** * If same scope already set, module must do nothing, not duplicate value. * @return void */ public function testNoDuplication(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], 'eduPersonAffiliation' => ['member'], 'eduPersonScopedAffiliation' => ['member@example.com'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['eduPersonScopedAffiliation'], ['member@example.com']); } /** * If source attribute not set, nothing happens * @return void */ public function testNoSourceAttribute(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'mail' => ['j.doe@example.edu', 'john@example.org'], 'eduPersonAffiliation' => ['member'], 'eduPersonScopedAffiliation' => ['library-walk-in@example.edu'], ] ]; $result = self::processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); } /** * If scope attribute not set, nothing happens * @return void */ public function testNoScopeAttribute(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'mail' => ['j.doe@example.edu', 'john@example.org'], 'eduPersonScopedAffiliation' => ['library-walk-in@example.edu'], 'eduPersonPrincipalName' => ['jdoe@example.com'], ] ]; $result = self::processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); } /** * When multiple @ signs in attribute, will use the first one. * @return void */ public function testMultiAt(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['john@doe@example.com'], 'eduPersonAffiliation' => ['member'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['eduPersonScopedAffiliation'], ['member@doe@example.com']); } /** * When multiple values in source attribute, should render multiple targets. * @return void */ public function testMultivaluedSource(): void { $config = [ 'scopeAttribute' => 'eduPersonPrincipalName', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], 'eduPersonAffiliation' => ['member', 'staff', 'faculty'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals( $attributes['eduPersonScopedAffiliation'], ['member@example.com', 'staff@example.com', 'faculty@example.com'] ); } /** * When the source attribute doesn't have a scope, the entire value is used. * @return void */ public function testNoAt(): void { $config = [ 'scopeAttribute' => 'schacHomeOrganization', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', ]; $request = [ 'Attributes' => [ 'schacHomeOrganization' => ['example.org'], 'eduPersonAffiliation' => ['student'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['eduPersonScopedAffiliation'], ['student@example.org']); } /** * When the target attribute exists and onlyIfEmpty is set * @return void */ public function testOnlyIfEmpty(): void { $config = [ 'scopeAttribute' => 'schacHomeOrganization', 'sourceAttribute' => 'eduPersonAffiliation', 'targetAttribute' => 'eduPersonScopedAffiliation', 'onlyIfEmpty' => true, ]; $request = [ 'Attributes' => [ 'schacHomeOrganization' => ['example.org'], 'eduPersonAffiliation' => ['student'], 'eduPersonScopedAffiliation' => ['staff@example.org', 'member@example.org'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['eduPersonScopedAffiliation'], ['staff@example.org', 'member@example.org']); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/ScopeFromAttributeTest.php0000644000000000000000000000735014042503475027151 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'sourceAttribute' => 'eduPersonPrincipalName', 'targetAttribute' => 'scope', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('scope', $attributes); $this->assertEquals($attributes['scope'], ['example.com']); } /** * If scope already set, module must not overwrite. * @return void */ public function testNoOverwrite(): void { $config = [ 'sourceAttribute' => 'eduPersonPrincipalName', 'targetAttribute' => 'scope', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['jdoe@example.com'], 'scope' => ['example.edu'] ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['scope'], ['example.edu']); } /** * If source attribute not set, nothing happens * @return void */ public function testNoSourceAttribute(): void { $config = [ 'sourceAttribute' => 'eduPersonPrincipalName', 'targetAttribute' => 'scope', ]; $request = [ 'Attributes' => [ 'mail' => ['j.doe@example.edu', 'john@example.org'], 'scope' => ['example.edu'] ] ]; $result = self::processFilter($config, $request); $this->assertEquals($request['Attributes'], $result['Attributes']); } /** * When multiple @ signs in attribute, should use last one. * @return void */ public function testMultiAt(): void { $config = [ 'sourceAttribute' => 'eduPersonPrincipalName', 'targetAttribute' => 'scope', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['john@doe@example.com'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['scope'], ['example.com']); } /** * When the source attribute doesn't have a scope, a warning is emitted * @return void */ public function testNoAt(): void { $config = [ 'sourceAttribute' => 'eduPersonPrincipalName', 'targetAttribute' => 'scope', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['johndoe'], ] ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('scope', $attributes); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeMapTest.php0000644000000000000000000001462214042503475025771 0ustar rootrootprocess($request); return $request; } /** * @return void */ public function testBasic(): void { $config = [ 'attribute1' => 'attribute2', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute2' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testDuplicate(): void { $config = [ 'attribute1' => 'attribute2', '%duplicate', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute1' => ['value'], 'attribute2' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testMultiple(): void { $config = [ 'attribute1' => ['attribute2', 'attribute3'], ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute2' => ['value'], 'attribute3' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testMultipleDuplicate(): void { $config = [ 'attribute1' => ['attribute2', 'attribute3'], '%duplicate', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute1' => ['value'], 'attribute2' => ['value'], 'attribute3' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testCircular(): void { $config = [ 'attribute1' => 'attribute1', 'attribute2' => 'attribute2', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], 'attribute2' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute1' => ['value'], 'attribute2' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testMissingMap(): void { $config = [ 'attribute1' => 'attribute3', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], 'attribute2' => ['value'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute2' => ['value'], 'attribute3' => ['value'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testInvalidOriginalAttributeType(): void { $config = [ 10 => 'attribute2', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $this->expectException(\Exception::class); self::processFilter($config, $request); } /** * @return void */ public function testInvalidMappedAttributeType(): void { $config = [ 'attribute1' => 10, ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $this->expectException(\Exception::class); self::processFilter($config, $request); } /** * @return void */ public function testMissingMapFile(): void { $config = [ 'non_existant_mapfile', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value'], ], ]; $this->expectException(\Exception::class); self::processFilter($config, $request); } /** * @return void */ public function testOverwrite(): void { $config = [ 'attribute1' => 'attribute2', ]; $request = [ 'Attributes' => [ 'attribute1' => ['value1'], 'attribute2' => ['value2'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute2' => ['value1'], ]; $this->assertEquals($expected, $result); } /** * @return void */ public function testOverwriteReversed(): void { $config = [ 'attribute1' => 'attribute2', ]; $request = [ 'Attributes' => [ 'attribute2' => ['value2'], 'attribute1' => ['value1'], ], ]; $processed = self::processFilter($config, $request); $result = $processed['Attributes']; $expected = [ 'attribute2' => ['value1'], ]; $this->assertEquals($expected, $result); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/CardinalitySingleTest.php0000644000000000000000000001205414042503475026772 0ustar rootroothttp; $filter = new CardinalitySingle($config, null, $http); $filter->process($request); return $request; } /** * @return void */ protected function setUp() { \SimpleSAML\Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); $this->http = $this->getMockBuilder(HttpAdapter::class) ->setMethods(['redirectTrustedURL']) ->getMock(); } /** * Test singleValued * @return void */ public function testSingleValuedUnchanged(): void { $config = [ 'singleValued' => ['eduPersonPrincipalName'] ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['eduPersonPrincipalName' => ['joe@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test first value extraction * @return void */ public function testFirstValue(): void { $config = [ 'firstValue' => ['eduPersonPrincipalName'] ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com', 'bob@example.net'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['eduPersonPrincipalName' => ['joe@example.com']]; $this->assertEquals($expectedData, $attributes, "Only first value should be returned"); } /** * @return void */ public function testFirstValueUnchanged(): void { $config = [ 'firstValue' => ['eduPersonPrincipalName'] ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['eduPersonPrincipalName' => ['joe@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test flattening * @return void */ public function testFlatten(): void { $config = [ 'flatten' => ['eduPersonPrincipalName'], 'flattenWith' => '|', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com', 'bob@example.net'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['eduPersonPrincipalName' => ['joe@example.com|bob@example.net']]; $this->assertEquals($expectedData, $attributes, "Flattened string should be returned"); } /** * @return void */ public function testFlattenUnchanged(): void { $config = [ 'flatten' => ['eduPersonPrincipalName'], 'flattenWith' => '|', ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['eduPersonPrincipalName' => ['joe@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test abort * @return void */ public function testAbort(): void { $config = [ 'singleValued' => ['eduPersonPrincipalName'], ]; $request = [ 'Attributes' => [ 'eduPersonPrincipalName' => ['joe@example.com', 'bob@example.net'], ], ]; /** @psalm-suppress UndefinedMethod */ $this->http->expects($this->once()) ->method('redirectTrustedURL'); $this->processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/CardinalityTest.php0000644000000000000000000001665314042503475025641 0ustar rootroothttp; $filter = new Cardinality($config, null, $http); $filter->process($request); return $request; } /** * @return void */ protected function setUp() { Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); $this->http = $this->getMockBuilder(HttpAdapter::class) ->setMethods(['redirectTrustedURL']) ->getMock(); } /** * Test where a minimum is set but no maximum * @return void */ public function testMinNoMax(): void { $config = [ 'mail' => ['min' => 1], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['mail' => ['joe@example.com', 'bob@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test where a maximum is set but no minimum * @return void */ public function testMaxNoMin(): void { $config = [ 'mail' => ['max' => 2], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['mail' => ['joe@example.com', 'bob@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test in bounds within a maximum an minimum * @return void */ public function testMaxMin(): void { $config = [ 'mail' => ['min' => 1, 'max' => 2], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $result = $this->processFilter($config, $request); $attributes = $result['Attributes']; $expectedData = ['mail' => ['joe@example.com', 'bob@example.com']]; $this->assertEquals($expectedData, $attributes, "Assertion values should not have changed"); } /** * Test maximum is out of bounds results in redirect * @return void */ public function testMaxOutOfBounds(): void { $config = [ 'mail' => ['max' => 2], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com', 'fred@example.com'], ], ]; /** @psalm-suppress UndefinedMethod It's a mock-object */ $this->http->expects($this->once()) ->method('redirectTrustedURL'); $this->processFilter($config, $request); } /** * Test minimum is out of bounds results in redirect * @return void */ public function testMinOutOfBounds(): void { $config = [ 'mail' => ['min' => 3], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; /** @psalm-suppress UndefinedMethod It's a mock-object */ $this->http->expects($this->once()) ->method('redirectTrustedURL'); $this->processFilter($config, $request); } /** * Test missing attribute results in redirect * @return void */ public function testMissingAttribute(): void { $config = [ 'mail' => ['min' => 1], ]; $request = [ 'Attributes' => [], ]; /** @psalm-suppress UndefinedMethod It's a mock-object */ $this->http->expects($this->once()) ->method('redirectTrustedURL'); $this->processFilter($config, $request); } /* * Configuration errors */ /** * Test invalid minimum values * @return void */ public function testMinInvalid(): void { $this->expectException(SspException::class); $this->expectExceptionMessageRegExp('/Minimum/'); $config = [ 'mail' => ['min' => false], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $this->processFilter($config, $request); } /** * Test invalid minimum values * @return void */ public function testMinNegative(): void { $this->expectException(SspException::class); $this->expectExceptionMessageRegExp('/Minimum/'); $config = [ 'mail' => ['min' => -1], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $this->processFilter($config, $request); } /** * Test invalid maximum values * @return void */ public function testMaxInvalid(): void { $this->expectException(SspException::class); $this->expectExceptionMessageRegExp('/Maximum/'); $config = [ 'mail' => ['max' => false], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $this->processFilter($config, $request); } /** * Test maximum < minimum * @return void */ public function testMinGreaterThanMax(): void { $this->expectException(SspException::class); $this->expectExceptionMessageRegExp('/less than/'); $config = [ 'mail' => ['min' => 2, 'max' => 1], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $this->processFilter($config, $request); } /** * Test invalid attribute name * @return void */ public function testInvalidAttributeName(): void { $this->expectException(SspException::class); $this->expectExceptionMessageRegExp('/Invalid attribute/'); $config = [ ['min' => 2, 'max' => 1], ]; $request = [ 'Attributes' => [ 'mail' => ['joe@example.com', 'bob@example.com'], ], ]; $this->processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/PHPTest.php0000644000000000000000000001040514042503475024012 0ustar rootrootprocess($request); return $request; } /** * Test the configuration of the filter. * @return void */ public function testInvalidConfiguration(): void { $config = []; $this->expectException(Error\Exception::class); $this->expectExceptionMessage( "core:PHP: missing mandatory configuration option 'code'." ); new PHP($config, null); } /** * Check that defining the code works as expected. * @return void */ public function testCodeDefined(): void { $config = [ 'code' => ' $attributes["key"] = array("value"); ', ]; $request = ['Attributes' => []]; $expected = [ 'Attributes' => [ 'key' => ['value'], ], ]; $this->assertEquals($expected, $this->processFilter($config, $request)); } /** * Check that the incoming attributes are also available after processing * @return void */ public function testPreserveIncomingAttributes(): void { $config = [ 'code' => ' $attributes["orig2"] = array("value0"); ', ]; $request = [ 'Attributes' => [ 'orig1' => ['value1', 'value2'], 'orig2' => ['value3'], 'orig3' => ['value4'] ] ]; $expected = [ 'Attributes' => [ 'orig1' => ['value1', 'value2'], 'orig2' => ['value0'], 'orig3' => ['value4'] ], ]; $this->assertEquals($expected, $this->processFilter($config, $request)); } /** * Check that throwing an Exception inside the PHP code of the * filter (a documented use case) works. * @return void */ public function testThrowExceptionFromFilter(): void { $config = [ 'code' => ' if (empty($attributes["uid"])) { throw new Exception("Missing uid attribute."); } $attributes["uid"][0] = strtoupper($attributes["uid"][0]); ', ]; $request = [ 'Attributes' => [ 'orig1' => ['value1', 'value2'], ] ]; $this->expectException(Exception::class); $this->expectExceptionMessage("Missing uid attribute."); $this->processFilter($config, $request); } /** * Check that the entire state can be adjusted. * @return void */ public function testStateCanBeModified(): void { $config = [ 'code' => ' $attributes["orig2"] = array("value0"); $state["newKey"] = ["newValue"]; $state["Destination"]["attributes"][] = "givenName"; ', ]; $request = [ 'Attributes' => [ 'orig1' => ['value1', 'value2'], 'orig2' => ['value3'], 'orig3' => ['value4'] ], 'Destination' => [ 'attributes' => ['eduPersonPrincipalName'] ], ]; $expected = [ 'Attributes' => [ 'orig1' => ['value1', 'value2'], 'orig2' => ['value0'], 'orig3' => ['value4'] ], 'Destination' => [ 'attributes' => ['eduPersonPrincipalName', 'givenName'] ], 'newKey' => ['newValue'] ]; $this->assertEquals($expected, $this->processFilter($config, $request)); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/TargetedIDTest.php0000644000000000000000000001632314042503475025344 0ustar rootrootprocess($request); return $request; } // /** // * Test the most basic functionality // * @return void // */ // public function testBasic() // { // $config = []; // $request = [ // 'Attributes' => [], // 'UserID' => 'user2@example.org', // ]; // $result = self::processFilter($config, $request); // $attributes = $result['Attributes']; // $this->assertArrayHasKey('eduPersonTargetedID', $attributes); // $this->assertRegExp('/^[0-9a-f]{40}$/', $attributes['eduPersonTargetedID'][0]); // } // // // /** // * Test with src and dst entityIds. // * Make sure to overwrite any present eduPersonTargetedId // * @return void // */ // public function testWithSrcDst() // { // $config = []; // $request = [ // 'Attributes' => [ // 'eduPersonTargetedID' => 'dummy', // ], // 'UserID' => 'user2@example.org', // 'Source' => [ // 'metadata-set' => 'saml20-idp-hosted', // 'entityid' => 'urn:example:src:id', // ], // 'Destination' => [ // 'metadata-set' => 'saml20-sp-remote', // 'entityid' => 'joe', // ], // ]; // $result = self::processFilter($config, $request); // $attributes = $result['Attributes']; // $this->assertArrayHasKey('eduPersonTargetedID', $attributes); // $this->assertRegExp('/^[0-9a-f]{40}$/', $attributes['eduPersonTargetedID'][0]); // } // // // /** // * Test with nameId config option set. // * @return void // */ // public function testNameIdGeneration() // { // $config = [ // 'nameId' => true, // ]; // $request = array( // 'Attributes' => [], // 'UserID' => 'user2@example.org', // 'Source' => [ // 'metadata-set' => 'saml20-idp-hosted', // 'entityid' => 'urn:example:src:id', // ], // 'Destination' => [ // 'metadata-set' => 'saml20-sp-remote', // 'entityid' => 'joe', // ], // ); // $result = self::processFilter($config, $request); // $attributes = $result['Attributes']; // $this->assertArrayHasKey('eduPersonTargetedID', $attributes); // $this->assertRegExp( // '#^[0-9a-f]{40}$#', // $attributes['eduPersonTargetedID'][0] // ); // } // // // /** // * Test that Id is the same for subsequent invocations with same input. // * @return void // */ // public function testIdIsPersistent() // { // $config = []; // $request = [ // 'Attributes' => [ // 'eduPersonTargetedID' => 'dummy', // ], // 'UserID' => 'user2@example.org', // 'Source' => [ // 'metadata-set' => 'saml20-idp-hosted', // 'entityid' => 'urn:example:src:id', // ], // 'Destination' => [ // 'metadata-set' => 'saml20-sp-remote', // 'entityid' => 'joe', // ], // ]; // for ($i = 0; $i < 10; ++$i) { // $result = self::processFilter($config, $request); // $attributes = $result['Attributes']; // $tid = $attributes['eduPersonTargetedID'][0]; // if (isset($prevtid)) { // $this->assertEquals($prevtid, $tid); // $prevtid = $tid; // } // } // } // // // /** // * Test that Id is different for two different usernames and two different sp's // * @return void // */ // public function testIdIsUnique() // { // $config = []; // $request = [ // 'Attributes' => [], // 'UserID' => 'user2@example.org', // 'Source' => [ // 'metadata-set' => 'saml20-idp-hosted', // 'entityid' => 'urn:example:src:id', // ], // 'Destination' => [ // 'metadata-set' => 'saml20-sp-remote', // 'entityid' => 'joe', // ], // ]; // $result = self::processFilter($config, $request); // $tid1 = $result['Attributes']['eduPersonTargetedID'][0]; // // $request['UserID'] = 'user3@example.org'; // $result = self::processFilter($config, $request); // $tid2 = $result['Attributes']['eduPersonTargetedID'][0]; // // $this->assertNotEquals($tid1, $tid2); // // $request['Destination']['entityid'] = 'urn:example.org:another-sp'; // $result = self::processFilter($config, $request); // $tid3 = $result['Attributes']['eduPersonTargetedID'][0]; // // $this->assertNotEquals($tid2, $tid3); // } /** * Test no userid set * @return void */ public function testNoUserID(): void { $this->expectException(Exception::class); $config = []; $request = [ 'Attributes' => [], ]; self::processFilter($config, $request); } /** * Test with specified attribute not set * @return void */ public function testAttributeNotExists(): void { $this->expectException(Exception::class); $config = [ 'attributename' => 'uid', ]; $request = [ 'Attributes' => [ 'displayName' => 'Jack Student', ], ]; self::processFilter($config, $request); } /** * Test with configuration error 1 * @return void */ public function testConfigInvalidAttributeName(): void { $this->expectException(Exception::class); $config = [ 'attributename' => 5, ]; $request = [ 'Attributes' => [ 'displayName' => 'Jack Student', ], ]; self::processFilter($config, $request); } /** * Test with configuration error 2 * @return void */ public function testConfigInvalidNameId(): void { $this->expectException(Exception::class); $config = [ 'nameId' => 'persistent', ]; $request = [ 'Attributes' => [ 'displayName' => 'Jack Student', ], ]; self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeAlterTest.php0000644000000000000000000002231514042503475026321 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'subject' => 'test', 'pattern' => '/wrong/', 'replacement' => 'right', ]; $request = [ 'Attributes' => [ 'test' => ['somethingiswrong'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertEquals($attributes['test'], ['somethingisright']); } /** * Test the most basic functionality. * @return void */ public function testWithTarget(): void { $config = [ 'subject' => 'test', 'target' => 'test2', 'pattern' => '/wrong/', 'replacement' => 'right', ]; $request = [ 'Attributes' => [ 'something' => ['somethingelse'], 'test' => ['wrong'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test2', $attributes); $this->assertEquals($attributes['test'], ['wrong']); $this->assertEquals($attributes['test2'], ['right']); } /** * Module is a no op if subject attribute is not present. * @return void */ public function testNomatch(): void { $config = [ 'subject' => 'test', 'pattern' => '/wrong/', 'replacement' => 'right', ]; $request = [ 'Attributes' => [ 'something' => ['somevalue'], 'somethingelse' => ['someothervalue'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals( $attributes, ['something' => ['somevalue'], 'somethingelse' => ['someothervalue']] ); } /** * Test replacing attribute value. * @return void */ public function testReplaceMatch(): void { $config = [ 'subject' => 'source', 'pattern' => '/wrong/', 'replacement' => 'right', '%replace', ]; $request = [ 'Attributes' => [ 'source' => ['wrongthing'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['source'], ['right']); } /** * Test replacing attribute value. * @return void */ public function testReplaceMatchWithTarget(): void { $config = [ 'subject' => 'source', 'pattern' => '/wrong/', 'replacement' => 'right', 'target' => 'test', '%replace', ]; $request = [ 'Attributes' => [ 'source' => ['wrong'], 'test' => ['wrong'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['test'], ['right']); } /** * Test replacing attribute values. * @return void */ public function testReplaceNoMatch(): void { $config = [ 'subject' => 'test', 'pattern' => '/doink/', 'replacement' => 'wrong', 'target' => 'test', '%replace', ]; $request = [ 'Attributes' => [ 'source' => ['wrong'], 'test' => ['right'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['test'], ['right']); } /** * Test removing attribute values. * Note that removing a value does not renumber the attributes array. * Also ensure unrelated attributes are not touched. * @return void */ public function testRemoveMatch(): void { $config = [ 'subject' => 'eduPersonAffiliation', 'pattern' => '/^emper/', '%remove', ]; $request = [ 'Attributes' => [ 'displayName' => ['emperor kuzco'], 'eduPersonAffiliation' => ['member', 'emperor', 'staff'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['displayName'], ['emperor kuzco']); $this->assertEquals($attributes['eduPersonAffiliation'], [0 => 'member', 2 => 'staff']); } /** * Test removing attribute values, resulting in an empty attribute. * @return void */ public function testRemoveMatchAll(): void { $config = [ 'subject' => 'eduPersonAffiliation', 'pattern' => '/^emper/', '%remove', ]; $request = [ 'Attributes' => [ 'displayName' => ['emperor kuzco'], 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); } /** * Test for exception with illegal config. * @return void */ public function testWrongConfig(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'eduPersonAffiliation', 'pattern' => '/^emper/', '%dwiw', ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; self::processFilter($config, $request); } /** * Test for exception with illegal config. * @return void */ public function testIncompleteConfig(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'eduPersonAffiliation', ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; self::processFilter($config, $request); } /** * Test for exception with illegal config. * @return void */ public function testIncompleteConfig2(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'test', 'pattern' => '/wrong/', ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; self::processFilter($config, $request); } /** * Test for exception with illegal config. * @return void */ public function testIncompleteConfig3(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'test', 'pattern' => '/wrong/', '%replace', '%remove', ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; self::processFilter($config, $request); } /** * Test for exception with illegal config. * @return void */ public function testIncompleteConfig4(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'test', 'pattern' => '/wrong/', 'target' => 'test2', '%remove', ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; self::processFilter($config, $request); } /** * Test for exception with illegal config. * @return void */ public function testIncompleteConfig5(): void { $this->expectException(Exception::class); $config = [ 'subject' => 'test', 'pattern' => '/wrong/', 'replacement' => null, ]; $request = [ 'Attributes' => [ 'eduPersonAffiliation' => ['emperess', 'emperor'], ], ]; $result = self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeCopyTest.php0000644000000000000000000001152414042503475026164 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'test' => 'testnew', ]; $request = [ 'Attributes' => ['test' => ['AAP']], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertArrayHasKey('testnew', $attributes); $this->assertEquals($attributes['testnew'], ['AAP']); } /** * Test the most basic functionality. * @return void */ public function testArray(): void { $config = [ 'test' => ['new1', 'new2'], ]; $request = [ 'Attributes' => ['test' => ['AAP']], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertArrayHasKey('new1', $attributes); $this->assertArrayHasKey('new2', $attributes); $this->assertEquals($attributes['new1'], ['AAP']); $this->assertEquals($attributes['new2'], ['AAP']); } /** * Test that existing attributes are left unmodified. * @return void */ public function testExistingNotModified(): void { $config = [ 'test' => 'testnew', ]; $request = [ 'Attributes' => [ 'test' => ['AAP'], 'original1' => ['original_value1'], 'original2' => ['original_value2'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('testnew', $attributes); $this->assertEquals($attributes['test'], ['AAP']); $this->assertArrayHasKey('original1', $attributes); $this->assertEquals($attributes['original1'], ['original_value1']); $this->assertArrayHasKey('original2', $attributes); $this->assertEquals($attributes['original2'], ['original_value2']); } /** * Test copying multiple attributes * @return void */ public function testCopyMultiple(): void { $config = [ 'test1' => 'new1', 'test2' => 'new2', ]; $request = [ 'Attributes' => ['test1' => ['val1'], 'test2' => ['val2.1', 'val2.2']], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('new1', $attributes); $this->assertEquals($attributes['new1'], ['val1']); $this->assertArrayHasKey('new2', $attributes); $this->assertEquals($attributes['new2'], ['val2.1', 'val2.2']); } /** * Test behaviour when target attribute exists (should be replaced). * @return void */ public function testCopyClash(): void { $config = [ 'test' => 'new1', ]; $request = [ 'Attributes' => [ 'test' => ['testvalue1'], 'new1' => ['newvalue1'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['new1'], ['testvalue1']); } /** * Test wrong attribute name * @return void */ public function testWrongAttributeName(): void { $this->expectException(Exception::class); $config = [ ['value2'], ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; self::processFilter($config, $request); } /** * Test wrong attribute value * @return void */ public function testWrongAttributeValue(): void { $this->expectException(Exception::class); $config = [ 'test' => 100, ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeAddTest.php0000644000000000000000000001205514042503475025742 0ustar rootrootprocess($request); return $request; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'test' => ['value1', 'value2'], ]; $request = [ 'Attributes' => [], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertEquals($attributes['test'], ['value1', 'value2']); } /** * Test that existing attributes are left unmodified. * @return void */ public function testExistingNotModified(): void { $config = [ 'test' => ['value1', 'value2'], ]; $request = [ 'Attributes' => [ 'original1' => ['original_value1'], 'original2' => ['original_value2'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertEquals($attributes['test'], ['value1', 'value2']); $this->assertArrayHasKey('original1', $attributes); $this->assertEquals($attributes['original1'], ['original_value1']); $this->assertArrayHasKey('original2', $attributes); $this->assertEquals($attributes['original2'], ['original_value2']); } /** * Test single string as attribute value. * @return void */ public function testStringValue(): void { $config = [ 'test' => 'value', ]; $request = [ 'Attributes' => [], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test', $attributes); $this->assertEquals($attributes['test'], ['value']); } /** * Test adding multiple attributes in one config. * @return void */ public function testAddMultiple(): void { $config = [ 'test1' => ['value1'], 'test2' => ['value2'], ]; $request = [ 'Attributes' => [], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('test1', $attributes); $this->assertEquals($attributes['test1'], ['value1']); $this->assertArrayHasKey('test2', $attributes); $this->assertEquals($attributes['test2'], ['value2']); } /** * Test behavior when appending attribute values. * @return void */ public function testAppend(): void { $config = [ 'test' => ['value2'], ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['test'], ['value1', 'value2']); } /** * Test replacing attribute values. * @return void */ public function testReplace(): void { $config = [ '%replace', 'test' => ['value2'], ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertEquals($attributes['test'], ['value2']); } /** * Test wrong usage generates exceptions * @return void */ public function testWrongFlag(): void { $this->expectException(Exception::class); $config = [ '%nonsense', 'test' => ['value2'], ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; self::processFilter($config, $request); } /** * Test wrong attribute value * @return void */ public function testWrongAttributeValue(): void { $this->expectException(Exception::class); $config = [ '%replace', 'test' => [true], ]; $request = [ 'Attributes' => [ 'test' => ['value1'], ], ]; self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/AttributeLimitTest.php0000644000000000000000000004027314042503475026333 0ustar rootrootprocess($request); return $request; } /** * Test reading IdP Attributes. * @return void */ public function testIdPAttrs(): void { $config = [ 'cn', 'mail' ]; $request = [ 'Attributes' => [ 'eduPersonTargetedID' => ['eptid@example.org'], 'eduPersonAffiliation' => ['member'], 'cn' => ['user name'], 'mail' => ['user@example.org'], ], 'Destination' => [ ], 'Source' => [ 'attributes' => ['cn', 'mail'], ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertArrayNotHasKey('eduPersonTargetedID', $attributes); $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); $this->assertCount(2, $attributes); $config = [ 'cn', 'default' => true, ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertArrayNotHasKey('eduPersonTargetedID', $attributes); $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); $this->assertCount(2, $attributes); } /** * Tests when no attributes are in metadata. * @return void */ public function testNULLMetadataAttrs(): void { $config = [ 'cn', 'mail' ]; $request = [ 'Attributes' => [ 'eduPersonTargetedID' => ['eptid@example.org'], 'eduPersonAffiliation' => ['member'], 'cn' => ['user name'], 'mail' => ['user@example.org'], ], 'Destination' => [ ], 'Source' => [ ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertArrayNotHasKey('eduPersonTargetedID', $attributes); $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); $this->assertCount(2, $attributes); $config = [ 'cn', 'default' => true, ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayNotHasKey('mail', $attributes); $this->assertArrayNotHasKey('eduPersonTargetedID', $attributes); $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); $this->assertCount(1, $attributes); $config = [ ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertCount(4, $attributes); $this->assertArrayHasKey('eduPersonTargetedID', $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); } /** * @return void */ public static function setUpBeforeClass() { self::$request = [ 'Attributes' => [ 'eduPersonTargetedID' => ['eptid@example.org'], 'eduPersonAffiliation' => ['member'], 'cn' => ['common name'], 'mail' => ['user@example.org'], ], 'Destination' => [ 'attributes' => ['cn', 'mail'], ], 'Source' => [ ], ]; } /** * Test the most basic functionality. * @return void */ public function testBasic(): void { $config = [ 'cn', 'mail' ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertCount(2, $attributes); } /** * Test defaults with metadata available. * @return void */ public function testDefaultWithMetadata(): void { $config = [ 'default' => true, ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertCount(2, $attributes); } /** * Test defaults with attributes and metadata * @return void */ public function testDefaultWithAttrs(): void { $config = [ 'default' => true, 'eduPersonTargetedID', 'eduPersonAffiliation', ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(2, $attributes); $this->assertArrayHasKey('cn', $attributes); $this->assertArrayHasKey('mail', $attributes); $this->assertArrayNotHasKey('eduPersonTargetedID', $attributes); $this->assertArrayNotHasKey('eduPersonAffiliation', $attributes); } /** * Test for exception with illegal config. * @return void */ public function testInvalidConfig(): void { $this->expectException(Exception::class); $config = [ 'invalidArg' => true, ]; self::processFilter($config, self::$request); } /** * Test for invalid attribute name * @return void */ public function testInvalidAttributeName(): void { $this->expectException(Exception::class); $config = [ null ]; self::processFilter($config, self::$request); } /** * Test for attribute value matching * @return void */ public function testMatchAttributeValues(): void { $config = [ 'eduPersonAffiliation' => ['member'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); $config = [ 'eduPersonAffiliation' => ['member', 'staff'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); $config = [ 'eduPersonAffiliation' => ['student'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); $config = [ 'eduPersonAffiliation' => ['student', 'staff'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); } /** * @return void */ public function testBadOptionsNotTreatedAsValidValues(): void { // Ensure really misconfigured ignoreCase and regex options are not interpretted as valid valus $config = [ 'eduPersonAffiliation' => ['ignoreCase' => 'member', 'nomatch'], 'mail' => ['regex' => 'user@example.org', 'nomatch'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); } /** * Verify that the true value for ignoreCase doesn't get converted into a string ('1') by * php and matched against an attribute value of '1' * @return void */ public function testThatIgnoreCaseOptionNotMatchBooleanAsStringValue(): void { $config = [ 'someAttribute' => ['ignoreCase' => true, 'someValue'] ]; $request = [ 'Attributes' => [ 'someAttribute' => ['1'], //boolean true as a string ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); } /** * Test for attribute value matching ignore case * @return void */ public function testMatchAttributeValuesIgnoreCase(): void { $config = [ 'eduPersonAffiliation' => ['ignoreCase' => true, 'meMber'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); $config = [ 'eduPersonAffiliation' => ['ignoreCase' => true, 'membeR', 'sTaff'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonAffiliation', $attributes); $this->assertEquals($attributes['eduPersonAffiliation'], ['member']); $config = [ 'eduPersonAffiliation' => ['ignoreCase' => true, 'Student'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); $config = [ 'eduPersonAffiliation' => ['ignoreCase' => true, 'studeNt', 'sTaff'] ]; $result = self::processFilter($config, self::$request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); } /** * Test for attribute value matching * @return void */ public function testMatchAttributeValuesRegex(): void { // SSP Logger requires a configuration to be set. Configuration::loadFromArray([], '[ARRAY]', 'simplesaml'); $state = self::$request; $state['Attributes']['eduPersonEntitlement'] = [ 'urn:mace:example.terena.org:tcs:personal-user', 'urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100', '1' //boolean true as a string ]; $config = [ 'eduPersonEntitlement' => [ 'regex' => true, '/^urn:x-surfnet:surf/' ] ]; $result = self::processFilter($config, $state); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonEntitlement', $attributes); $this->assertEquals( ['urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'], $attributes['eduPersonEntitlement'] ); // Matching multiple lines shouldn't duplicate the attribute $config = [ 'eduPersonEntitlement' => [ 'regex' => true, '/urn:x-surfnet:surf/', '/urn:x-surfnet/' ] ]; $result = self::processFilter($config, $state); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonEntitlement', $attributes); $this->assertEquals( ['urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'], $attributes['eduPersonEntitlement'] ); // Invalid and no-match regex expressions should not stop a valid regex from matching $config = [ 'eduPersonEntitlement' => [ 'regex' => true, '/urn:mace:example.terena.org:tcs:no-match/', '$invalidRegex[', '/^URN:x-surf.*SURF.*n$/i' ] ]; $result = self::processFilter($config, $state); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonEntitlement', $attributes); $this->assertEquals( ['urn:x-surfnet:surfdomeinen.nl:role:dnsadmin'], $attributes['eduPersonEntitlement'] ); // No matches should remove attribute $config = [ 'eduPersonEntitlement' => [ 'regex' => true, '/urn:x-no-match/' ] ]; $result = self::processFilter($config, $state); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); // A regex that matches an input value multiple times should work. $config = [ 'eduPersonEntitlement' => [ 'regex' => true, '/surf/' ] ]; $result = self::processFilter($config, $state); $attributes = $result['Attributes']; $this->assertCount(1, $attributes); $this->assertArrayHasKey('eduPersonEntitlement', $attributes); $this->assertEquals( ['urn:x-surfnet:surfdomeinen.nl:role:dnsadmin', 'urn:x-surfnet:surf.nl:surfdrive:quota:100'], $attributes['eduPersonEntitlement'] ); } /** * Test for allowed attributes not an array. * * This test is very unlikely and would require malformed metadata processing. * Cannot be generated via config options. * @return void */ public function testMatchAttributeValuesNotArray(): void { $this->expectException(Exception::class); $config = [ ]; $request = [ 'Attributes' => [ 'eduPersonTargetedID' => ['eptid@example.org'], 'eduPersonAffiliation' => ['member'], 'cn' => ['user name'], 'mail' => ['user@example.org'], 'discardme' => ['somethingiswrong'], ], 'Destination' => [ 'attributes' => ['eduPersonAffiliation' => 'student'], ], 'Source' => [ ], ]; self::processFilter($config, $request); } /** * Test attributes not intersecting * @return void */ public function testNoIntersection(): void { $config = [ 'default' => true, ]; $request = [ 'Attributes' => [ 'eduPersonTargetedID' => ['eptid@example.org'], 'eduPersonAffiliation' => ['member'], 'cn' => ['user name'], 'mail' => ['user@example.org'], 'discardme' => ['somethingiswrong'], ], 'Destination' => [ 'attributes' => ['urn:oid:1.2.840.113549.1.9.1'], ], 'Source' => [ ], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertCount(0, $attributes); $this->assertEmpty($attributes); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/PairwiseIDTest.php0000644000000000000000000002353014042503475025366 0ustar rootrootsetConfigUtils(self::$configUtils); $filter->setLogger(self::$logger); $filter->process($request); return $request; } /** * Test the most basic functionality */ public function testBasic(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex-ample.org']; $request = [ 'Attributes' => ['uid' => ['u=se-r2']], 'core:SP' => 'urn:sp', ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $this->assertRegExp( PairwiseID::SPEC_PATTERN, $attributes[Constants::ATTR_PAIRWISE_ID][0] ); $this->assertEquals( '53d4f7fe57fb597ada481e81e0f15048bc610774cbb5614ea38f08ea918ba199@ex-ample.org', $attributes[Constants::ATTR_PAIRWISE_ID][0] ); } /** * Test the most basic functionality on proxied request */ public function testBasicProxiedRequest(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex-ample.org']; $request = [ 'Attributes' => ['uid' => ['u=se-r2']], 'saml:RequesterID' => [0 => 'urn:sp'], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $this->assertRegExp( PairwiseID::SPEC_PATTERN, $attributes[Constants::ATTR_PAIRWISE_ID][0] ); $this->assertEquals( '53d4f7fe57fb597ada481e81e0f15048bc610774cbb5614ea38f08ea918ba199@ex-ample.org', $attributes[Constants::ATTR_PAIRWISE_ID][0] ); } /** * Test the proxied request with multiple hops */ public function testProxiedRequestMultipleHops(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex-ample.org']; $request = [ 'Attributes' => ['uid' => ['u=se-r2']], 'saml:RequesterID' => [0 => 'urn:sp', 1 => 'urn:some:sp', 2 => 'urn:some:other:sp'], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $this->assertRegExp( PairwiseID::SPEC_PATTERN, $attributes[Constants::ATTR_PAIRWISE_ID][0] ); $this->assertEquals( '53d4f7fe57fb597ada481e81e0f15048bc610774cbb5614ea38f08ea918ba199@ex-ample.org', $attributes[Constants::ATTR_PAIRWISE_ID][0] ); } /** * Test that illegal characters in scope throws an exception. */ public function testScopeIllegalCharacterThrowsException(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex%ample.org']; $request = [ 'Attributes' => ['uid' => ['user2']], 'core:SP' => 'urn:sp', ]; $this->expectException(AssertionFailedException::class); self::processFilter($config, $request); } /** * Test that generated ID's for the same user, but different SP's are NOT equal */ public function testUniqueIdentifierPerSPSameUser(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], 'core:SP' => 'urn:sp', ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value1 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; // Switch SP $request['core:SP'] = 'urn:some:other:sp'; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value2 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; $this->assertNotSame($value1, $value2); } /** * Test that generated ID's for different users, but the same SP's are NOT equal */ public function testUniqueIdentifierPerUserSameSP(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], 'core:SP' => 'urn:sp', ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value1 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; // Switch user $request['Attributes'] = ['uid' => ['user2']]; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value2 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; $this->assertNotSame($value1, $value2); } /** * Test that generated ID's for the same user and same SP, but with a different salt are NOT equal */ public function testUniqueIdentifierDifferentSalts(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], 'core:SP' => 'urn:sp', ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value1 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; // Change the salt self::$configUtils = new class () extends Utils\Config { public static function getSecretSalt() { // stub return 'pepper'; } }; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value2 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; $this->assertNotSame($value1, $value2); } /** * Test that generated ID's for the same user and same SP, but with a different scope are NOT equal */ public function testUniqueIdentifierDifferentScopes(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], 'core:SP' => 'urn:sp', ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value1 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; // Change the scope $config['scope'] = 'example.edu'; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_PAIRWISE_ID, $attributes); $value2 = $attributes[Constants::ATTR_PAIRWISE_ID][0]; $this->assertNotSame($value1, $value2); $this->assertRegExp( '/@example.org$/i', $value1 ); $this->assertRegExp( '/@example.edu$/i', $value2 ); } /** * Test that weak identifiers log a warning */ public function testWeakIdentifierLogsWarning(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'b']; $request = [ 'Attributes' => ['uid' => ['a']], 'core:SP' => 'urn:sp', ]; $this->expectException(RuntimeException::class); $this->expectExceptionMessage( 'core:PairwiseID: Generated ID \'c5b54935db5e291a6b94688921fa77ced8ce425ce8c61a448bd4997f494dbebe@b\' can hardly be considered globally unique.' ); self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/Process/SubjectIDTest.php0000644000000000000000000001321514042503475025201 0ustar rootrootsetLogger(self::$logger); $filter->process($request); return $request; } /** * Test the most basic functionality */ public function testBasic(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex-ample.org']; $request = [ 'Attributes' => ['uid' => ['u=se-r2']], ]; $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_SUBJECT_ID, $attributes); $this->assertRegExp( SubjectID::SPEC_PATTERN, $attributes[Constants::ATTR_SUBJECT_ID][0] ); $this->assertEquals('u=se-r2@ex-ample.org', $attributes[Constants::ATTR_SUBJECT_ID][0]); } /** * Test that illegal characters in userID throws an exception. */ public function testUserIDIllegalCharacterThrowsException(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['u=se+r2']], ]; $this->expectException(AssertionFailedException::class); self::processFilter($config, $request); } /** * Test that illegal characters in scope throws an exception. */ public function testScopeIllegalCharacterThrowsException(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'ex%ample.org']; $request = [ 'Attributes' => ['uid' => ['user2']], ]; $this->expectException(AssertionFailedException::class); self::processFilter($config, $request); } /** * Test that generated ID's for different users, but the same SP's are NOT equal */ public function testUniqueIdentifierPerUserSameSP(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_SUBJECT_ID, $attributes); $value1 = $attributes[Constants::ATTR_SUBJECT_ID][0]; // Switch user $request['Attributes'] = ['uid' => ['user2']]; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_SUBJECT_ID, $attributes); $value2 = $attributes[Constants::ATTR_SUBJECT_ID][0]; $this->assertNotSame($value1, $value2); } /** * Test that generated ID's for the same user and same SP, but with a different scope are NOT equal */ public function testUniqueIdentifierDifferentScopes(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'example.org']; $request = [ 'Attributes' => ['uid' => ['user1']], ]; // Generate first ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_SUBJECT_ID, $attributes); $value1 = $attributes[Constants::ATTR_SUBJECT_ID][0]; // Change the scope $config['scope'] = 'example.edu'; // Generate second ID $result = self::processFilter($config, $request); $attributes = $result['Attributes']; $this->assertArrayHasKey(Constants::ATTR_SUBJECT_ID, $attributes); $value2 = $attributes[Constants::ATTR_SUBJECT_ID][0]; $this->assertNotSame($value1, $value2); $this->assertRegExp( '/@example.org$/i', $value1 ); $this->assertRegExp( '/@example.edu$/i', $value2 ); } /** * Test that weak identifiers log a warning */ public function testWeakIdentifierLogsWarning(): void { $config = ['identifyingAttribute' => 'uid', 'scope' => 'b']; $request = [ 'Attributes' => ['uid' => ['a']], ]; $this->expectException(RuntimeException::class); $this->expectExceptionMessage('core:SubjectID: Generated ID \'a@b\' can hardly be considered globally unique.'); self::processFilter($config, $request); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/UserPassBaseTest.php0000644000000000000000000000641414042503475024312 0ustar rootroot Constants::BINDING_PAOS, ]; $attributes = ['attrib' => 'val']; $username = $_SERVER['PHP_AUTH_USER'] = 'username'; $password = $_SERVER['PHP_AUTH_PW'] = 'password'; $stub = $this->getMockBuilder(UserPassBase::class) ->disableOriginalConstructor() ->setMethods(['login']) ->getMockForAbstractClass(); /** @var \SimpleSAML\Module\core\Auth\UserPassBase $stub */ $stub->expects($this->once()) ->method('login') ->with($username, $password) ->will($this->returnValue($attributes)); $stub->authenticate($state); $this->assertSame($attributes, $state['Attributes']); } /** * @return void */ public function testAuthenticateECPMissingUsername(): void { $this->expectException(SspError::class); $this->expectExceptionMessage('WRONGUSERPASS'); $state = [ 'saml:Binding' => Constants::BINDING_PAOS, ]; unset($_SERVER['PHP_AUTH_USER']); $_SERVER['PHP_AUTH_PW'] = 'password'; /** @var \SimpleSAML\Module\core\Auth\UserPassBase $stub */ $stub = $this->getMockBuilder(UserPassBase::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $stub->authenticate($state); } /** * @return void */ public function testAuthenticateECPMissingPassword(): void { $this->expectException(SspError::class); $this->expectExceptionMessage('WRONGUSERPASS'); $state = [ 'saml:Binding' => Constants::BINDING_PAOS, ]; $_SERVER['PHP_AUTH_USER'] = 'username'; unset($_SERVER['PHP_AUTH_PW']); $stub = $this->getMockBuilder(UserPassBase::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); /** @psalm-suppress UndefinedMethod Remove when Psalm 3.x is in place */ $stub->authenticate($state); } /** * @return void */ public function testAuthenticateECPCallsLoginWithForcedUsername(): void { $state = [ 'saml:Binding' => Constants::BINDING_PAOS, ]; $attributes = []; $forcedUsername = 'forcedUsername'; $_SERVER['PHP_AUTH_USER'] = 'username'; $password = $_SERVER['PHP_AUTH_PW'] = 'password'; $stub = $this->getMockBuilder(UserPassBase::class) ->disableOriginalConstructor() ->setMethods(['login']) ->getMockForAbstractClass(); /** @var \SimpleSAML\Module\core\Auth\UserPassBase $stub */ $stub->expects($this->once()) ->method('login') ->with($forcedUsername, $password) ->will($this->returnValue($attributes)); $stub->setForcedUsername($forcedUsername); $stub->authenticate($state); } } simplesamlphp-1.19.1/tests/modules/core/lib/Auth/UserPassOrgBaseTest.php0000644000000000000000000000254314042503475024761 0ustar rootroot true, 'remember.organization.checked' => false, 'my-org' => [ 'description' => 'My organization', // The rest of the options are the same as those available for // the LDAP authentication source. 'hostname' => 'ldap://ldap.myorg.com', 'dnpattern' => 'uid=%username%,ou=employees,dc=example,dc=org', // Whether SSL/TLS should be used when contacting the LDAP server. 'enable_tls' => false, ] ]; /** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase $mockUserPassOrgBase */ $mockUserPassOrgBase = $this->getMockBuilder(\SimpleSAML\Module\core\Auth\UserPassOrgBase::class) ->setConstructorArgs([['AuthId' => 'my-org'], &$config]) ->setMethods([]) ->getMockForAbstractClass(); $this->assertTrue($mockUserPassOrgBase->getRememberOrganizationEnabled()); } } simplesamlphp-1.19.1/tests/bootstrap.php0000644000000000000000000000037614042503475017061 0ustar rootroot $urn) { $lower = str_replace([':', '-'], '_', strtolower($name)); if (!array_key_exists('attribute_' . $lower, $defs)) { $defs['attribute_' . $lower] = []; } if (!array_key_exists('attribute_' . $lower, $trans)) { $trans['attribute_' . $lower] = []; } if (array_key_exists('no', $trans['attribute_' . $lower])) { // fix the locale code $trans['attribute_' . $lower]['nb'] = $trans['attribute_' . $lower]['no']; unset($trans['attribute_' . $lower]['no']); } $names = [$name, $urn, $urns[$urn]]; if (array_key_exists($urn, $schac)) { $names[] = $schac[$urn]; } $attributes[$name] = [ 'names' => $names, 'translations' => array_merge( [ 'en' => $defs['attribute_' . $lower]['en'], ], $trans['attribute_' . $lower] ), ]; } // process other sets of attributes foreach (['facebook', 'linkedin', 'openid', 'twitter', 'windowslive'] as $set) { include_once($base . 'attributemap/' . $set . '2name.php'); foreach ($attributemap as $alias => $attr) { if (array_key_exists($attr, $attributes)) { $attributes[$attr]['names'][] = $alias; } } } // build the dictionaries per language foreach (array_keys($languages) as $language) { $strings = new Gettext\Translations(); // load existing translations in the PO files $strings->addFromPoFile($base . 'locales/' . $language . "/LC_MESSAGES/attributes.po"); foreach ($attributes as $attribute) { foreach ($attribute['names'] as $name) { if (empty($name)) { continue; } $translation = new Gettext\Translation('', $name); if ( array_key_exists($language, $attribute['translations']) && !is_null($attribute['translations'][$language]) ) { $t = $strings->find($translation); if ($t) { if ($t->getOriginal() === $t->getTranslation()) { $t->setTranslation($attribute['translations'][$language]); $translation = $t; } } } if (!is_null($attribute['translations']['en']) && $language !== 'en') { $translation->addComment('English string: ' . $attribute['translations']['en']); } $strings[] = $translation; } } foreach ($strings as $entry) { if ($entry->getTranslation() === '') { // ensure that all entries contain a translation string $entry->setTranslation($entry->getOriginal()); } } // remove headers that only cause unnecessary changes in our commits $strings->deleteHeader('POT-Creation-Date'); $strings->deleteHeader('PO-Revision-Date'); $strings->setLanguage($language); echo "Saving translations to " . $base . "locales/" . $language . "/LC_MESSAGES/attributes.po\n"; Gettext\Generators\Po::toFile($strings, $base . 'locales/' . $language . '/LC_MESSAGES/attributes.po'); } simplesamlphp-1.19.1/bin/memcacheSync.php0000755000000000000000000001120414042503475017044 0ustar rootroot#!/usr/bin/env php $state) { if ($state === false) { echo "WARNING: Server " . $server . " is down.\n"; $warnServerDown++; continue; } $items = $state['curr_items']; echo "Server " . $server . " has " . $items . " items.\n"; $serverKeys = getServerKeys($server); $keys = array_merge($keys, $serverKeys); } } echo "Total number of keys: " . count($keys) . "\n"; $keys = array_unique($keys); echo "Total number of unique keys: " . count($keys) . "\n"; echo "Starting synchronization.\n" ; $skipped = 0; $sync = 0; foreach ($keys as $key) { $res = \SimpleSAML\Memcache::get($key); if ($res === null) { $skipped += 1; } else { $sync += 1; } } echo "Synchronization done.\n"; echo $sync . " keys in sync.\n"; if ($skipped > 0) { echo $skipped . " keys skipped.\n"; echo "Keys are skipped because they are either expired, or are of a type unknown\n"; echo "to SimpleSAMLphp.\n"; } if ($warnServerDown > 0) { echo "WARNING: " . $warnServerDown . " server(s) down. Not all servers are synchronized.\n"; } if ($warnBigSlab > 0) { echo "WARNING: " . $warnBigSlab . " slab(s) may have contained more keys than we were told about.\n"; } /** * Fetch all keys available in an server. * * @param string $server The server, as a string with :. * * @return array An array with all the keys available on the server. */ function getServerKeys(string $server): array { $server = explode(':', $server); $host = $server[0]; $port = (int) $server[1]; echo "Connecting to: " . $host . ":" . $port . "\n"; $socket = fsockopen($host, $port); echo "Connected. Finding keys.\n"; if (fwrite($socket, "stats slabs\r\n") === false) { echo "Error requesting slab dump from server.\n"; exit(1); } // Read list of slabs $slabs = []; while (($line = fgets($socket)) !== false) { $line = rtrim($line); if ($line === 'END') { break; } if (preg_match('/^STAT (\d+):/', $line, $matches)) { $slab = (int) $matches[1]; if (!in_array($slab, $slabs, true)) { $slabs[] = $slab; } } } // Dump keys in slabs $keys = []; foreach ($slabs as $slab) { if (fwrite($socket, "stats cachedump " . $slab . " 1000000\r\n") === false) { echo "Error requesting cache dump from server.\n"; exit(1); } /* We keep track of the result size, to be able to warn the user if it is * so big that keys may have been lost. */ $resultSize = 0; while (($line = fgets($socket)) !== false) { $resultSize += strlen($line); $line = rtrim($line); if ($line === 'END') { break; } if (preg_match('/^ITEM (.*) \[\d+ b; \d+ s\]/', $line, $matches)) { $keys[] = $matches[1]; } else { echo "Unknown result from cache dump: " . $line . "\n"; } } if ($resultSize > 1900000 || count($keys) >= 1000000) { echo "WARNING: Slab " . $slab . " on server " . $host . ":" . $port . " may have contained more keys than we were told about.\n"; $GLOBALS['warnBigSlab'] += 1; } } echo "Found " . count($keys) . " key(s).\n"; fclose($socket); return $keys; } simplesamlphp-1.19.1/bin/initMDSPdo.php0000755000000000000000000000200314042503475016414 0ustar rootroot#!/usr/bin/env php initDatabase(); if ($result === false) { echo "Failed to initialize metadata database." . PHP_EOL; } else { echo "Successfully initialized metadata database." . PHP_EOL; } } } simplesamlphp-1.19.1/bin/ldapattrschemaparser.pl0000755000000000000000000000433214042503475020506 0ustar rootroot#!/usr/bin/env perl use strict; use warnings; my @valid_formats = ( 'simple', 'oid2name', 'oid2urn', 'name2oid', 'name2urn', 'urn2oid', 'urn2name', ); my $format = shift; unless (defined($format)) { print(STDERR "Usage: simpleparser.pl FORMAT \n"); print(STDERR "Valid formats: ", join(' ', @valid_formats), "\n"); exit(1); } unless (grep { $_ eq $format } @valid_formats) { print(STDERR "Invalid format: $format\n"); print(STDERR "Valid formats: ", join(' ', @valid_formats), "\n"); exit(1); } # Load file my $text = join('', <>); # Strip comments $text =~ s/#.*$//gm; my %oids; my %names; while ($text =~ m"attributetype\s*\(\s*([\d.]+).*?NAME\s+(?:'(.*?)'|(\(.*?\)))"sg) { my $oid = $1; my @attributes; if (defined($2)) { # Single attribute @attributes = ($2); } else { # Multiple attributes my $input = $3; while ($input =~ m"'(.*?)'"gs) { push(@attributes, $1); } } foreach my $attrname (@attributes) { $names{$attrname} = $oid; } $oids{$oid} = [ @attributes ]; } if ($format eq 'simple') { foreach my $oid (sort keys %oids) { my @names = @{$oids{$oid}}; print "$oid ", join(' ', @names), "\n"; } exit(0); } print "[0]; print "\t'urn:oid:$oid' => '$name',\n"; } } elsif ($format eq 'oid2urn') { foreach my $oid (sort keys %oids) { my $name = $oids{$oid}->[0]; print "\t'urn:oid:$oid' => 'urn:mace:dir:attribute-def:$name',\n"; } } elsif ($format eq 'name2oid') { foreach my $name (sort keys %names) { my $oid = $names{$name}; print "\t'$name' => 'urn:oid:$oid',\n"; } } elsif ($format eq 'name2urn') { foreach my $name (sort keys %names) { print "\t'$name' => 'urn:mace:dir:attribute-def:$name',\n"; } } elsif ($format eq 'urn2oid') { foreach my $name (sort keys %names) { my $oid = $names{$name}; print "\t'urn:mace:dir:attribute-def:$name' => 'urn:oid:$oid',\n"; } } elsif ($format eq 'urn2name') { foreach my $name (sort keys %names) { print "\t'urn:mace:dir:attribute-def:$name' => '$name',\n"; } } print ");\n"; print "?>"; simplesamlphp-1.19.1/bin/importPdoMetadata.php0000755000000000000000000000211314042503475020062 0ustar rootroot#!/usr/bin/env php initDatabase(); $metadataDir = rtrim(\SimpleSAML\Configuration::getInstance()->getString('metadatadir'), '/'); foreach (glob("{$metadataDir}/*.php") as $filename) { $metadata = []; require_once $filename; $set = basename($filename, ".php"); echo "importing set '$set'..." . PHP_EOL; foreach ($metadata as $k => $v) { echo "\t$k" . PHP_EOL; $mdshp->addEntry($k, $set, $v); } } } } simplesamlphp-1.19.1/bin/build-release.sh0000755000000000000000000000340614042503475017012 0ustar rootroot#!/usr/bin/env bash set -e VERSION=$1 REPOPATH=$2 if ! shift; then echo "$0: Missing required version parameter." >&2 exit 1 fi if [ -z "$VERSION" ]; then echo "$0: Empty version parameter." >&2 exit 1 fi if [ -z "$REPOPATH" ]; then REPOPATH="https://github.com/simplesamlphp/simplesamlphp.git" fi TAG="v$VERSION" TARGET="simplesamlphp-$VERSION" cd /tmp if [ -a "$TARGET" ]; then echo "$0: Destination already exists: $TARGET" >&2 exit 1 fi umask 0022 git clone $REPOPATH $TARGET cd $TARGET git checkout $TAG cd .. if [ ! -x "$TARGET/composer.phar" ]; then curl -sS https://getcomposer.org/installer | php -- --install-dir=$TARGET fi # Downgrade composer to v1 to remain compatible with composer <1.8.5 (Debian 10) php "$TARGET/composer.phar" self-update --1 # Set the version in composer.json php "$TARGET/composer.phar" config version "v$VERSION" -d "$TARGET" # Install dependencies (without vcs history or dev tools) php "$TARGET/composer.phar" install --no-dev --prefer-dist -o -d "$TARGET" cd $TARGET npm install npm audit fix npm run build cd .. mkdir -p "$TARGET/config" "$TARGET/metadata" "$TARGET/cert" "$TARGET/log" "$TARGET/data" cp -rv "$TARGET/config-templates/"* "$TARGET/config/" cp -rv "$TARGET/metadata-templates/"* "$TARGET/metadata/" rm -rf "$TARGET/.git" rm -rf "$TARGET/node_modules" rm "$TARGET/www/assets/js/stylesheet.js"* rm "$TARGET/.editorconfig" rm "$TARGET/.gitattributes" rm -r "$TARGET/.github" rm "$TARGET/.php_cs.dist" rm "$TARGET/codecov.yml" rm "$TARGET/phpcs.xml" rm "$TARGET/psalm.xml" rm "$TARGET"/{,modules}/.gitignore rm "$TARGET"/{cache,config,metadata,locales}/.gitkeep rm "$TARGET/composer.phar" tar --owner 0 --group 0 -cvzf "$TARGET.tar.gz" "$TARGET" rm -rf "$TARGET" echo "Created: /tmp/$TARGET.tar.gz" simplesamlphp-1.19.1/bin/console0000755000000000000000000000062214042503475015323 0ustar rootroot#!/usr/bin/env php getParameterOption(['--modules', '-m'], 'core'); $kernel = new Kernel($module); $application = new Application($kernel); $application->run($input); simplesamlphp-1.19.1/lib/0000755000000000000000000000000014042503475013731 5ustar rootrootsimplesamlphp-1.19.1/lib/_autoload_modules.php0000644000000000000000000001474514042503475020154 0ustar rootroot, UNINETT * @package SimpleSAMLphp */ /** * This temporary autoloader allows loading classes with their old-style names (SimpleSAML_Path_Something) even if they * have been migrated to namespaces, by registering an alias for the new class. If the class has not yet been migrated, * the autoloader will then try to load it. * * @param string $class The full name of the class using underscores to separate the elements of the path, and starting * with 'SimpleSAML_'. * @deprecated This function will be removed in SSP 2.0. */ function temporaryLoader(string $class) { // handle the upgrade to the latest version of XMLSecLibs using namespaces if (strstr($class, 'XMLSec') && !strstr($class, '\\RobRichards\\XMLSecLibs\\')) { $new = '\\RobRichards\\XMLSecLibs\\' . $class; if (class_exists($new, true)) { class_alias($new, $class); SimpleSAML\Logger::warning("The class '$class' is now using namespaces, please use '$new'."); return; } } if (!strstr($class, 'SimpleSAML_')) { return; // not a valid class name for old classes } $original = $class; // list of classes that have been renamed or moved $renamed = [ 'SimpleSAML_Metadata_MetaDataStorageHandlerMDX' => 'SimpleSAML_Metadata_Sources_MDQ', 'SimpleSAML_Logger_LoggingHandlerSyslog' => 'SimpleSAML_Logger_SyslogLoggingHandler', 'SimpleSAML_Logger_LoggingHandlerErrorLog' => 'SimpleSAML_Logger_ErrorLogLoggingHandler', 'SimpleSAML_Logger_LoggingHandlerFile' => 'SimpleSAML_Logger_FileLoggingHandler', 'SimpleSAML_Logger_LoggingHandler' => 'SimpleSAML_Logger_LoggingHandlerInterface', 'SimpleSAML_IdP_LogoutHandler' => 'SimpleSAML_IdP_LogoutHandlerInterface', 'SimpleSAML_IdP_LogoutIFrame' => 'SimpleSAML_IdP_IFrameLogoutHandler', 'SimpleSAML_IdP_LogoutTraditional' => 'SimpleSAML_IdP_TraditionalLogoutHandler', 'SimpleSAML_Auth_Default' => 'SimpleSAML_Auth_DefaultAuth', 'SimpleSAML_Auth_LDAP' => 'SimpleSAML_Module_ldap_Auth_Ldap', ]; if (array_key_exists($class, $renamed)) { // the class has been renamed, try to load it and create an alias $class = $renamed[$class]; } // try to load it from the corresponding file $path = explode('_', $class); $file = dirname(__FILE__) . DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $path) . '.php'; if (file_exists($file)) { require_once $file; } // it exists, so it's not yet migrated to namespaces if (class_exists($class, false) || interface_exists($class, false)) { return; } // it didn't exist, try to see if it was migrated to namespaces $new = join('\\', $path); if (class_exists($new, false) || interface_exists($new, false)) { // do not try to autoload it if it doesn't exist! It should! class_alias($new, $original); SimpleSAML\Logger::warning("The class or interface '$original' is now using namespaces, please use '$new'."); } } /** * Autoload function for SimpleSAMLphp modules following PSR-0. * * @param string $className Name of the class. * * @deprecated This method will be removed in SSP 2.0. * * TODO: this autoloader should be removed once everything has been migrated to namespaces. */ function sspmodAutoloadPSR0(string $className) { $modulePrefixLength = strlen('sspmod_'); $classPrefix = substr($className, 0, $modulePrefixLength); if ($classPrefix !== 'sspmod_') { return; } // list of classes that have been renamed or moved $renamed = [ 'sspmod_adfs_SAML2_XML_fed_Const' => [ 'module' => 'adfs', 'path' => ['SAML2', 'XML', 'fed', 'Constants'] ], ]; if (array_key_exists($className, $renamed)) { // the class has been renamed, try to load it and create an alias $module = $renamed[$className]['module']; $path = $renamed[$className]['path']; } else { $modNameEnd = strpos($className, '_', $modulePrefixLength); $module = substr($className, $modulePrefixLength, $modNameEnd - $modulePrefixLength); $path = explode('_', substr($className, $modNameEnd + 1)); } if (!\SimpleSAML\Module::isModuleEnabled($module)) { return; } $file = \SimpleSAML\Module::getModuleDir($module) . '/lib/' . join('/', $path) . '.php'; if (!file_exists($file)) { return; } require_once($file); if (!class_exists($className, false) && !interface_exists($className, false)) { // the file exists, but the class is not defined. Is it using namespaces? $nspath = join('\\', $path); if ( class_exists('SimpleSAML\\Module\\' . $module . '\\' . $nspath) || interface_exists('SimpleSAML\\Module\\' . $module . '\\' . $nspath) ) { // the class has been migrated, create an alias and warn about it \SimpleSAML\Logger::warning( "The class or interface '$className' is now using namespaces, please use 'SimpleSAML\\Module\\" . $module . "\\" . $nspath . "' instead." ); class_alias("SimpleSAML\\Module\\$module\\$nspath", $className); } } } /** * Autoload function for SimpleSAMLphp modules following PSR-4. * * @param string $className Name of the class. */ function sspmodAutoloadPSR4(string $className) { $elements = explode('\\', $className); if ($elements[0] === '') { // class name starting with /, ignore array_shift($elements); } if (count($elements) < 4) { return; // it can't be a module } if (array_shift($elements) !== 'SimpleSAML') { return; // the first element is not "SimpleSAML" } if (array_shift($elements) !== 'Module') { return; // the second element is not "module" } // this is a SimpleSAMLphp module following PSR-4 $module = array_shift($elements); if (!\SimpleSAML\Module::isModuleEnabled($module)) { return; // module not enabled, avoid giving out any information at all } $file = \SimpleSAML\Module::getModuleDir($module) . '/lib/' . implode('/', $elements) . '.php'; if (file_exists($file)) { require_once($file); } } spl_autoload_register("temporaryLoader"); spl_autoload_register('sspmodAutoloadPSR0'); spl_autoload_register('sspmodAutoloadPSR4'); simplesamlphp-1.19.1/lib/_autoload.php0000644000000000000000000000123614042503475016413 0ustar rootroot * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML\XML; class Parser { /** @var \SimpleXMLElement */ public $simplexml; /** * @param string $xml */ public function __construct($xml) { $this->simplexml = new \SimpleXMLElement($xml); $this->simplexml->registerXPathNamespace('saml2', 'urn:oasis:names:tc:SAML:2.0:assertion'); $this->simplexml->registerXPathNamespace('saml2meta', 'urn:oasis:names:tc:SAML:2.0:metadata'); $this->simplexml->registerXPathNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#'); } /** * @param \SimpleXMLElement $element * @return \SimpleSAML\XML\Parser * @psalm-return \SimpleSAML\XML\Parser */ public static function fromSimpleXMLElement(\SimpleXMLElement $element) { // Traverse all existing namespaces in element $namespaces = $element->getNamespaces(); foreach ($namespaces as $prefix => $ns) { $element[(($prefix === '') ? 'xmlns' : 'xmlns:' . $prefix)] = $ns; } /* Create a new parser with the xml document where the namespace definitions * are added. */ $xml = $element->asXML(); if ($xml === false) { throw new \Exception('Error converting SimpleXMLElement to well-formed XML string.'); } return new Parser($xml); } /** * @param string $xpath * @param string $defvalue * @throws \Exception * @return string */ public function getValueDefault($xpath, $defvalue) { try { /** @var string */ return $this->getValue($xpath, true); } catch (\Exception $e) { return $defvalue; } } /** * @param string $xpath * @param bool $required * @throws \Exception * @return string|null */ public function getValue($xpath, $required = false) { $result = $this->simplexml->xpath($xpath); if (!is_array($result) || empty($result)) { if ($required) { throw new \Exception( 'Could not get value from XML document using the following XPath expression: ' . $xpath ); } else { return null; } } return (string) $result[0]; } /** * @param array $xpath * @param bool $required * @throws \Exception * @return string|null */ public function getValueAlternatives(array $xpath, $required = false) { foreach ($xpath as $x) { $seek = $this->getValue($x); if ($seek) { return $seek; } } if ($required) { throw new \Exception( 'Could not get value from XML document using multiple alternative XPath expressions.' ); } else { return null; } } } simplesamlphp-1.19.1/lib/SimpleSAML/XML/Shib13/0000755000000000000000000000000014042503475017330 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/XML/Shib13/AuthnResponse.php0000644000000000000000000004071114042503475022642 0ustar rootroot * @package SimpleSAMLphp * @deprecated This class will be removed in a future release */ namespace SimpleSAML\XML\Shib13; use DOMDocument; use DOMNode; use DOMNodeList; use DOMXpath; use SAML2\DOMDocumentFactory; use SimpleSAML\Configuration; use SimpleSAML\Error; use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Utils; use SimpleSAML\XML\Validator; class AuthnResponse { /** * @var \SimpleSAML\XML\Validator|null This variable contains an XML validator for this message. */ private $validator = null; /** * @var bool Whether this response was validated by some external means (e.g. SSL). */ private $messageValidated = false; /** @var string */ const SHIB_PROTOCOL_NS = 'urn:oasis:names:tc:SAML:1.0:protocol'; /** @var string */ const SHIB_ASSERT_NS = 'urn:oasis:names:tc:SAML:1.0:assertion'; /** * @var \DOMDocument|null The DOMDocument which represents this message. */ private $dom = null; /** * @var string|null The relaystate which is associated with this response. */ private $relayState = null; /** * Set whether this message was validated externally. * * @param bool $messageValidated TRUE if the message is already validated, FALSE if not. * @return void */ public function setMessageValidated($messageValidated) { assert(is_bool($messageValidated)); $this->messageValidated = $messageValidated; } /** * @param string $xml * @throws \Exception * @return void */ public function setXML($xml) { assert(is_string($xml)); try { $this->dom = DOMDocumentFactory::fromString(str_replace("\r", "", $xml)); } catch (\Exception $e) { throw new \Exception('Unable to parse AuthnResponse XML.'); } } /** * @param string|null $relayState * @return void */ public function setRelayState($relayState) { $this->relayState = $relayState; } /** * @return string|null */ public function getRelayState() { return $this->relayState; } /** * @throws \SimpleSAML\Error\Exception * @return bool */ public function validate() { assert($this->dom instanceof DOMDocument); if ($this->messageValidated) { // This message was validated externally return true; } // Validate the signature $this->validator = new Validator($this->dom, ['ResponseID', 'AssertionID']); // Get the issuer of the response $issuer = $this->getIssuer(); // Get the metadata of the issuer $metadata = MetaDataStorageHandler::getMetadataHandler(); $md = $metadata->getMetaDataConfig($issuer, 'shib13-idp-remote'); $publicKeys = $md->getPublicKeys('signing'); if (!empty($publicKeys)) { $certFingerprints = []; foreach ($publicKeys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } $certFingerprints[] = sha1(base64_decode($key['X509Certificate'])); } $this->validator->validateFingerprint($certFingerprints); } elseif ($md->hasValue('certFingerprint')) { $certFingerprints = $md->getArrayizeString('certFingerprint'); // Validate the fingerprint $this->validator->validateFingerprint($certFingerprints); } elseif ($md->hasValue('caFile')) { // Validate against CA $this->validator->validateCA(Utils\Config::getCertPath($md->getString('caFile'))); } else { throw new Error\Exception( 'Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' . $issuer . '].' ); } return true; } /** * Checks if the given node is validated by the signature on this response. * * @param \DOMElement|\SimpleXMLElement $node Node to be validated. * @return bool TRUE if the node is validated or FALSE if not. */ private function isNodeValidated($node): bool { if ($this->messageValidated) { // This message was validated externally return true; } if ($this->validator === null) { return false; } // Convert the node to a DOM node if it is an element from SimpleXML if ($node instanceof \SimpleXMLElement) { $node = dom_import_simplexml($node); } assert($node instanceof DOMNode); return $this->validator->isNodeValidated($node); } /** * This function runs an xPath query on this authentication response. * * @param string $query The query which should be run. * @param \DOMNode $node The node which this query is relative to. If this node is NULL (the default) * then the query will be relative to the root of the response. * @return \DOMNodeList */ private function doXPathQuery(string $query, DOMNode $node = null): DOMNodeList { assert($this->dom instanceof DOMDocument); if ($node === null) { $node = $this->dom->documentElement; } assert($node instanceof DOMNode); $xPath = new DOMXpath($this->dom); $xPath->registerNamespace('shibp', self::SHIB_PROTOCOL_NS); $xPath->registerNamespace('shib', self::SHIB_ASSERT_NS); return $xPath->query($query, $node); } /** * Retrieve the session index of this response. * * @return string|null The session index of this response. */ public function getSessionIndex() { assert($this->dom instanceof DOMDocument); $query = '/shibp:Response/shib:Assertion/shib:AuthnStatement'; $nodelist = $this->doXPathQuery($query); if ($node = $nodelist->item(0)) { return $node->getAttribute('SessionIndex'); } return null; } /** * @throws \Exception * @return array */ public function getAttributes(): array { $metadata = MetaDataStorageHandler::getMetadataHandler(); $md = $metadata->getMetaData($this->getIssuer(), 'shib13-idp-remote'); $base64 = isset($md['base64attributes']) ? $md['base64attributes'] : false; if (!($this->dom instanceof DOMDocument)) { return []; } $attributes = []; $assertions = $this->doXPathQuery('/shibp:Response/shib:Assertion'); foreach ($assertions as $assertion) { if (!$this->isNodeValidated($assertion)) { throw new \Exception('Shib13 AuthnResponse contained an unsigned assertion.'); } $conditions = $this->doXPathQuery('shib:Conditions', $assertion); if ($conditions->length > 0) { $condition = $conditions->item(0); $start = $condition->getAttribute('NotBefore'); $end = $condition->getAttribute('NotOnOrAfter'); if ($start && $end) { if (!self::checkDateConditions($start, $end)) { error_log('Date check failed ... (from ' . $start . ' to ' . $end . ')'); continue; } } } $attribute_nodes = $this->doXPathQuery( 'shib:AttributeStatement/shib:Attribute/shib:AttributeValue', $assertion ); foreach ($attribute_nodes as $attribute) { /** @var \DOMElement $attribute */ $value = $attribute->textContent; /** @var \DOMElement $parentNode */ $parentNode = $attribute->parentNode; $name = $parentNode->getAttribute('AttributeName'); if ($attribute->hasAttribute('Scope')) { $scopePart = '@' . $attribute->getAttribute('Scope'); } else { $scopePart = ''; } if (empty($name)) { throw new \Exception('Shib13 Attribute node without an AttributeName.'); } if (!array_key_exists($name, $attributes)) { $attributes[$name] = []; } if ($base64) { $encodedvalues = explode('_', $value); foreach ($encodedvalues as $v) { $attributes[$name][] = base64_decode($v) . $scopePart; } } else { $attributes[$name][] = $value . $scopePart; } } } return $attributes; } /** * @throws \Exception * @return string */ public function getIssuer() { $query = '/shibp:Response/shib:Assertion/@Issuer'; $nodelist = $this->doXPathQuery($query); if ($attr = $nodelist->item(0)) { return $attr->value; } else { throw new \Exception('Could not find Issuer field in Authentication response'); } } /** * @return array */ public function getNameID() { $nameID = []; $query = '/shibp:Response/shib:Assertion/shib:AuthenticationStatement/shib:Subject/shib:NameIdentifier'; $nodelist = $this->doXPathQuery($query); if ($node = $nodelist->item(0)) { $nameID["Value"] = $node->nodeValue; $nameID["Format"] = $node->getAttribute('Format'); } return $nameID; } /** * Build a authentication response. * * @param \SimpleSAML\Configuration $idp Metadata for the IdP the response is sent from. * @param \SimpleSAML\Configuration $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(Configuration $idp, 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 = []; } $id = Utils\Random::generateID(); $issueInstant = Utils\Time::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks $notBefore = Utils\Time::generateTimestamp(time() - 30); $assertionExpire = Utils\Time::generateTimestamp(time() + 300); // 5 minutes $assertionid = Utils\Random::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', false); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = Utils\Random::generateID(); $subjectNode = '' . '' . htmlspecialchars($nameid) . '' . '' . '' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '' . '' . ''; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= ''; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->encAttribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= ''; } /* * The SAML 1.1 response message */ $response = ' ' . htmlspecialchars($audience) . ' ' . $subjectNode . ' ' . $encodedattributes . ' '; return $response; } /** * Format a shib13 attribute. * * @param string $name Name of the attribute. * @param array $values Values of the attribute (as an array of strings). * @param bool $base64 Whether the attriubte values should be base64-encoded. * @param array $scopedAttributes Array of attributes names which are scoped. * @return string The attribute encoded as an XML-string. */ private function encAttribute(string $name, array $values, bool $base64, array $scopedAttributes): string { if (in_array($name, $scopedAttributes, true)) { $scoped = true; } else { $scoped = false; } $attr = ''; foreach ($values as $value) { $scopePart = ''; if ($scoped) { $tmp = explode('@', $value, 2); if (count($tmp) === 2) { $value = $tmp[0]; $scopePart = ' Scope="' . htmlspecialchars($tmp[1]) . '"'; } } if ($base64) { $value = base64_encode($value); } $attr .= '' . htmlspecialchars($value) . ''; } $attr .= ''; return $attr; } /** * Check if we are currently between the given date & time conditions. * * Note that this function allows a 10-minute leap from the initial time as marked by $start. * * @param string|null $start A SAML2 timestamp marking the start of the period to check. Defaults to null, in which * case there's no limitations in the past. * @param string|null $end A SAML2 timestamp marking the end of the period to check. Defaults to null, in which * case there's no limitations in the future. * * @return bool True if the current time belongs to the period specified by $start and $end. False otherwise. * * @see \SAML2\Utils::xsDateTimeToTimestamp. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ protected static function checkDateConditions($start = null, $end = null) { $currentTime = time(); if (!empty($start)) { $startTime = \SAML2\Utils::xsDateTimeToTimestamp($start); // allow for a 10 minute difference in time if (($startTime < 0) || (($startTime - 600) > $currentTime)) { return false; } } if (!empty($end)) { $endTime = \SAML2\Utils::xsDateTimeToTimestamp($end); if (($endTime < 0) || ($endTime <= $currentTime)) { return false; } } return true; } } simplesamlphp-1.19.1/lib/SimpleSAML/XML/Shib13/AuthnRequest.php0000644000000000000000000000370214042503475022473 0ustar rootroot * @package SimpleSAMLphp * @deprecated This class will be removed in a future release */ namespace SimpleSAML\XML\Shib13; use SimpleSAML\Metadata\MetaDataStorageHandler; class AuthnRequest { /** @var string|null */ private $issuer = null; /** @var string|null */ private $relayState = null; /** * @param string|null $relayState * @return void */ public function setRelayState($relayState) { $this->relayState = $relayState; } /** * @return string|null */ public function getRelayState() { return $this->relayState; } /** * @param string|null $issuer * @return void */ public function setIssuer($issuer) { $this->issuer = $issuer; } /** * @return string|null */ public function getIssuer() { return $this->issuer; } /** * @param string $destination * @param string $shire * @return string */ public function createRedirect($destination, $shire) { $metadata = MetaDataStorageHandler::getMetadataHandler(); $idpmetadata = $metadata->getMetaDataConfig($destination, 'shib13-idp-remote'); $desturl = $idpmetadata->getDefaultEndpoint( 'SingleSignOnService', ['urn:mace:shibboleth:1.0:profiles:AuthnRequest'] ); $desturl = $desturl['Location']; $target = $this->getRelayState(); $issuer = $this->getIssuer(); assert($issuer !== null); $url = $desturl . '?' . 'providerId=' . urlencode($issuer) . '&shire=' . urlencode($shire) . (isset($target) ? '&target=' . urlencode($target) : ''); return $url; } } simplesamlphp-1.19.1/lib/SimpleSAML/XML/Validator.php0000644000000000000000000003625714042503475020752 0ustar rootroot $publickey, ]; } else { assert($publickey === false || is_array($publickey)); } // Create an XML security object $objXMLSecDSig = new XMLSecurityDSig(); // Add the id attribute if the user passed in an id attribute if ($idAttribute !== null) { if (is_string($idAttribute)) { $objXMLSecDSig->idKeys[] = $idAttribute; } elseif (is_array($idAttribute)) { foreach ($idAttribute as $ida) { $objXMLSecDSig->idKeys[] = $ida; } } } // Locate the XMLDSig Signature element to be used $signatureElement = $objXMLSecDSig->locateSignature($xmlNode); if (!$signatureElement) { throw new \Exception('Could not locate XML Signature element.'); } // Canonicalize the XMLDSig SignedInfo element in the message $objXMLSecDSig->canonicalizeSignedInfo(); // Validate referenced xml nodes if (!$objXMLSecDSig->validateReference()) { throw new \Exception('XMLsec: digest validation failed'); } // Find the key used to sign the document $objKey = $objXMLSecDSig->locateKey(); if (empty($objKey)) { throw new \Exception('Error loading key to handle XML signature'); } // Load the key data if ($publickey !== false && array_key_exists('PEM', $publickey)) { // We have PEM data for the public key / certificate $objKey->loadKey($publickey['PEM']); } else { // No PEM data. Search for key in signature if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) { throw new \Exception('Error finding key data for XML signature validation.'); } if ($publickey !== false) { /* $publickey is set, and should therefore contain one or more fingerprints. * Check that the response contains a certificate with a matching * fingerprint. */ assert(is_array($publickey['certFingerprint'])); $certificate = $objKey->getX509Certificate(); if ($certificate === null) { // Wasn't signed with an X509 certificate throw new \Exception('Message wasn\'t signed with an X509 certificate,' . ' and no public key was provided in the metadata.'); } self::validateCertificateFingerprint($certificate, $publickey['certFingerprint']); // Key OK } } // Check the signature if ($objXMLSecDSig->verify($objKey) !== 1) { throw new \Exception("Unable to validate Signature"); } // Extract the certificate $this->x509Certificate = $objKey->getX509Certificate(); // Find the list of validated nodes $this->validNodes = $objXMLSecDSig->getValidatedNodes(); } /** * Retrieve the X509 certificate which was used to sign the XML. * * This function will return the certificate as a PEM-encoded string. If the XML * wasn't signed by an X509 certificate, NULL will be returned. * * @return string|null The certificate as a PEM-encoded string, or NULL if not signed with an X509 certificate. */ public function getX509Certificate() { return $this->x509Certificate; } /** * Calculates the fingerprint of an X509 certificate. * * @param string $x509cert The certificate as a base64-encoded string. The string may optionally * be framed with '-----BEGIN CERTIFICATE-----' and '-----END CERTIFICATE-----'. * @return string|null The fingerprint as a 40-character lowercase hexadecimal number. NULL is returned if the * argument isn't an X509 certificate. */ private static function calculateX509Fingerprint(string $x509cert): ?string { $lines = explode("\n", $x509cert); $data = ''; foreach ($lines as $line) { // Remove '\r' from end of line if present $line = rtrim($line); if ($line === '-----BEGIN CERTIFICATE-----') { // Delete junk from before the certificate $data = ''; } elseif ($line === '-----END CERTIFICATE-----') { // Ignore data after the certificate break; } elseif ($line === '-----BEGIN PUBLIC KEY-----') { // This isn't an X509 certificate return null; } else { // Append the current line to the certificate data $data .= $line; } } /* $data now contains the certificate as a base64-encoded string. The fingerprint * of the certificate is the sha1-hash of the certificate. */ return strtolower(sha1(base64_decode($data))); } /** * Helper function for validating the fingerprint. * * Checks the fingerprint of a certificate against an array of valid fingerprints. * Will throw an exception if none of the fingerprints matches. * * @param string $certificate The X509 certificate we should validate. * @param array $fingerprints The valid fingerprints. * @throws \Exception * @return void */ private static function validateCertificateFingerprint(string $certificate, array $fingerprints): void { $certFingerprint = self::calculateX509Fingerprint($certificate); if ($certFingerprint === null) { // Couldn't calculate fingerprint from X509 certificate. Should not happen. throw new \Exception('Unable to calculate fingerprint from X509' . ' certificate. Maybe it isn\'t an X509 certificate?'); } foreach ($fingerprints as $fp) { assert(is_string($fp)); if ($fp === $certFingerprint) { // The fingerprints matched return; } } // None of the fingerprints matched. Throw an exception describing the error. throw new \Exception('Invalid fingerprint of certificate. Expected one of [' . implode('], [', $fingerprints) . '], but got [' . $certFingerprint . ']'); } /** * Validate the fingerprint of the certificate which was used to sign this document. * * This function accepts either a string, or an array of strings as a parameter. If this * is an array, then any string (certificate) in the array can match. If this is a string, * then that string must match, * * @param string|array $fingerprints The fingerprints which should match. This can be a single string, * or an array of fingerprints. * @throws \Exception * @return void */ public function validateFingerprint($fingerprints) { assert(is_string($fingerprints) || is_array($fingerprints)); if ($this->x509Certificate === null) { throw new \Exception('Key used to sign the message was not an X509 certificate.'); } if (!is_array($fingerprints)) { $fingerprints = [$fingerprints]; } // Normalize the fingerprints foreach ($fingerprints as &$fp) { assert(is_string($fp)); // Make sure that the fingerprint is in the correct format $fp = strtolower(str_replace(":", "", $fp)); } self::validateCertificateFingerprint($this->x509Certificate, $fingerprints); } /** * This function checks if the given XML node was signed. * * @param \DOMNode $node The XML node which we should verify that was signed. * * @return bool TRUE if this node (or a parent node) was signed. FALSE if not. */ public function isNodeValidated($node) { assert($node instanceof \DOMNode); if ($this->validNodes !== null) { while ($node !== null) { if (in_array($node, $this->validNodes, true)) { return true; } $node = $node->parentNode; } } /* Neither this node nor any of the parent nodes could be found in the list of * signed nodes. */ return false; } /** * Validate the certificate used to sign the XML against a CA file. * * This function throws an exception if unable to validate against the given CA file. * * @param string $caFile File with trusted certificates, in PEM-format. * @throws \Exception * @return void */ public function validateCA($caFile) { assert(is_string($caFile)); if ($this->x509Certificate === null) { throw new \Exception('Key used to sign the message was not an X509 certificate.'); } self::validateCertificate($this->x509Certificate, $caFile); } /** * Validate a certificate against a CA file, by using the builtin * openssl_x509_checkpurpose function * * @param string $certificate The certificate, in PEM format. * @param string $caFile File with trusted certificates, in PEM-format. * @return boolean|string TRUE on success, or a string with error messages if it failed. * @deprecated */ private static function validateCABuiltIn(string $certificate, string $caFile) { // Clear openssl errors while (openssl_error_string() !== false) { } $res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, [$caFile]); $errors = ''; // Log errors while (($error = openssl_error_string()) !== false) { $errors .= ' [' . $error . ']'; } if ($res !== true) { return $errors; } return true; } /** * Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command. * * This function uses the openssl verify command to verify a certificate, to work around limitations * on the openssl_x509_checkpurpose function. That function will not work on certificates without a purpose * set. * * @param string $certificate The certificate, in PEM format. * @param string $caFile File with trusted certificates, in PEM-format. * @return bool|string TRUE on success, a string with error messages on failure. * @throws \Exception * @deprecated */ private static function validateCAExec(string $certificate, string $caFile) { $command = [ 'openssl', 'verify', '-CAfile', $caFile, '-purpose', 'any', ]; $cmdline = ''; foreach ($command as $c) { $cmdline .= escapeshellarg($c) . ' '; } $cmdline .= '2>&1'; $descSpec = [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], ]; $process = proc_open($cmdline, $descSpec, $pipes); if (!is_resource($process)) { throw new \Exception('Failed to execute verification command: ' . $cmdline); } if (fwrite($pipes[0], $certificate) === false) { throw new \Exception('Failed to write certificate for verification.'); } fclose($pipes[0]); $out = ''; while (!feof($pipes[1])) { $line = trim(fgets($pipes[1])); if (strlen($line) > 0) { $out .= ' [' . $line . ']'; } } fclose($pipes[1]); $status = proc_close($process); if ($status !== 0 || $out !== ' [stdin: OK]') { return $out; } return true; } /** * Validate the certificate used to sign the XML against a CA file. * * This function throws an exception if unable to validate against the given CA file. * * @param string $certificate The certificate, in PEM format. * @param string $caFile File with trusted certificates, in PEM-format. * @throws \Exception * @return void * @deprecated */ public static function validateCertificate($certificate, $caFile) { assert(is_string($certificate)); assert(is_string($caFile)); if (!file_exists($caFile)) { throw new \Exception('Could not load CA file: ' . $caFile); } Logger::debug('Validating certificate against CA file: ' . var_export($caFile, true)); $resBuiltin = self::validateCABuiltIn($certificate, $caFile); if ($resBuiltin !== true) { Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, true)); $resExternal = self::validateCAExec($certificate, $caFile); if ($resExternal !== true) { Logger::debug('Failed to validate with external function: ' . var_export($resExternal, true)); throw new \Exception('Could not verify certificate against CA file "' . $caFile . '". Internal result:' . var_export($resBuiltin, true) . ' External result:' . var_export($resExternal, true)); } } Logger::debug('Successfully validated certificate.'); } } simplesamlphp-1.19.1/lib/SimpleSAML/XML/Errors.php0000644000000000000000000000767514042503475020303 0ustar rootrootlevel . ',code=' . $error->code . ',line=' . $error->line . ',col=' . $error->column . ',msg=' . trim($error->message); } /** * Format a list of errors as a string. * * This fucntion takes an array of LibXMLError objects and creates a string with all the errors. * Each error will be separated by a newline, and the string will end with a newline-character. * * @param array $errors An array of errors. * @return string A string representing the errors. An empty string will be returned if there were no * errors in the array. */ public static function formatErrors($errors) { assert(is_array($errors)); $ret = ''; foreach ($errors as $error) { $ret .= self::formatError($error) . "\n"; } return $ret; } } simplesamlphp-1.19.1/lib/SimpleSAML/XML/Signer.php0000644000000000000000000002444314042503475020246 0ustar rootrootloadPrivateKey($options['privatekey'], $pass); } if (array_key_exists('certificate', $options)) { $this->loadCertificate($options['certificate']); } if (array_key_exists('privatekey_array', $options)) { $this->loadPrivateKeyArray($options['privatekey_array']); } if (array_key_exists('publickey_array', $options)) { $this->loadPublicKeyArray($options['publickey_array']); } if (array_key_exists('id', $options)) { $this->setIDAttribute($options['id']); } } /** * Set the private key from an array. * * This function loads the private key from an array matching what is returned * by \SimpleSAML\Utils\Crypto::loadPrivateKey(...). * * @param array $privatekey The private key. * @return void */ public function loadPrivateKeyArray($privatekey) { assert(is_array($privatekey)); assert(array_key_exists('PEM', $privatekey)); $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'private']); if (array_key_exists('password', $privatekey)) { $this->privateKey->passphrase = $privatekey['password']; } $this->privateKey->loadKey($privatekey['PEM'], false); } /** * Set the private key. * * Will throw an exception if unable to load the private key. * * @param string $file The file which contains the private key. The path is assumed to be relative * to the cert-directory. * @param string|null $pass The passphrase on the private key. Pass no value or NULL if the private * key is unencrypted. * @param bool $full_path Whether the filename found in the configuration contains the * full path to the private key or not. Default to false. * @throws \Exception * @return void */ public function loadPrivateKey($file, $pass = null, $full_path = false) { assert(is_string($file)); assert(is_string($pass) || $pass === null); assert(is_bool($full_path)); if (!$full_path) { $keyFile = Utils\Config::getCertPath($file); } else { $keyFile = $file; } if (!file_exists($keyFile)) { throw new \Exception('Could not find private key file "' . $keyFile . '".'); } $keyData = file_get_contents($keyFile); if ($keyData === false) { throw new \Exception('Unable to read private key file "' . $keyFile . '".'); } $privatekey = ['PEM' => $keyData]; if ($pass !== null) { $privatekey['password'] = $pass; } $this->loadPrivateKeyArray($privatekey); } /** * Set the public key / certificate we should include in the signature. * * This function loads the public key from an array matching what is returned * by \SimpleSAML\Utils\Crypto::loadPublicKey(...). * * @param array $publickey The public key. * @throws \Exception * @return void */ public function loadPublicKeyArray($publickey) { assert(is_array($publickey)); if (!array_key_exists('PEM', $publickey)) { // We have a public key with only a fingerprint throw new \Exception('Tried to add a certificate fingerprint in a signature.'); } // For now, we only assume that the public key is an X509 certificate $this->certificate = $publickey['PEM']; } /** * Set the certificate we should include in the signature. * * If this function isn't called, no certificate will be included. * Will throw an exception if unable to load the certificate. * * @param string $file The file which contains the certificate. The path is assumed to be relative to * the cert-directory. * @param bool $full_path Whether the filename found in the configuration contains the * full path to the private key or not. Default to false. * @throws \Exception * @return void */ public function loadCertificate($file, $full_path = false) { assert(is_string($file)); assert(is_bool($full_path)); if (!$full_path) { $certFile = Utils\Config::getCertPath($file); } else { $certFile = $file; } if (!file_exists($certFile)) { throw new \Exception('Could not find certificate file "' . $certFile . '".'); } $cert = file_get_contents($certFile); if ($cert === false) { throw new \Exception('Unable to read certificate file "' . $certFile . '".'); } $this->certificate = $cert; } /** * Set the attribute name for the ID value. * * @param string $idAttrName The name of the attribute which contains the id. * @return void */ public function setIDAttribute($idAttrName) { assert(is_string($idAttrName)); $this->idAttrName = $idAttrName; } /** * Add an extra certificate to the certificate chain in the signature. * * Extra certificates will be added to the certificate chain in the order they * are added. * * @param string $file The file which contains the certificate, relative to the cert-directory. * @param bool $full_path Whether the filename found in the configuration contains the * full path to the private key or not. Default to false. * @throws \Exception * @return void */ public function addCertificate($file, $full_path = false) { assert(is_string($file)); assert(is_bool($full_path)); if (!$full_path) { $certFile = Utils\Config::getCertPath($file); } else { $certFile = $file; } if (!file_exists($certFile)) { throw new \Exception('Could not find extra certificate file "' . $certFile . '".'); } $certificate = file_get_contents($certFile); if ($certificate === false) { throw new \Exception('Unable to read extra certificate file "' . $certFile . '".'); } $this->extraCertificates[] = $certificate; } /** * Signs the given DOMElement and inserts the signature at the given position. * * The private key must be set before calling this function. * * @param \DOMElement $node The DOMElement we should generate a signature for. * @param \DOMElement $insertInto The DOMElement we should insert the signature element into. * @param \DOMElement $insertBefore The element we should insert the signature element before. Defaults to NULL, * in which case the signature will be appended to the element spesified in * $insertInto. * @throws \Exception * @return void */ public function sign($node, $insertInto, $insertBefore = null) { assert($node instanceof DOMElement); assert($insertInto instanceof DOMElement); assert($insertBefore === null || $insertBefore instanceof DOMElement || $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText); $privateKey = $this->privateKey; if ($privateKey === false) { throw new \Exception('Private key not set.'); } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $options = []; if (!empty($this->idAttrName)) { $options['id_name'] = $this->idAttrName; } $objXMLSecDSig->addReferenceList( [$node], XMLSecurityDSig::SHA256, ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N], $options ); $objXMLSecDSig->sign($privateKey); // Add the certificate to the signature $objXMLSecDSig->add509Cert($this->certificate, true); // Add extra certificates foreach ($this->extraCertificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, true); } $objXMLSecDSig->insertSignature($insertInto, $insertBefore); } } simplesamlphp-1.19.1/lib/SimpleSAML/Configuration.php0000644000000000000000000014043114042503475021162 0ustar rootroot * @package SimpleSAMLphp */ class Configuration implements Utils\ClearableState { /** * The release version of this package */ public const VERSION = '1.19.1'; /** * A default value which means that the given option is required. * * @var string */ const REQUIRED_OPTION = '___REQUIRED_OPTION___'; /** * Associative array with mappings from instance-names to configuration objects. * * @var array */ private static $instance = []; /** * Configuration directories. * * This associative array contains the mappings from configuration sets to * configuration directories. * * @var array */ private static $configDirs = []; /** * Cache of loaded configuration files. * * The index in the array is the full path to the file. * * @var array */ private static $loadedConfigs = []; /** * The configuration array. * * @var array */ private $configuration; /** * The location which will be given when an error occurs. * * @var string */ private $location; /** * The file this configuration was loaded from. * * @var string|null */ private $filename = null; /** * Temporary property that tells if the deprecated getBaseURL() method has been called or not. * * @var bool */ private $deprecated_base_url_used = false; /** * Initializes a configuration from the given array. * * @param array $config The configuration array. * @param string $location The location which will be given when an error occurs. */ public function __construct($config, $location) { assert(is_array($config)); assert(is_string($location)); $this->configuration = $config; $this->location = $location; } /** * Load the given configuration file. * * @param string $filename The full path of the configuration file. * @param bool $required Whether the file is required. * * @return \SimpleSAML\Configuration The configuration file. An exception will be thrown if the * configuration file is missing. * * @throws \Exception If the configuration file is invalid or missing. */ private static function loadFromFile(string $filename, bool $required): Configuration { if (array_key_exists($filename, self::$loadedConfigs)) { return self::$loadedConfigs[$filename]; } if (file_exists($filename)) { $config = 'UNINITIALIZED'; // the file initializes a variable named '$config' ob_start(); if (interface_exists('Throwable', false)) { try { require($filename); } catch (\ParseError $e) { self::$loadedConfigs[$filename] = self::loadFromArray([], '[ARRAY]', 'simplesaml'); throw new Error\ConfigurationError($e->getMessage(), $filename, []); } } else { require($filename); } $spurious_output = ob_get_length() > 0; ob_end_clean(); // check that $config exists if (!isset($config)) { throw new Error\ConfigurationError( '$config is not defined in the configuration file.', $filename ); } // check that $config is initialized to an array if (!is_array($config)) { throw new Error\ConfigurationError( '$config is not an array.', $filename ); } // check that $config is not empty if (empty($config)) { throw new Error\ConfigurationError( '$config is empty.', $filename ); } } elseif ($required) { // file does not exist, but is required throw new Error\ConfigurationError('Missing configuration file', $filename); } else { // file does not exist, but is optional, so return an empty configuration object without saving it $cfg = new Configuration([], $filename); $cfg->filename = $filename; return $cfg; } $cfg = new Configuration($config, $filename); $cfg->filename = $filename; self::$loadedConfigs[$filename] = $cfg; if ($spurious_output) { Logger::warning( "The configuration file '$filename' generates output. Please review your configuration." ); } return $cfg; } /** * Set the directory for configuration files for the given configuration set. * * @param string $path The directory which contains the configuration files. * @param string $configSet The configuration set. Defaults to 'simplesaml'. * @return void */ public static function setConfigDir($path, $configSet = 'simplesaml') { assert(is_string($path)); assert(is_string($configSet)); self::$configDirs[$configSet] = $path; } /** * Store a pre-initialized configuration. * * Allows consumers to create configuration objects without having them * loaded from a file. * * @param \SimpleSAML\Configuration $config The configuration object to store * @param string $filename The name of the configuration file. * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'. * @return void * @throws \Exception */ public static function setPreLoadedConfig( Configuration $config, $filename = 'config.php', $configSet = 'simplesaml' ) { assert(is_string($filename)); assert(is_string($configSet)); if (!array_key_exists($configSet, self::$configDirs)) { if ($configSet !== 'simplesaml') { throw new \Exception('Configuration set \'' . $configSet . '\' not initialized.'); } else { self::$configDirs['simplesaml'] = dirname(dirname(dirname(__FILE__))) . '/config'; } } $dir = self::$configDirs[$configSet]; $filePath = $dir . '/' . $filename; self::$loadedConfigs[$filePath] = $config; } /** * Load a configuration file from a configuration set. * * @param string $filename The name of the configuration file. * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'. * * @return \SimpleSAML\Configuration The Configuration object. * @throws \Exception If the configuration set is not initialized. */ public static function getConfig($filename = 'config.php', $configSet = 'simplesaml') { assert(is_string($filename)); assert(is_string($configSet)); if (!array_key_exists($configSet, self::$configDirs)) { if ($configSet !== 'simplesaml') { throw new \Exception('Configuration set \'' . $configSet . '\' not initialized.'); } else { self::$configDirs['simplesaml'] = Utils\Config::getConfigDir(); } } $dir = self::$configDirs[$configSet]; $filePath = $dir . '/' . $filename; return self::loadFromFile($filePath, true); } /** * Load a configuration file from a configuration set. * * This function will return a configuration object even if the file does not exist. * * @param string $filename The name of the configuration file. * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'. * * @return \SimpleSAML\Configuration A configuration object. * @throws \Exception If the configuration set is not initialized. */ public static function getOptionalConfig($filename = 'config.php', $configSet = 'simplesaml') { assert(is_string($filename)); assert(is_string($configSet)); if (!array_key_exists($configSet, self::$configDirs)) { if ($configSet !== 'simplesaml') { throw new \Exception('Configuration set \'' . $configSet . '\' not initialized.'); } else { self::$configDirs['simplesaml'] = Utils\Config::getConfigDir(); } } $dir = self::$configDirs[$configSet]; $filePath = $dir . '/' . $filename; return self::loadFromFile($filePath, false); } /** * Loads a configuration from the given array. * * @param array $config The configuration array. * @param string $location The location which will be given when an error occurs. Optional. * @param string|null $instance The name of this instance. If specified, the configuration will be loaded and an * instance with that name will be kept for it to be retrieved later with getInstance($instance). If null, the * configuration will not be kept for later use. Defaults to null. * * @return \SimpleSAML\Configuration The configuration object. */ public static function loadFromArray($config, $location = '[ARRAY]', $instance = null) { assert(is_array($config)); assert(is_string($location)); $c = new Configuration($config, $location); if ($instance !== null) { self::$instance[$instance] = $c; } return $c; } /** * Get a configuration file by its instance name. * * This function retrieves a configuration file by its instance name. The instance * name is initialized by the init function, or by copyFromBase function. * * If no configuration file with the given instance name is found, an exception will * be thrown. * * @param string $instancename The instance name of the configuration file. Deprecated. * * @return \SimpleSAML\Configuration The configuration object. * * @throws \Exception If the configuration with $instancename name is not initialized. */ public static function getInstance($instancename = 'simplesaml') { assert(is_string($instancename)); // check if the instance exists already if (array_key_exists($instancename, self::$instance)) { return self::$instance[$instancename]; } if ($instancename === 'simplesaml') { try { return self::getConfig(); } catch (Error\ConfigurationError $e) { throw Error\CriticalConfigurationError::fromException($e); } } throw new Error\CriticalConfigurationError( 'Configuration with name ' . $instancename . ' is not initialized.' ); } /** * Initialize a instance name with the given configuration file. * * TODO: remove. * * @param string $path * @param string $instancename * @param string $configfilename * @return \SimpleSAML\Configuration * * @see setConfigDir() * @deprecated This function is superseeded by the setConfigDir function. */ public static function init($path, $instancename = 'simplesaml', $configfilename = 'config.php') { assert(is_string($path)); assert(is_string($instancename)); assert(is_string($configfilename)); if ($instancename === 'simplesaml') { // for backwards compatibility self::setConfigDir($path, 'simplesaml'); } // check if we already have loaded the given config - return the existing instance if we have if (array_key_exists($instancename, self::$instance)) { return self::$instance[$instancename]; } self::$instance[$instancename] = self::loadFromFile($path . '/' . $configfilename, true); return self::$instance[$instancename]; } /** * Load a configuration file which is located in the same directory as this configuration file. * * TODO: remove. * * @param string $instancename * @param string $filename * @return \SimpleSAML\Configuration * * @see getConfig() * @deprecated This function is superseeded by the getConfig() function. */ public function copyFromBase($instancename, $filename) { assert(is_string($instancename)); assert(is_string($filename)); assert($this->filename !== null); // check if we already have loaded the given config - return the existing instance if we have if (array_key_exists($instancename, self::$instance)) { return self::$instance[$instancename]; } $dir = dirname($this->filename); self::$instance[$instancename] = self::loadFromFile($dir . '/' . $filename, true); return self::$instance[$instancename]; } /** * Retrieve the current version of SimpleSAMLphp. * * @return string */ public function getVersion() { return self::VERSION; } /** * Retrieve a configuration option set in config.php. * * @param string $name Name of the configuration option. * @param mixed $default Default value of the configuration option. This parameter will default to null if not * specified. This can be set to \SimpleSAML\Configuration::REQUIRED_OPTION, which will * cause an exception to be thrown if the option isn't found. * * @return mixed The configuration option with name $name, or $default if the option was not found. * * @throws \Exception If the required option cannot be retrieved. */ public function getValue($name, $default = null) { // return the default value if the option is unset if (!array_key_exists($name, $this->configuration)) { if ($default === self::REQUIRED_OPTION) { throw new \Exception( $this->location . ': Could not retrieve the required option ' . var_export($name, true) ); } return $default; } return $this->configuration[$name]; } /** * Check whether a key in the configuration exists or not. * * @param string $name The key in the configuration to look for. * * @return boolean If the value is set in this configuration. */ public function hasValue($name) { return array_key_exists($name, $this->configuration); } /** * Check whether any key of the set given exists in the configuration. * * @param array $names An array of options to look for. * * @return boolean If any of the keys in $names exist in the configuration */ public function hasValueOneOf($names) { foreach ($names as $name) { if ($this->hasValue($name)) { return true; } } return false; } /** * Retrieve the absolute path of the SimpleSAMLphp installation, relative to the root of the website. * * For example: simplesaml/ * * The path will always end with a '/' and never have a leading slash. * * @return string The absolute path relative to the root of the website. * * @throws \SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect. * * @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use getBasePath() instead. */ public function getBaseURL() { if (!$this->deprecated_base_url_used) { $this->deprecated_base_url_used = true; Logger::warning( "\SimpleSAML\Configuration::getBaseURL() is deprecated, please use getBasePath() instead." ); } if (preg_match('/^\*(.*)$/D', $this->getString('baseurlpath', 'simplesaml/'), $matches)) { // deprecated behaviour, will be removed in the future return Utils\HTTP::getFirstPathElement(false) . $matches[1]; } return ltrim($this->getBasePath(), '/'); } /** * Retrieve the absolute path pointing to the SimpleSAMLphp installation. * * The path is guaranteed to start and end with a slash ('/'). E.g.: /simplesaml/ * * @return string The absolute path where SimpleSAMLphp can be reached in the web server. * * @throws \SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect. */ public function getBasePath() { $baseURL = $this->getString('baseurlpath', 'simplesaml/'); if (preg_match('#^https?://[^/]*(?:/(.+/?)?)?$#', $baseURL, $matches)) { // we have a full url, we need to strip the path if (!array_key_exists(1, $matches)) { // absolute URL without path return '/'; } return '/' . rtrim($matches[1], '/') . '/'; } elseif ($baseURL === '' || $baseURL === '/') { // root directory of site return '/'; } elseif (preg_match('#^/?((?:[^/\s]+/?)+)#', $baseURL, $matches)) { // local path only return '/' . rtrim($matches[1], '/') . '/'; } else { /* * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful * with the configuration. Use a guessed base path instead of the one provided. */ $c = $this->toArray(); $c['baseurlpath'] = Utils\HTTP::guessBasePath(); throw new Error\CriticalConfigurationError( 'Incorrect format for option \'baseurlpath\'. Value is: "' . $this->getString('baseurlpath', 'simplesaml/') . '". Valid format is in the form' . ' [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/].', $this->filename, $c ); } } /** * This function resolves a path which may be relative to the SimpleSAMLphp base directory. * * The path will never end with a '/'. * * @param string|null $path The path we should resolve. This option may be null. * * @return string|null $path if $path is an absolute path, or $path prepended with the base directory of this * SimpleSAMLphp installation. We will return NULL if $path is null. */ public function resolvePath($path) { if ($path === null) { return null; } assert(is_string($path)); return Utils\System::resolvePath($path, $this->getBaseDir()); } /** * Retrieve a path configuration option set in config.php. * * The function will always return an absolute path unless the option is not set. It will then return the default * value. * * It checks if the value starts with a slash, and prefixes it with the value from getBaseDir if it doesn't. * * @param string $name Name of the configuration option. * @param string|null $default Default value of the configuration option. This parameter will default to null if * not specified. * * @return string|null The path configuration option with name $name, or $default if the option was not found. */ public function getPathValue($name, $default = null) { // return the default value if the option is unset if (!array_key_exists($name, $this->configuration)) { $path = $default; } else { $path = $this->configuration[$name]; } $path = $this->resolvePath($path); if ($path === null) { return null; } return $path . '/'; } /** * Retrieve the base directory for this SimpleSAMLphp installation. * * This function first checks the 'basedir' configuration option. If this option is undefined or null, then we * fall back to looking at the current filename. * * @return string The absolute path to the base directory for this SimpleSAMLphp installation. This path will * always end with a slash. */ public function getBaseDir() { // check if a directory is configured in the configuration file $dir = $this->getString('basedir', null); if ($dir !== null) { // add trailing slash if it is missing if (substr($dir, -1) !== DIRECTORY_SEPARATOR) { $dir .= DIRECTORY_SEPARATOR; } return $dir; } // the directory wasn't set in the configuration file, path is /lib/SimpleSAML/Configuration.php $dir = __FILE__; assert(basename($dir) === 'Configuration.php'); $dir = dirname($dir); assert(basename($dir) === 'SimpleSAML'); $dir = dirname($dir); assert(basename($dir) === 'lib'); $dir = dirname($dir); // Add trailing directory separator $dir .= DIRECTORY_SEPARATOR; return $dir; } /** * This function retrieves a boolean configuration option. * * An exception will be thrown if this option isn't a boolean, or if this option isn't found, and no default value * is given. * * @param string $name The name of the option. * @param mixed $default 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 boolean|mixed The option with the given name, or $default if the option isn't found and $default is * specified. * * @throws \Exception If the option is not boolean. */ public function getBoolean($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!is_bool($ret)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' is not a valid boolean value.' ); } return $ret; } /** * This function retrieves a string configuration option. * * 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. * * @param string $name The name of the option. * @param mixed $default 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 string|mixed The option with the given name, or $default if the option isn't found and $default is * specified. * * @throws \Exception If the option is not a string. */ public function getString($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!is_string($ret)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' is not a valid string value.' ); } return $ret; } /** * This function retrieves an integer configuration option. * * An exception will be thrown if this option isn't an integer, or if this option isn't found, and no default value * is given. * * @param string $name The name of the option. * @param mixed $default 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 int|mixed The option with the given name, or $default if the option isn't found and $default is * specified. * * @throws \Exception If the option is not an integer. */ public function getInteger($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!is_int($ret)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' is not a valid integer value.' ); } return $ret; } /** * This function retrieves an integer configuration option where the value must be in the specified range. * * An exception will be thrown if: * - the option isn't an integer * - the option isn't found, and no default value is given * - the value is outside of the allowed range * * @param string $name The name of the option. * @param int $minimum The smallest value which is allowed. * @param int $maximum The largest value which is allowed. * @param mixed $default 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 int|mixed The option with the given name, or $default if the option isn't found and $default is * specified. * * @throws \Exception If the option is not in the range specified. */ public function getIntegerRange($name, $minimum, $maximum, $default = self::REQUIRED_OPTION) { assert(is_string($name)); assert(is_int($minimum)); assert(is_int($maximum)); $ret = $this->getInteger($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if ($ret < $minimum || $ret > $maximum) { throw new \Exception( $this->location . ': Value of option ' . var_export($name, true) . ' is out of range. Value is ' . $ret . ', allowed range is [' . $minimum . ' - ' . $maximum . ']' ); } return $ret; } /** * Retrieve a configuration option with one of the given values. * * This will check that the configuration option matches one of the given values. The match will use * strict comparison. An exception will be thrown if it does not match. * * The option can be mandatory or optional. If no default value is given, it will be considered to be * mandatory, and an exception will be thrown if it isn't provided. If a default value is given, it * is considered to be optional, and the default value is returned. The default value is automatically * included in the list of allowed values. * * @param string $name The name of the option. * @param array $allowedValues The values the option is allowed to take, as an array. * @param mixed $default The default value which will be returned if the option isn't found. If this parameter * isn't given, the option will be considered to be mandatory. The default value can be * any value, including null. * * @return mixed The option with the given name, or $default if the option isn't found and $default is given. * * @throws \Exception If the option does not have any of the allowed values. */ public function getValueValidate($name, $allowedValues, $default = self::REQUIRED_OPTION) { assert(is_string($name)); assert(is_array($allowedValues)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!in_array($ret, $allowedValues, true)) { $strValues = []; foreach ($allowedValues as $av) { $strValues[] = var_export($av, true); } $strValues = implode(', ', $strValues); throw new \Exception( $this->location . ': Invalid value given for the option ' . var_export($name, true) . '. It should have one of the following values: ' . $strValues . '; but it had the following value: ' . var_export($ret, true) ); } return $ret; } /** * This function retrieves an array configuration option. * * 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. * * @param string $name The name of the option. * @param mixed $default 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. * * @throws \Exception If the option is not an array. */ public function getArray($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!is_array($ret)) { throw new \Exception($this->location . ': The option ' . var_export($name, true) . ' is not an array.'); } return $ret; } /** * This function retrieves an array configuration option. * * If the configuration option isn't an array, it will be converted to an array. * * @param string $name The name of the option. * @param mixed $default 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. */ public function getArrayize($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } if (!is_array($ret)) { $ret = [$ret]; } return $ret; } /** * This function retrieves a configuration option with a string or an array of strings. * * If the configuration option is a string, it will be converted to an array with a single string * * @param string $name The name of the option. * @param mixed $default 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. * * @throws \Exception If the option is not a string or an array of strings. */ public function getArrayizeString($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getArrayize($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } foreach ($ret as $value) { if (!is_string($value)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' must be a string or an array of strings.' ); } } return $ret; } /** * Retrieve an array as a \SimpleSAML\Configuration object. * * This function will load the value of an option into a \SimpleSAML\Configuration object. The option must contain * an array. * * 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. * * @param string $name The name of the option. * @param array|null $default A default value which will be used if the option isn't found. An empty Configuration * object will be returned if this parameter isn't given and the option doesn't exist. * This function will only return null if $default is set to null and the option * doesn't exist. * * @return mixed The option with the given name, or $default if the option isn't found and $default is specified. * * @throws \Exception If the option is not an array. */ public function getConfigItem($name, $default = []) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === null) { // the option wasn't found, or it is explicitly null // do not instantiate a new Configuration instance, but just return null return null; } if (!is_array($ret)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' is not an array.' ); } return self::loadFromArray($ret, $this->location . '[' . var_export($name, true) . ']'); } /** * Retrieve an array of arrays as an array of \SimpleSAML\Configuration objects. * * This function will retrieve an option containing an array of arrays, and create an array of * \SimpleSAML\Configuration objects from that array. The indexes in the new array will be the same as the original * indexes, but the values will be \SimpleSAML\Configuration objects. * * An exception will be thrown if this option isn't an array of arrays, or if this option isn't found, and no * default value is given. * * @param string $name The name of the option. * * @return array The array of \SimpleSAML\Configuration objects. * * @throws \Exception If the value of this element is not an array. * * @deprecated Very specific function, will be removed in a future release; use getConfigItem or getArray instead */ public function getConfigList($name) { assert(is_string($name)); $ret = $this->getValue($name, []); if (!is_array($ret)) { throw new \Exception( $this->location . ': The option ' . var_export($name, true) . ' is not an array.' ); } $out = []; foreach ($ret as $index => $config) { $newLoc = $this->location . '[' . var_export($name, true) . '][' . var_export($index, true) . ']'; if (!is_array($config)) { throw new \Exception($newLoc . ': The value of this element was expected to be an array.'); } $out[$index] = self::loadFromArray($config, $newLoc); } return $out; } /** * Retrieve list of options. * * This function returns the name of all options which are defined in this * configuration file, as an array of strings. * * @return array Name of all options defined in this configuration file. */ public function getOptions() { return array_keys($this->configuration); } /** * Convert this configuration object back to an array. * * @return array An associative array with all configuration options and values. */ public function toArray() { return $this->configuration; } /** * Retrieve the default binding for the given endpoint type. * * This function combines the current metadata type (SAML 2 / SAML 1.1) * with the endpoint type to determine which binding is the default. * * @param string $endpointType The endpoint type. * * @return string The default binding. * * @throws \Exception If the default binding is missing for this endpoint type. */ private function getDefaultBinding(string $endpointType): string { $set = $this->getString('metadata-set'); switch ($set . ':' . $endpointType) { case 'saml20-idp-remote:SingleSignOnService': case 'saml20-idp-remote:SingleLogoutService': case 'saml20-sp-remote:SingleLogoutService': return Constants::BINDING_HTTP_REDIRECT; case 'saml20-sp-remote:AssertionConsumerService': return Constants::BINDING_HTTP_POST; case 'saml20-idp-remote:ArtifactResolutionService': return Constants::BINDING_SOAP; case 'shib13-idp-remote:SingleSignOnService': return 'urn:mace:shibboleth:1.0:profiles:AuthnRequest'; case 'shib13-sp-remote:AssertionConsumerService': return 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post'; default: throw new \Exception('Missing default binding for ' . $endpointType . ' in ' . $set); } } /** * Helper function for dealing with metadata endpoints. * * @param string $endpointType The endpoint type. * * @return array Array of endpoints of the given type. * * @throws \Exception If any element of the configuration options for this endpoint type is incorrect. */ public function getEndpoints($endpointType) { assert(is_string($endpointType)); $loc = $this->location . '[' . var_export($endpointType, true) . ']:'; if (!array_key_exists($endpointType, $this->configuration)) { // no endpoints of the given type return []; } $eps = $this->configuration[$endpointType]; if (is_string($eps)) { // for backwards-compatibility $eps = [$eps]; } elseif (!is_array($eps)) { throw new \Exception($loc . ': Expected array or string.'); } foreach ($eps as $i => &$ep) { $iloc = $loc . '[' . var_export($i, true) . ']'; if (is_string($ep)) { // for backwards-compatibility $ep = [ 'Location' => $ep, 'Binding' => $this->getDefaultBinding($endpointType), ]; $responseLocation = $this->getString($endpointType . 'Response', null); if ($responseLocation !== null) { $ep['ResponseLocation'] = $responseLocation; } } elseif (!is_array($ep)) { throw new \Exception($iloc . ': Expected a string or an array.'); } if (!array_key_exists('Location', $ep)) { throw new \Exception($iloc . ': Missing Location.'); } if (!is_string($ep['Location'])) { throw new \Exception($iloc . ': Location must be a string.'); } if (!array_key_exists('Binding', $ep)) { throw new \Exception($iloc . ': Missing Binding.'); } if (!is_string($ep['Binding'])) { throw new \Exception($iloc . ': Binding must be a string.'); } if (array_key_exists('ResponseLocation', $ep)) { if (!is_string($ep['ResponseLocation'])) { throw new \Exception($iloc . ': ResponseLocation must be a string.'); } } if (array_key_exists('index', $ep)) { if (!is_int($ep['index'])) { throw new \Exception($iloc . ': index must be an integer.'); } } } return $eps; } /** * Find an endpoint of the given type, using a list of supported bindings as a way to prioritize. * * @param string $endpointType The endpoint type. * @param array $bindings Sorted array of acceptable bindings. * @param mixed $default The default value to return if no matching endpoint is found. If no default is provided, * an exception will be thrown. * * @return array|null The default endpoint, or null if no acceptable endpoints are used. * * @throws \Exception If no supported endpoint is found. */ public function getEndpointPrioritizedByBinding($endpointType, array $bindings, $default = self::REQUIRED_OPTION) { assert(is_string($endpointType)); $endpoints = $this->getEndpoints($endpointType); foreach ($bindings as $binding) { foreach ($endpoints as $ep) { if ($ep['Binding'] === $binding) { return $ep; } } } if ($default === self::REQUIRED_OPTION) { $loc = $this->location . '[' . var_export($endpointType, true) . ']:'; throw new \Exception($loc . 'Could not find a supported ' . $endpointType . ' endpoint.'); } return $default; } /** * Find the default endpoint of the given type. * * @param string $endpointType The endpoint type. * @param array $bindings Array with acceptable bindings. Can be null if any binding is allowed. * @param mixed $default The default value to return if no matching endpoint is found. If no default is provided, * an exception will be thrown. * * @return mixed The default endpoint, or the $default parameter if no acceptable endpoints are used. * * @throws \Exception If no supported endpoint is found and no $default parameter is specified. */ public function getDefaultEndpoint($endpointType, array $bindings = null, $default = self::REQUIRED_OPTION) { assert(is_string($endpointType)); $endpoints = $this->getEndpoints($endpointType); $defaultEndpoint = Utils\Config\Metadata::getDefaultEndpoint($endpoints, $bindings); if ($defaultEndpoint !== null) { return $defaultEndpoint; } if ($default === self::REQUIRED_OPTION) { $loc = $this->location . '[' . var_export($endpointType, true) . ']:'; throw new \Exception($loc . 'Could not find a supported ' . $endpointType . ' endpoint.'); } return $default; } /** * Retrieve a string which may be localized into many languages. * * The default language returned is always 'en'. * * @param string $name The name of the option. * @param mixed $default The default value. If no default is given, and the option isn't found, an exception will * be thrown. * * @return mixed Associative array with language => string pairs, or the provided default value. * * @throws \Exception If the translation is not an array or a string, or its index or value are not strings. */ public function getLocalizedString($name, $default = self::REQUIRED_OPTION) { assert(is_string($name)); $ret = $this->getValue($name, $default); if ($ret === $default) { // the option wasn't found, or it matches the default value. In any case, return this value return $ret; } $loc = $this->location . '[' . var_export($name, true) . ']'; if (is_string($ret)) { $ret = ['en' => $ret]; } if (!is_array($ret)) { throw new \Exception($loc . ': Must be an array or a string.'); } foreach ($ret as $k => $v) { if (!is_string($k)) { throw new \Exception($loc . ': Invalid language code: ' . var_export($k, true)); } if (!is_string($v)) { throw new \Exception($loc . '[' . var_export($v, true) . ']: Must be a string.'); } } return $ret; } /** * Get public key from metadata. * * @param string|null $use The purpose this key can be used for. (encryption or signing). * @param bool $required Whether the public 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 Public key data, or empty array if no public key or was found. * * @throws \Exception If the certificate or public key cannot be loaded from a file. * @throws \SimpleSAML\Error\Exception If the file does not contain a valid PEM-encoded certificate, or there is no * certificate in the metadata. */ public function getPublicKeys($use = null, $required = false, $prefix = '') { assert(is_bool($required)); assert(is_string($prefix)); if ($this->hasValue($prefix . 'keys')) { $ret = []; foreach ($this->getArray($prefix . 'keys') as $key) { if ($use !== null && isset($key[$use]) && !$key[$use]) { continue; } if (isset($key['X509Certificate'])) { // Strip whitespace from key $key['X509Certificate'] = preg_replace('/\s+/', '', $key['X509Certificate']); } $ret[] = $key; } return $ret; } elseif ($this->hasValue($prefix . 'certData')) { $certData = $this->getString($prefix . 'certData'); $certData = preg_replace('/\s+/', '', $certData); return [ [ 'encryption' => true, 'signing' => true, 'type' => 'X509Certificate', 'X509Certificate' => $certData, ], ]; } elseif ($this->hasValue($prefix . 'certificate')) { $file = $this->getString($prefix . 'certificate'); $file = Utils\Config::getCertPath($file); $data = @file_get_contents($file); if ($data === false) { throw new \Exception( $this->location . ': Unable to load certificate/public key from file "' . $file . '".' ); } // extract certificate data (if this is a certificate) $pattern = '/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m'; if (!preg_match($pattern, $data, $matches)) { throw new \SimpleSAML\Error\Exception( $this->location . ': Could not find PEM encoded certificate in "' . $file . '".' ); } $certData = preg_replace('/\s+/', '', $matches[1]); return [ [ 'encryption' => true, 'signing' => true, 'type' => 'X509Certificate', 'X509Certificate' => $certData, ], ]; } elseif ($required === true) { throw new \SimpleSAML\Error\Exception($this->location . ': Missing certificate in metadata.'); } else { return []; } } /** * Clear any configuration information cached. * Allows for configuration files to be changed and reloaded during a given request. Most useful * when running phpunit tests and needing to alter config.php between test cases * * @return void */ public static function clearInternalState() { self::$configDirs = []; self::$instance = []; self::$loadedConfigs = []; } } simplesamlphp-1.19.1/lib/SimpleSAML/SessionHandler.php0000644000000000000000000001153714042503475021300 0ustar rootroot * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML; abstract class SessionHandler { /** * This static variable contains a reference to the current * instance of the session handler. This variable will be NULL if * we haven't instantiated a session handler yet. * * @var \SimpleSAML\SessionHandler */ protected static $sessionHandler; /** * This function retrieves the current instance of the session handler. * The session handler will be instantiated if this is the first call * to this function. * * @return \SimpleSAML\SessionHandler The current session handler. * * @throws \Exception If we cannot instantiate the session handler. */ public static function getSessionHandler() { if (self::$sessionHandler === null) { self::createSessionHandler(); } return self::$sessionHandler; } /** * This constructor is included in case it is needed in the * future. Including it now allows us to write parent::__construct() in * the subclasses of this class. */ protected function __construct() { } /** * Create a new session id. * * @return string The new session id. */ abstract public function newSessionId(); /** * Retrieve the session ID saved in the session cookie, if there's one. * * @return string|null The session id saved in the cookie or null if no session cookie was set. */ abstract public function getCookieSessionId(); /** * Retrieve the session cookie name. * * @return string The session cookie name. */ abstract public function getSessionCookieName(); /** * Save the session. * * @param \SimpleSAML\Session $session The session object we should save. */ abstract public function saveSession(Session $session); /** * Load the session. * * @param string|null $sessionId The ID of the session we should load, or null to use the default. * * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist. */ abstract public function loadSession($sessionId = null); /** * Check whether the session cookie is set. * * This function will only return false if is is certain that the cookie isn't set. * * @return bool True if it was set, false if not. */ abstract public function hasSessionCookie(); /** * Set a session cookie. * * @param string $sessionName The name of the session. * @param string|null $sessionID The session ID to use. Set to null to delete the cookie. * @param array|null $cookieParams Additional parameters to use for the session cookie. * * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie. */ abstract public function setCookie($sessionName, $sessionID, array $cookieParams = null); /** * Initialize the session handler. * * This function creates an instance of the session handler which is * selected in the 'store.type' configuration directive. If no * session handler is selected, then we will fall back to the default * PHP session handler. * * @return void * * @throws \Exception If we cannot instantiate the session handler. */ private static function createSessionHandler(): void { $store = Store::getInstance(); if ($store === false) { self::$sessionHandler = new SessionHandlerPHP(); } else { /** @var \SimpleSAML\Store $store At this point, $store can only be an object */ self::$sessionHandler = new SessionHandlerStore($store); } } /** * Get the cookie parameters that should be used for session cookies. * * @return array An array with the cookie parameters. * @link http://www.php.net/manual/en/function.session-get-cookie-params.php */ public function getCookieParams() { $config = Configuration::getInstance(); return [ 'lifetime' => $config->getInteger('session.cookie.lifetime', 0), 'path' => $config->getString('session.cookie.path', '/'), 'domain' => strval($config->getString('session.cookie.domain', null)), 'secure' => $config->getBoolean('session.cookie.secure', false), 'samesite' => $config->getString('session.cookie.samesite', null), 'httponly' => true, ]; } } simplesamlphp-1.19.1/lib/SimpleSAML/Session.php0000644000000000000000000010773114042503475020004 0ustar rootroot * @author Jaime Pérez Crespo, UNINETT AS * @package SimpleSAMLphp */ class Session implements \Serializable, Utils\ClearableState { /** * This is a timeout value for setData, which indicates that the data * should never be deleted, i.e. lasts the whole session lifetime. */ public const DATA_TIMEOUT_SESSION_END = 'sessionEndTimeout'; /** * The list of loaded session objects. * * This is an associative array indexed with the session id. * * @var array */ private static $sessions = []; /** * This variable holds the instance of the session - Singleton approach. * * Warning: do not set the instance manually, call Session::load() instead. * * @var \SimpleSAML\Session|null */ private static $instance = null; /** * The global configuration. * * @var \SimpleSAML\Configuration */ private static $config; /** * The session ID of this session. * * @var string|null */ private $sessionId; /** * Transient session flag. * * @var boolean|false */ private $transient = false; /** * The track id is a new random unique identifier that is generated for each session. * This is used in the debug logs and error messages to easily track more information * about what went wrong. * * @var string */ private $trackid; /** * @var integer|null */ private $rememberMeExpire = null; /** * Marks a session as modified, and therefore needs to be saved before destroying * this object. * * @var bool */ private $dirty = false; /** * Tells the session object that the save callback has been registered and there's no need to register it again. * * @var bool */ private $callback_registered = false; /** * This is an array of objects which will expire automatically after a set time. It is used * where one needs to store some information - for example a logout request, but doesn't * want it to be stored forever. * * The data store contains three levels of nested associative arrays. The first is the data type, the * second is the identifier, and the third contains the expire time of the data and the data itself. * * @var array */ private $dataStore = []; /** * The list of IdP-SP associations. * * This is an associative array with the IdP id as the key, and the list of * associations as the value. * * @var array */ private $associations = []; /** * The authentication token. * * This token is used to prevent session fixation attacks. * * @var string|null */ private $authToken; /** * Authentication data. * * This is an array with authentication data for the various authsources. * * @var array Associative array of associative arrays. */ private $authData = []; /** * Private constructor that restricts instantiation to either getSessionFromRequest() for the current session or * getSession() for a specific one. * * @param boolean $transient Whether to create a transient session or not. */ private function __construct(bool $transient = false) { $this->setConfiguration(Configuration::getInstance()); if (php_sapi_name() === 'cli' || defined('STDIN')) { $this->trackid = 'CL' . bin2hex(openssl_random_pseudo_bytes(4)); Logger::setTrackId($this->trackid); $this->transient = $transient; return; } if ($transient) { // transient session $this->trackid = 'TR' . bin2hex(openssl_random_pseudo_bytes(4)); Logger::setTrackId($this->trackid); $this->transient = true; } else { // regular session $sh = SessionHandler::getSessionHandler(); $this->sessionId = $sh->newSessionId(); $sh->setCookie($sh->getSessionCookieName(), $this->sessionId, $sh->getCookieParams()); $this->trackid = bin2hex(openssl_random_pseudo_bytes(5)); Logger::setTrackId($this->trackid); $this->markDirty(); // initialize data for session check function if defined $checkFunction = self::$config->getValue('session.check_function', null); if (is_callable($checkFunction)) { call_user_func($checkFunction, $this, true); } } } /** * Set the configuration we should use. * * @param Configuration $config * @return void */ public function setConfiguration(Configuration $config) { self::$config = $config; } /** * Serialize this session object. * * This method will be invoked by any calls to serialize(). * * @return string The serialized representation of this session object. */ public function serialize() { return serialize(get_object_vars($this)); } /** * Unserialize a session object and load it.. * * This method will be invoked by any calls to unserialize(), allowing us to restore any data that might not * be serializable in its original form (e.g.: DOM objects). * * @param string $serialized The serialized representation of a session that we want to restore. */ public function unserialize($serialized) { $session = unserialize($serialized); if (is_array($session)) { foreach ($session as $k => $v) { $this->$k = $v; } } self::$config = Configuration::getInstance(); // look for any raw attributes and load them in the 'Attributes' array foreach ($this->authData as $authority => $parameters) { if (!array_key_exists('RawAttributes', $parameters)) { continue; } foreach ($parameters['RawAttributes'] as $attribute => $values) { foreach ($values as $idx => $value) { // this should be originally a DOMNodeList /* @var \SAML2\XML\saml\AttributeValue $value */ $this->authData[$authority]['Attributes'][$attribute][$idx] = $value->getElement()->childNodes; } } } } /** * Retrieves the current session. Creates a new session if there's not one. * * @return Session The current session. * @throws \Exception When session couldn't be initialized and the session fallback is disabled by configuration. */ public static function getSessionFromRequest() { // check if we already have initialized the session if (isset(self::$instance)) { return self::$instance; } // check if we have stored a session stored with the session handler try { /** @var \SimpleSAML\Session|null $session Help Scrutinizer with the correct type */ $session = self::getSession(); } catch (\Exception $e) { /* * For some reason, we were unable to initialize this session. Note that this error might be temporary, and * it's possible that we can recover from it in subsequent requests, so we should not try to create a new * session here. Therefore, use just a transient session and throw the exception for someone else to handle * it. */ self::useTransientSession(); Logger::error('Error loading session: ' . $e->getMessage()); if ($e instanceof Error\Exception) { $cause = $e->getCause(); if ($cause instanceof \Exception) { throw $cause; } } throw $e; } // if getSession() found it, use it if ($session instanceof Session) { return self::load($session); } /* * We didn't have a session loaded when we started, but we have it now. At this point, getSession() failed but * it must have triggered the creation of a session at some point during the process (e.g. while logging an * error message). This means we don't need to create a new session again, we can use the one that's loaded now * instead. */ if (self::$instance !== null) { return self::$instance; } // try to create a new session try { self::load(new Session()); } catch (Error\CannotSetCookie $e) { // can't create a regular session because we can't set cookies. Use transient. $c = Configuration::getInstance(); self::useTransientSession(); if ($e->getCode() === Error\CannotSetCookie::SECURE_COOKIE) { throw new Error\CriticalConfigurationError( $e->getMessage(), null, $c->toArray() ); } Logger::error('Error creating session: ' . $e->getMessage()); } // we must have a session now, either regular or transient /** @var \SimpleSAML\Session */ return self::$instance; } /** * Get a session from the session handler. * * @param string|null $sessionId The session we should get, or null to get the current session. * * @return \SimpleSAML\Session|null The session that is stored in the session handler, * or null if the session wasn't found. */ public static function getSession($sessionId = null) { assert(is_string($sessionId) || $sessionId === null); $sh = SessionHandler::getSessionHandler(); if ($sessionId === null) { $checkToken = true; $sessionId = $sh->getCookieSessionId(); if ($sessionId === null) { return null; } } else { $checkToken = false; } if (array_key_exists($sessionId, self::$sessions)) { return self::$sessions[$sessionId]; } $session = $sh->loadSession($sessionId); if ($session === null) { return null; } assert($session instanceof self); if ($checkToken) { $globalConfig = Configuration::getInstance(); if ($session->authToken !== null) { $authTokenCookieName = $globalConfig->getString( 'session.authtoken.cookiename', 'SimpleSAMLAuthToken' ); if (!isset($_COOKIE[$authTokenCookieName])) { Logger::warning('Missing AuthToken cookie.'); return null; } if (!Utils\Crypto::secureCompare($session->authToken, $_COOKIE[$authTokenCookieName])) { Logger::warning('Invalid AuthToken cookie.'); return null; } } // run session check function if defined $checkFunction = $globalConfig->getValue('session.check_function', null); if (is_callable($checkFunction)) { $check = call_user_func($checkFunction, $session); if ($check !== true) { Logger::warning('Session did not pass check function.'); return null; } } } self::$sessions[$sessionId] = $session; return $session; } /** * Load a given session as the current one. * * This method will also set the track ID in the logger to the one in the given session. * * Warning: never set self::$instance yourself, call this method instead. * * @param \SimpleSAML\Session $session The session to load. * @return \SimpleSAML\Session The session we just loaded, just for convenience. */ private static function load(Session $session): Session { Logger::setTrackId($session->getTrackID()); self::$instance = $session; return self::$instance; } /** * Use a transient session. * * Create a session that should not be saved at the end of the request. * Subsequent calls to getInstance() will return this transient session. * * @return void */ public static function useTransientSession() { if (isset(self::$instance)) { // we already have a session, don't bother with a transient session return; } self::load(new Session(true)); } /** * Create a new session and cache it. * * @param string $sessionId The new session we should create. * @return void */ public static function createSession($sessionId) { assert(is_string($sessionId)); self::$sessions[$sessionId] = null; } /** * Save the session to the store. * * This method saves the session to the session handler in case it has been marked as dirty. * * WARNING: please do not use this method directly unless you really need to and know what you are doing. Use * markDirty() instead. * * @return void */ public function save() { // clean out old data $this->expireData(); if (!$this->dirty) { // session hasn't changed, don't bother saving it return; } $this->dirty = false; $this->callback_registered = false; $sh = SessionHandler::getSessionHandler(); try { $sh->saveSession($this); } catch (\Exception $e) { if (!($e instanceof Error\Exception)) { $e = new Error\UnserializableException($e); } Logger::error('Unable to save session.'); $e->logError(); } } /** * Save the current session and clean any left overs that could interfere with the normal application behaviour. * * Use this method if you are using PHP sessions in your application *and* in SimpleSAMLphp, *after* you are done * using SimpleSAMLphp and before trying to access your application's session again. * * @return void */ public function cleanup() { $this->save(); $sh = SessionHandler::getSessionHandler(); if ($sh instanceof SessionHandlerPHP) { $sh->restorePrevious(); } } /** * Mark this session as dirty. * * This method will register a callback to save the session right before any output is sent to the browser. * * @return void */ public function markDirty() { if ($this->isTransient()) { return; } $this->dirty = true; if ($this->callback_registered) { // we already have a shutdown callback registered for this object, no need to add another one return; } $this->callback_registered = header_register_callback([$this, 'save']); } /** * Destroy the session. * * Destructor for this class. It will save the session to the session handler * in case the session has been marked as dirty. Do nothing otherwise. * * @return void */ public function __destruct() { $this->save(); } /** * Retrieve the session ID of this session. * * @return string|null The session ID, or null if this is a transient session. */ public function getSessionId() { return $this->sessionId; } /** * Retrieve if session is transient. * * @return boolean The session transient flag. */ public function isTransient() { return $this->transient; } /** * Get a unique ID that will be permanent for this session. * Used for debugging and tracing log files related to a session. * * @return string The unique ID. */ public function getTrackID() { return $this->trackid; } /** * Get remember me expire time. * * @return integer|null The remember me expire time. */ public function getRememberMeExpire() { return $this->rememberMeExpire; } /** * Set remember me expire time. * * @param int $expire Unix timestamp when remember me session cookies expire. * @return void */ public function setRememberMeExpire($expire = null) { assert(is_int($expire) || $expire === null); if ($expire === null) { $expire = time() + self::$config->getInteger('session.rememberme.lifetime', 14 * 86400); } $this->rememberMeExpire = $expire; $cookieParams = ['expire' => $this->rememberMeExpire]; $this->updateSessionCookies($cookieParams); } /** * Marks the user as logged in with the specified authority. * * If the user already has logged in, the user will be logged out first. * * @param string $authority The authority the user logged in with. * @param array|null $data The authentication data for this authority. * @return void * * @throws Error\CannotSetCookie If the authentication token cannot be set for some reason. */ public function doLogin($authority, array $data = null) { assert(is_string($authority)); assert(is_array($data) || $data === null); Logger::debug('Session: doLogin("' . $authority . '")'); $this->markDirty(); if (isset($this->authData[$authority])) { // we are already logged in, log the user out first $this->doLogout($authority); } if ($data === null) { $data = []; } $data['Authority'] = $authority; if (!isset($data['AuthnInstant'])) { $data['AuthnInstant'] = time(); } $maxSessionExpire = time() + self::$config->getInteger('session.duration', 8 * 60 * 60); if (!isset($data['Expire']) || $data['Expire'] > $maxSessionExpire) { // unset, or beyond our session lifetime. Clamp it to our maximum session lifetime $data['Expire'] = $maxSessionExpire; } // check if we have non-serializable attribute values foreach ($data['Attributes'] as $attribute => $values) { foreach ($values as $idx => $value) { if (is_string($value) || is_int($value)) { continue; } // at this point, this should be a DOMNodeList object... if (!is_a($value, 'DOMNodeList')) { continue; } /* @var \DOMNodeList $value */ if ($value->length === 0) { continue; } /** @psalm-var \DOMNode $node We made sure value has at least 1 item in the check above */ $node = $value->item(0); // create an AttributeValue object and save it to 'RawAttributes', using same attribute name and index $attrval = new AttributeValue($node->parentNode); $data['RawAttributes'][$attribute][$idx] = $attrval; } } $this->authData[$authority] = $data; $this->authToken = Utils\Random::generateID(); $sessionHandler = SessionHandler::getSessionHandler(); if ( !$this->transient && (!empty($data['RememberMe']) || $this->rememberMeExpire !== null) && self::$config->getBoolean('session.rememberme.enable', false) ) { $this->setRememberMeExpire(); } else { try { Utils\HTTP::setCookie( self::$config->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken, $sessionHandler->getCookieParams() ); } catch (Error\CannotSetCookie $e) { /* * Something went wrong when setting the auth token. We cannot recover from this, so we better log a * message and throw an exception. The user is not properly logged in anyway, so clear all login * information from the session. */ unset($this->authToken); unset($this->authData[$authority]); Logger::error('Cannot set authentication token cookie: ' . $e->getMessage()); throw $e; } } } /** * Marks the user as logged out. * * This function will call any registered logout handlers before marking the user as logged out. * * @param string $authority The authentication source we are logging out of. * @return void */ public function doLogout($authority) { Logger::debug('Session: doLogout(' . var_export($authority, true) . ')'); if (!isset($this->authData[$authority])) { Logger::debug('Session: Already logged out of ' . $authority . '.'); return; } $this->markDirty(); $this->callLogoutHandlers($authority); unset($this->authData[$authority]); if (!$this->isValid($authority) && $this->rememberMeExpire !== null) { $this->rememberMeExpire = null; $this->updateSessionCookies(); } } /** * This function calls all registered logout handlers. * * @param string $authority The authentication source we are logging out from. * @return void * * @throws \Exception If the handler is not a valid function or method. */ private function callLogoutHandlers(string $authority): void { assert(isset($this->authData[$authority])); if (empty($this->authData[$authority]['LogoutHandlers'])) { return; } foreach ($this->authData[$authority]['LogoutHandlers'] as $handler) { // verify that the logout handler is a valid function if (!is_callable($handler)) { $classname = $handler[0]; $functionname = $handler[1]; throw new \Exception( 'Logout handler is not a valid function: ' . $classname . '::' . $functionname ); } // call the logout handler call_user_func($handler); } // we require the logout handlers to register themselves again if they want to be called later unset($this->authData[$authority]['LogoutHandlers']); } /** * Is the session representing an authenticated user, and is the session still alive. * This function will return false after the user has timed out. * * @param string $authority The authentication source that the user should be authenticated with. * * @return bool True if the user has a valid session, false if not. */ public function isValid($authority) { assert(is_string($authority)); if (!isset($this->authData[$authority])) { Logger::debug( 'Session: ' . var_export($authority, true) . ' not valid because we are not authenticated.' ); return false; } if ($this->authData[$authority]['Expire'] <= time()) { Logger::debug('Session: ' . var_export($authority, true) . ' not valid because it is expired.'); return false; } Logger::debug('Session: Valid session found with ' . var_export($authority, true) . '.'); return true; } /** * Update session cookies. * * @param array $params The parameters for the cookies. * @return void */ public function updateSessionCookies($params = null) { assert(is_null($params) || is_array($params)); $sessionHandler = SessionHandler::getSessionHandler(); if ($this->sessionId !== null) { $sessionHandler->setCookie($sessionHandler->getSessionCookieName(), $this->sessionId, $params); } $params = array_merge($sessionHandler->getCookieParams(), is_array($params) ? $params : []); if ($this->authToken !== null) { Utils\HTTP::setCookie( self::$config->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken, $params ); } } /** * Set the lifetime for authentication source. * * @param string $authority The authentication source we are setting expire time for. * @param int $expire The number of seconds authentication source is valid. * @return void */ public function setAuthorityExpire($authority, $expire = null) { assert(isset($this->authData[$authority])); assert(is_int($expire) || $expire === null); $this->markDirty(); if ($expire === null) { $expire = time() + self::$config->getInteger('session.duration', 8 * 60 * 60); } $this->authData[$authority]['Expire'] = $expire; } /** * This function registers a logout handler. * * @param string $authority The authority for which register the handler. * @param string $classname The class which contains the logout handler. * @param string $functionname The logout handler function. * @return void * * @throws \Exception If the handler is not a valid function or method. */ public function registerLogoutHandler($authority, $classname, $functionname) { assert(isset($this->authData[$authority])); $logout_handler = [$classname, $functionname]; if (!is_callable($logout_handler)) { throw new \Exception( 'Logout handler is not a valid function: ' . $classname . '::' . $functionname ); } $this->authData[$authority]['LogoutHandlers'][] = $logout_handler; $this->markDirty(); } /** * Delete data from the data store. * * This function immediately deletes the data with the given type and id from the data store. * * @param string $type The type of the data. * @param string $id The identifier of the data. * @return void */ public function deleteData($type, $id) { assert(is_string($type)); assert(is_string($id)); if (!array_key_exists($type, $this->dataStore)) { return; } unset($this->dataStore[$type][$id]); $this->markDirty(); } /** * This function stores data in the data store. * * The timeout value can be Session::DATA_TIMEOUT_SESSION_END, which indicates * that the data should never be deleted. * * @param string $type The type of the data. This is checked when retrieving data from the store. * @param string $id The identifier of the data. * @param mixed $data The data. * @param int|string|null $timeout The number of seconds this data should be stored after its last access. * This parameter is optional. The default value is set in 'session.datastore.timeout', * and the default is 4 hours. * @return void * * @throws \Exception If the data couldn't be stored. * */ public function setData($type, $id, $data, $timeout = null) { assert(is_string($type)); assert(is_string($id)); assert(is_int($timeout) || $timeout === null || $timeout === self::DATA_TIMEOUT_SESSION_END); if ($timeout === null) { // use the default timeout $timeout = self::$config->getInteger('session.datastore.timeout', null); if ($timeout !== null) { if ($timeout <= 0) { throw new \Exception( 'The value of the session.datastore.timeout' . ' configuration option should be a positive integer.' ); } } } if ($timeout === self::DATA_TIMEOUT_SESSION_END) { $expires = self::DATA_TIMEOUT_SESSION_END; } else { $expires = time() + $timeout; } $dataInfo = [ 'expires' => $expires, 'timeout' => $timeout, 'data' => $data ]; if (!array_key_exists($type, $this->dataStore)) { $this->dataStore[$type] = []; } $this->dataStore[$type][$id] = $dataInfo; $this->markDirty(); } /** * This function removes expired data from the data store. * * @return void */ private function expireData(): void { $ct = time(); foreach ($this->dataStore as &$typedData) { foreach ($typedData as $id => $info) { if ($info['expires'] === self::DATA_TIMEOUT_SESSION_END) { // this data never expires continue; } if ($ct > $info['expires']) { unset($typedData[$id]); $this->markDirty(); } } } } /** * This function retrieves data from the data store. * * Note that this will not change when the data stored in the data store will expire. If that is required, * the data should be written back with setData. * * @param string $type The type of the data. This must match the type used when adding the data. * @param string|null $id The identifier of the data. Can be null, in which case null will be returned. * * @return mixed The data of the given type with the given id or null if the data doesn't exist in the data store. */ public function getData($type, $id) { assert(is_string($type)); assert($id === null || is_string($id)); if ($id === null) { return null; } if (!array_key_exists($type, $this->dataStore)) { return null; } if (!array_key_exists($id, $this->dataStore[$type])) { return null; } return $this->dataStore[$type][$id]['data']; } /** * This function retrieves all data of the specified type from the data store. * * The data will be returned as an associative array with the id of the data as the key, and the data * as the value of each key. The value will be stored as a copy of the original data. setData must be * used to update the data. * * An empty array will be returned if no data of the given type is found. * * @param string $type The type of the data. * * @return array An associative array with all data of the given type. */ public function getDataOfType($type) { assert(is_string($type)); if (!array_key_exists($type, $this->dataStore)) { return []; } $ret = []; foreach ($this->dataStore[$type] as $id => $info) { $ret[$id] = $info['data']; } return $ret; } /** * Get the current persistent authentication state. * * @param string $authority The authority to retrieve the data from. * * @return array|null The current persistent authentication state, or null if not authenticated. */ public function getAuthState($authority) { assert(is_string($authority)); if (!isset($this->authData[$authority])) { return null; } return $this->authData[$authority]; } /** * Check whether the session cookie is set. * * This function will only return false if is is certain that the cookie isn't set. * * @return bool true if it was set, false if not. */ public function hasSessionCookie() { $sh = SessionHandler::getSessionHandler(); return $sh->hasSessionCookie(); } /** * Add an SP association for an IdP. * * This function is only for use by the IdP class. * * @param string $idp The IdP id. * @param array $association The association we should add. * @return void */ public function addAssociation($idp, array $association) { assert(is_string($idp)); assert(isset($association['id'])); assert(isset($association['Handler'])); if (!isset($this->associations)) { $this->associations = []; } if (!isset($this->associations[$idp])) { $this->associations[$idp] = []; } $this->associations[$idp][$association['id']] = $association; $this->markDirty(); } /** * Retrieve the associations for an IdP. * * This function is only for use by the IdP class. * * @param string $idp The IdP id. * * @return array The IdP associations. */ public function getAssociations($idp) { assert(is_string($idp)); if (!isset($this->associations)) { $this->associations = []; } if (!isset($this->associations[$idp])) { return []; } foreach ($this->associations[$idp] as $id => $assoc) { if (!isset($assoc['Expires'])) { continue; } if ($assoc['Expires'] >= time()) { continue; } unset($this->associations[$idp][$id]); } return $this->associations[$idp]; } /** * Remove an SP association for an IdP. * * This function is only for use by the IdP class. * * @param string $idp The IdP id. * @param string $associationId The id of the association. * @return void */ public function terminateAssociation($idp, $associationId) { assert(is_string($idp)); assert(is_string($associationId)); if (!isset($this->associations)) { return; } if (!isset($this->associations[$idp])) { return; } unset($this->associations[$idp][$associationId]); $this->markDirty(); } /** * Retrieve authentication data. * * @param string $authority The authentication source we should retrieve data from. * @param string $name The name of the data we should retrieve. * * @return mixed The value, or null if the value wasn't found. */ public function getAuthData($authority, $name) { assert(is_string($authority)); assert(is_string($name)); if (!isset($this->authData[$authority][$name])) { return null; } return $this->authData[$authority][$name]; } /** * Retrieve a list of authorities (authentication sources) that are currently valid within * this session. * * @return mixed An array containing every authority currently valid. Empty if none available. */ public function getAuthorities() { $authorities = []; foreach (array_keys($this->authData) as $authority) { if ($this->isValid($authority)) { $authorities[] = $authority; } } return $authorities; } /** * Clear any configuration information cached * @return void */ public static function clearInternalState() { self::$config = null; self::$instance = null; self::$sessions = null; } } simplesamlphp-1.19.1/lib/SimpleSAML/Stats.php0000644000000000000000000000453214042503475017452 0ustar rootrootgetString('class'); $cls = Module::resolveClass($cls, 'Stats\Output', '\SimpleSAML\Stats\Output'); $output = new $cls($config); return $output; } /** * Initialize the outputs. * * @return void */ private static function initOutputs(): void { $config = Configuration::getInstance(); $outputCfgs = $config->getConfigList('statistics.out'); self::$outputs = []; foreach ($outputCfgs as $cfg) { self::$outputs[] = self::createOutput($cfg); } } /** * Notify about an event. * * @param string $event The event. * @param array $data Event data. Optional. * * @return void|boolean False if output is not enabled, void otherwise. */ public static function log($event, array $data = []) { assert(is_string($event)); assert(!isset($data['op'])); assert(!isset($data['time'])); assert(!isset($data['_id'])); if (!self::$initialized) { self::initOutputs(); self::$initialized = true; } if (empty(self::$outputs)) { // not enabled return false; } $data['op'] = $event; $data['time'] = microtime(true); // the ID generation is designed to cluster IDs related in time close together $int_t = (int) $data['time']; $hd = openssl_random_pseudo_bytes(16); $data['_id'] = sprintf('%016x%s', $int_t, bin2hex($hd)); foreach (self::$outputs as $out) { $out->emit($data); } } } simplesamlphp-1.19.1/lib/SimpleSAML/Console/0000755000000000000000000000000014042503475017241 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Console/Application.php0000644000000000000000000000116514042503475022220 0ustar rootrootgetDefinition(); $inputDefinition->addOption( new InputOption('--module', '-m', InputOption::VALUE_REQUIRED, 'The module name', $kernel->getModule()) ); } } simplesamlphp-1.19.1/lib/SimpleSAML/Command/0000755000000000000000000000000014042503475017215 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Command/RouterDebugCommand.php0000644000000000000000000000455414042503475023464 0ustar rootrootrouter = $router; } /** * {@inheritDoc} * @return void */ protected function configure() { $this ->setDescription('Displays current routes for a module') ->setHelp( <<<'EOF' The %command.name% displays the configured routes for a module: php %command.full_name% EOF ) ; } /** * {@inheritdoc} * @psalm-suppress InvalidReturnType */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); $routes = $this->router->getRouteCollection(); $tableHeaders = array('Name', 'Method', 'Scheme', 'Host', 'Path', 'Controller'); $tableRows = array(); foreach ($routes->all() as $name => $route) { $row = [ $name, $route->getMethods() ? implode('|', $route->getMethods()) : 'ANY', $route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY', '' !== $route->getHost() ? $route->getHost() : 'ANY', $route->getPath(), ]; $controller = $route->getDefault('_controller'); if ($controller instanceof Closure) { $controller = 'Closure'; } elseif (is_object($controller)) { $controller = get_class($controller); } $row[] = $controller; $tableRows[] = $row; } $table = new Table($io); $table->setHeaders($tableHeaders)->setRows($tableRows); $table->setStyle('compact'); $table->render(); } } simplesamlphp-1.19.1/lib/SimpleSAML/Logger/0000755000000000000000000000000014042503475017056 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Logger/LoggingHandlerInterface.php0000644000000000000000000000166614042503475024305 0ustar rootroot * @package SimpleSAMLphp */ class FileLoggingHandler implements LoggingHandlerInterface { /** * A string with the path to the file where we should log our messages. * * @var null|string */ protected $logFile = null; /** * This array contains the mappings from syslog log levels to names. Copied more or less directly from * SimpleSAML\Logger\ErrorLogLoggingHandler. * * @var array */ private static $levelNames = [ Logger::EMERG => 'EMERGENCY', Logger::ALERT => 'ALERT', Logger::CRIT => 'CRITICAL', Logger::ERR => 'ERROR', Logger::WARNING => 'WARNING', Logger::NOTICE => 'NOTICE', Logger::INFO => 'INFO', Logger::DEBUG => 'DEBUG', ]; /** @var string|null */ protected $processname = null; /** @var string */ protected $format = "%b %d %H:%M:%S"; /** * Build a new logging handler based on files. * @param \SimpleSAML\Configuration $config */ public function __construct(Configuration $config) { // get the metadata handler option from the configuration $this->logFile = $config->getPathValue('loggingdir', 'log/') . $config->getString('logging.logfile', 'simplesamlphp.log'); // Remove any non-printable characters before storing $this->processname = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $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." ); } } Utils\Time::initTimezone(); } /** * Set the format desired for the logs. * * @param string $format The format used for logs. * @return void */ public function setLogFormat($format) { $this->format = $format; } /** * Log a message to the log file. * * @param int $level The log level. * @param string $string The formatted message to log. * @return void */ public function log($level, $string) { if (!is_null($this->logFile)) { // set human-readable log level. Copied from SimpleSAML\Logger\ErrorLogLoggingHandler. $levelName = sprintf('UNKNOWN%d', $level); if (array_key_exists($level, self::$levelNames)) { $levelName = self::$levelNames[$level]; } $formats = ['%process', '%level']; $replacements = [$this->processname, $levelName]; $matches = []; if (preg_match('/%date(?:\{([^\}]+)\})?/', $this->format, $matches)) { $format = "%b %d %H:%M:%S"; if (isset($matches[1])) { $format = $matches[1]; } array_push($formats, $matches[0]); array_push($replacements, strftime($format)); } $string = str_replace($formats, $replacements, $string); file_put_contents($this->logFile, $string . \PHP_EOL, FILE_APPEND); } } } simplesamlphp-1.19.1/lib/SimpleSAML/Logger/ErrorLogLoggingHandler.php0000644000000000000000000000445414042503475024136 0ustar rootroot * @author Olav Morken, UNINETT AS. * @package SimpleSAMLphp */ class ErrorLogLoggingHandler implements LoggingHandlerInterface { /** * This array contains the mappings from syslog log level to names. * * @var array */ private static $levelNames = [ Logger::EMERG => 'EMERG', Logger::ALERT => 'ALERT', Logger::CRIT => 'CRIT', Logger::ERR => 'ERR', Logger::WARNING => 'WARNING', Logger::NOTICE => 'NOTICE', Logger::INFO => 'INFO', Logger::DEBUG => 'DEBUG', ]; /** * The name of this process. * * @var string */ private $processname; /** * ErrorLogLoggingHandler constructor. * * @param \SimpleSAML\Configuration $config The configuration object for this handler. */ public function __construct(Configuration $config) { // Remove any non-printable characters before storing $this->processname = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $config->getString('logging.processname', 'SimpleSAMLphp')); } /** * Set the format desired for the logs. * * @param string $format The format used for logs. * @return void */ public function setLogFormat($format) { // we don't need the format here } /** * Log a message to syslog. * * @param int $level The log level. * @param string $string The formatted message to log. * @return void */ public function log($level, $string) { if (array_key_exists($level, self::$levelNames)) { $levelName = self::$levelNames[$level]; } else { $levelName = sprintf('UNKNOWN%d', $level); } $formats = ['%process', '%level']; $replacements = [$this->processname, $levelName]; $string = str_replace($formats, $replacements, $string); $string = preg_replace('/%\w+(\{[^\}]+\})?/', '', $string); $string = trim($string); error_log($string); } } simplesamlphp-1.19.1/lib/SimpleSAML/Logger/SyslogLoggingHandler.php0000644000000000000000000000435214042503475023660 0ustar rootroot * @package SimpleSAMLphp */ class SyslogLoggingHandler implements LoggingHandlerInterface { /** @var bool */ private $isWindows = false; /** @var string */ protected $format = "%b %d %H:%M:%S"; /** * Build a new logging handler based on syslog. * @param \SimpleSAML\Configuration $config */ public function __construct(Configuration $config) { $facility = $config->getInteger('logging.facility', defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER); // Remove any non-printable characters before storing $processname = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $config->getString('logging.processname', 'SimpleSAMLphp')); // Setting facility to LOG_USER (only valid in Windows), enable log level rewrite on windows systems if (Utils\System::getOS() === Utils\System::WINDOWS) { $this->isWindows = true; $facility = LOG_USER; } openlog($processname, LOG_PID, $facility); } /** * Set the format desired for the logs. * * @param string $format The format used for logs. * @return void */ public function setLogFormat($format) { $this->format = $format; } /** * Log a message to syslog. * * @param int $level The log level. * @param string $string The formatted message to log. * @return void */ public function log($level, $string) { // changing log level to supported levels if OS is Windows if ($this->isWindows) { if ($level <= 4) { $level = LOG_ERR; } else { $level = LOG_INFO; } } $formats = ['%process', '%level']; $replacements = ['', $level]; $string = str_replace($formats, $replacements, $string); $string = preg_replace('/%\w+(\{[^\}]+\})?/', '', $string); $string = trim($string); syslog($level, $string); } } simplesamlphp-1.19.1/lib/SimpleSAML/Logger/StandardErrorLoggingHandler.php0000644000000000000000000000151114042503475025144 0ustar rootroot * @package SimpleSAMLphp */ class StandardErrorLoggingHandler extends FileLoggingHandler { /** * StandardError constructor. * * It runs the parent constructor and sets the log file to be the standard error descriptor. * * @param \SimpleSAML\Configuration $config */ public function __construct(Configuration $config) { // Remove any non-printable characters before storing $this->processname = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $config->getString('logging.processname', 'SimpleSAMLphp')); $this->logFile = 'php://stderr'; } } simplesamlphp-1.19.1/lib/SimpleSAML/XHTML/0000755000000000000000000000000014042503475016533 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/XHTML/Template.php0000644000000000000000000007222114042503475021023 0ustar rootroot * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML\XHTML; use SimpleSAML\Configuration; use SimpleSAML\Locale\Language; use SimpleSAML\Locale\Localization; use SimpleSAML\Locale\Translate; use SimpleSAML\Logger; use SimpleSAML\Module; use SimpleSAML\TwigConfigurableI18n\Twig\Environment as Twig_Environment; use SimpleSAML\TwigConfigurableI18n\Twig\Extensions\Extension\I18n as Twig_Extensions_Extension_I18n; use SimpleSAML\Utils; use Symfony\Component\HttpFoundation\Response; use Twig\Loader\FilesystemLoader; use Twig\TwigFilter; use Twig\TwigFunction; /** * The content-property is set upstream, but this is not recognized by Psalm * @psalm-suppress PropertyNotSetInConstructor */ class Template extends Response { /** * The data associated with this template, accessible within the template itself. * * @var array */ public $data = []; /** * A translator instance configured to work with this template. * * @var \SimpleSAML\Locale\Translate */ private $translator; /** * The localization backend * * @var \SimpleSAML\Locale\Localization */ private $localization; /** * The configuration to use in this template. * * @var \SimpleSAML\Configuration */ private $configuration; /** * The file to load in this template. * * @var string */ private $template = 'default.php'; /** * The twig environment. * * @var \Twig\Environment * @psalm-suppress PropertyNotSetInConstructor Remove this annotation in 2.0 */ private $twig; /** * The template name. * * @var string */ private $twig_template; /** * Current module, if any. * * @var string */ private $module; /** * Whether to use the new user interface or not. * * @var bool */ private $useNewUI = false; /** * A template controller, if any. * * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set * the 'theme.controller' configuration option to a class that implements the * \SimpleSAML\XHTML\TemplateControllerInterface interface to use it. * * @var \SimpleSAML\XHTML\TemplateControllerInterface|null */ private $controller = null; /** * Whether we are using a non-default theme or not. * * If we are using a theme, this variable holds an array with two keys: "module" and "name", those being the name * of the module and the name of the theme, respectively. If we are using the default theme, the variable has * the 'default' string in the "name" key, and 'null' in the "module" key. * * @var array */ private $theme = ['module' => null, 'name' => 'default']; /** * Constructor * * @param \SimpleSAML\Configuration $configuration Configuration object * @param string $template Which template file to load * @param string|null $defaultDictionary The default dictionary where tags will come from. */ public function __construct(Configuration $configuration, $template, $defaultDictionary = null) { $this->configuration = $configuration; $this->template = $template; // TODO: do not remove the slash from the beginning, change the templates instead! $this->data['baseurlpath'] = ltrim($this->configuration->getBasePath(), '/'); // parse module and template name list($this->module) = $this->findModuleAndTemplateName($template); // parse config to find theme and module theme is in, if any list($this->theme['module'], $this->theme['name']) = $this->findModuleAndTemplateName( $this->configuration->getString('theme.use', 'default') ); // initialize internationalization system $this->translator = new Translate($configuration, $defaultDictionary); $this->localization = new Localization($configuration); // check if we are supposed to use the new UI $this->useNewUI = $this->configuration->getBoolean('usenewui', false); if ($this->useNewUI) { // check if we need to attach a theme controller $controller = $this->configuration->getString('theme.controller', false); if ( $controller && class_exists($controller) && in_array(TemplateControllerInterface::class, class_implements($controller)) ) { /** @var \SimpleSAML\XHTML\TemplateControllerInterface $this->controller */ $this->controller = new $controller(); } $this->twig = $this->setupTwig(); } $this->charset = 'UTF-8'; parent::__construct(); } /** * Return the URL of an asset, including a cache-buster parameter that depends on the last modification time of * the original file. * @param string $asset * @param string|null $module * @return string */ public function asset($asset, $module = null) { $baseDir = $this->configuration->getBaseDir(); if (is_null($module)) { $file = $baseDir . 'www/assets/' . $asset; $basePath = $this->configuration->getBasePath(); $path = $basePath . 'assets/' . $asset; } else { $file = $baseDir . 'modules/' . $module . '/www/assets/' . $asset; $path = Module::getModuleUrl($module . '/assets/' . $asset); } if (!file_exists($file)) { // don't be too harsh if an asset is missing, just pretend it's there... return $path; } $tag = $this->configuration->getVersion(); if ($tag === 'master') { $tag = strval(filemtime($file)); } $tag = substr(hash('md5', $tag), 0, 5); return $path . '?tag=' . $tag; } /** * Get the normalized template name. * * @return string The name of the template to use. */ public function getTemplateName() { return $this->normalizeTemplateName($this->template); } /** * Normalize the name of the template to one of the possible alternatives. * * @param string $templateName The template name to normalize. * @return string The filename we need to look for. */ private function normalizeTemplateName(string $templateName): string { if (strripos($templateName, '.twig')) { return $templateName; } $phppos = strripos($templateName, '.php'); if ($phppos) { $templateName = substr($templateName, 0, $phppos); } $tplpos = strripos($templateName, '.tpl'); if ($tplpos) { $templateName = substr($templateName, 0, $tplpos); } if ($this->useNewUI) { return $templateName . '.twig'; } return $templateName; } /** * Set up the places where twig can look for templates. * * @return TemplateLoader The twig template loader or false if the template does not exist. * @throws \Twig\Error\LoaderError In case a failure occurs. */ private function setupTwigTemplatepaths(): TemplateLoader { $filename = $this->normalizeTemplateName($this->template); // get namespace if any list($namespace, $filename) = $this->findModuleAndTemplateName($filename); $this->twig_template = ($namespace !== null) ? '@' . $namespace . '/' . $filename : $filename; $loader = new TemplateLoader(); $templateDirs = $this->findThemeTemplateDirs(); if ($this->module && $this->module != 'core') { $modDir = TemplateLoader::getModuleTemplateDir($this->module); $templateDirs[] = [$this->module => $modDir]; $templateDirs[] = ['__parent__' => $modDir]; } if ($this->theme['module']) { try { $templateDirs[] = [ $this->theme['module'] => TemplateLoader::getModuleTemplateDir($this->theme['module']) ]; } catch (\InvalidArgumentException $e) { // either the module is not enabled or it has no "templates" directory, ignore } } $templateDirs[] = ['core' => TemplateLoader::getModuleTemplateDir('core')]; // default, themeless templates are checked last $templateDirs[] = [ FilesystemLoader::MAIN_NAMESPACE => $this->configuration->resolvePath('templates') ]; foreach ($templateDirs as $entry) { $loader->addPath($entry[key($entry)], key($entry)); } return $loader; } /** * Setup twig. * @return \Twig\Environment * @throws \Exception if the template does not exist */ private function setupTwig(): \Twig\Environment { $auto_reload = $this->configuration->getBoolean('template.auto_reload', true); $cache = $this->configuration->getString('template.cache', false); // set up template paths $loader = $this->setupTwigTemplatepaths(); // abort if twig template does not exist if (!$loader->exists($this->twig_template)) { throw new \Exception('Template-file \"' . $this->getTemplateName() . '\" does not exist.'); } // load extra i18n domains if ($this->module) { $this->localization->addModuleDomain($this->module); } if ($this->theme['module'] !== null && $this->theme['module'] !== $this->module) { $this->localization->addModuleDomain($this->theme['module']); } // set up translation $options = [ 'auto_reload' => $auto_reload, 'cache' => $cache, 'strict_variables' => true, 'translation_function' => [Translate::class, 'translateSingularGettext'], 'translation_function_plural' => [Translate::class, 'translatePluralGettext'], ]; $twig = new Twig_Environment($loader, $options); $twig->addExtension(new Twig_Extensions_Extension_I18n()); $twig->addExtension(new \Twig\Extensions\DateExtension()); $twig->addFunction(new TwigFunction('moduleURL', [Module::class, 'getModuleURL'])); // initialize some basic context $langParam = $this->configuration->getString('language.parameter.name', 'language'); $twig->addGlobal('languageParameterName', $langParam); $twig->addGlobal('localeBackend', Localization::GETTEXT_I18N_BACKEND); $twig->addGlobal('currentLanguage', $this->translator->getLanguage()->getLanguage()); $twig->addGlobal('isRTL', false); // language RTL configuration if ($this->translator->getLanguage()->isLanguageRTL()) { $twig->addGlobal('isRTL', true); } $queryParams = $_GET; // add query parameters, in case we need them in the template if (isset($queryParams[$langParam])) { unset($queryParams[$langParam]); } $twig->addGlobal('queryParams', $queryParams); $twig->addGlobal('templateId', str_replace('.twig', '', $this->normalizeTemplateName($this->template))); $twig->addGlobal('isProduction', $this->configuration->getBoolean('production', true)); $twig->addGlobal('baseurlpath', ltrim($this->configuration->getBasePath(), '/')); // add a filter for translations out of arrays $twig->addFilter( new TwigFilter( 'translateFromArray', [Translate::class, 'translateFromArray'], ['needs_context' => true] ) ); // add an asset() function $twig->addFunction(new TwigFunction('asset', [$this, 'asset'])); if ($this->controller !== null) { $this->controller->setUpTwig($twig); } return $twig; } /** * Add overriding templates from the configured theme. * * @return array An array of module => templatedir lookups. */ private function findThemeTemplateDirs(): array { if (!isset($this->theme['module'])) { // no module involved return []; } // setup directories & namespaces $themeDir = Module::getModuleDir($this->theme['module']) . '/themes/' . $this->theme['name']; $subdirs = scandir($themeDir); if (empty($subdirs)) { // no subdirectories in the theme directory, nothing to do here // this is probably wrong, log a message Logger::warning('Empty theme directory for theme "' . $this->theme['name'] . '".'); return []; } $themeTemplateDirs = []; foreach ($subdirs as $entry) { // discard anything that's not a directory. Expression is negated to profit from lazy evaluation if (!($entry !== '.' && $entry !== '..' && is_dir($themeDir . '/' . $entry))) { continue; } // set correct name for the default namespace $ns = ($entry === 'default') ? FilesystemLoader::MAIN_NAMESPACE : $entry; $themeTemplateDirs[] = [$ns => $themeDir . '/' . $entry]; } return $themeTemplateDirs; } /** * Get the template directory of a module, if it exists. * * @param string $module * @return string The templates directory of a module * * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory. */ private function getModuleTemplateDir(string $module): string { if (!Module::isModuleEnabled($module)) { throw new \InvalidArgumentException('The module \'' . $module . '\' is not enabled.'); } $moduledir = Module::getModuleDir($module); // check if module has a /templates dir, if so, append $templatedir = $moduledir . '/templates'; if (!is_dir($templatedir)) { throw new \InvalidArgumentException('The module \'' . $module . '\' has no templates directory.'); } return $templatedir; } /** * Add the templates from a given module. * * Note that the module must be installed, enabled, and contain a "templates" directory. * * @param string $module The module where we need to search for templates. * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory. * @return void */ public function addTemplatesFromModule($module) { $dir = TemplateLoader::getModuleTemplateDir($module); /** @var \Twig\Loader\FilesystemLoader $loader */ $loader = $this->twig->getLoader(); $loader->addPath($dir, $module); } /** * Generate an array for its use in the language bar, indexed by the ISO 639-2 codes of the languages available, * containing their localized names and the URL that should be used in order to change to that language. * * @return array|null The array containing information of all available languages. */ private function generateLanguageBar(): ?array { $languages = $this->translator->getLanguage()->getLanguageList(); ksort($languages); $langmap = null; if (count($languages) > 1) { $parameterName = $this->getTranslator()->getLanguage()->getLanguageParameterName(); $langmap = []; foreach ($languages as $lang => $current) { $lang = strtolower($lang); $langname = $this->translator->getLanguage()->getLanguageLocalizedName($lang); $url = false; if (!$current) { $url = htmlspecialchars(Utils\HTTP::addURLParameters( '', [$parameterName => $lang] )); } $langmap[$lang] = [ 'name' => $langname, 'url' => $url, ]; } } return $langmap; } /** * Set some default context * @return void */ private function twigDefaultContext(): void { // show language bar by default if (!isset($this->data['hideLanguageBar'])) { $this->data['hideLanguageBar'] = false; } // get languagebar $this->data['languageBar'] = null; if ($this->data['hideLanguageBar'] === false) { $languageBar = $this->generateLanguageBar(); if (is_null($languageBar)) { $this->data['hideLanguageBar'] = true; } else { $this->data['languageBar'] = $languageBar; } } // assure that there is a and <h1> if (isset($this->data['header']) && !isset($this->data['pagetitle'])) { $this->data['pagetitle'] = $this->data['header']; } if (!isset($this->data['pagetitle'])) { $this->data['pagetitle'] = 'SimpleSAMLphp'; } $this->data['year'] = date('Y'); $this->data['header'] = $this->configuration->getValue('theme.header', 'SimpleSAMLphp'); } /** * Get the contents produced by this template. * * @return string The HTML rendered by this template, as a string. * @throws \Exception if the template cannot be found. */ protected function getContents() { $this->twigDefaultContext(); if ($this->controller) { $this->controller->display($this->data); } try { return $this->twig->render($this->twig_template, $this->data); } catch (\Twig\Error\RuntimeError $e) { throw new \SimpleSAML\Error\Exception(substr($e->getMessage(), 0, -1) . ' in ' . $this->template, 0, $e); } } /** * Send this template as a response. * * @return $this This response. * @throws \Exception if the template cannot be found. * * Note: No return type possible due to upstream limitations */ public function send() { $this->content = $this->getContents(); return parent::send(); } /** * Show the template to the user. * * This method is a remnant of the old templating system, where templates where shown manually instead of * returning a response. * * @return void * @deprecated Do not use this method, use Twig + send() instead. Will be removed in 2.0 */ public function show() { if ($this->useNewUI) { echo $this->getContents(); } else { require($this->findTemplatePath($this->template)); } } /** * Find module the template is in, if any * * @param string $template The relative path from the theme directory to the template file. * * @return array An array with the name of the module and template */ private function findModuleAndTemplateName(string $template): array { $tmp = explode(':', $template, 2); return (count($tmp) === 2) ? [$tmp[0], $tmp[1]] : [null, $tmp[0]]; } /** * 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. * @param bool $throw_exception * * @return string|null The absolute path to the template file. * * @throws \Exception If the template file couldn't be found. */ private function findTemplatePath(string $template, bool $throw_exception = true): ?string { $extensions = ['.tpl.php', '.php']; list($templateModule, $templateName) = $this->findModuleAndTemplateName($template); $templateModule = ($templateModule !== null) ? $templateModule : 'default'; // first check the current theme if ($this->theme['module'] !== null) { // .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName> $filename = Module::getModuleDir($this->theme['module']) . '/themes/' . $this->theme['name'] . '/' . $templateModule . '/' . $templateName; } elseif ($templateModule !== 'default') { // .../module/<templateModule>/templates/<templateName> $filename = Module::getModuleDir($templateModule) . '/templates/' . $templateName; } else { // .../templates/<theme>/<templateName> $base = $this->configuration->getPathValue('templatedir', 'templates/') ?: 'templates/'; $filename = $base . $templateName; } $filename = $this->normalizeTemplateName($filename); foreach ($extensions as $extension) { if (file_exists($filename . $extension)) { return $filename . $extension; } } // not found in current theme 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 = Module::getModuleDir($templateModule) . '/templates/' . $templateName; } else { // .../templates/<templateName> $base = $this->configuration->getPathValue('templatedir', 'templates/') ?: 'templates/'; $filename = $base . '/' . $templateName; } $filename = $this->normalizeTemplateName($filename); foreach ($extensions as $extension) { if (file_exists($filename . $extension)) { return $filename . $extension; } } // not found in default template if ($throw_exception) { // log error and throw exception $error = 'Template: Could not find template file [' . $template . '] at [' . $filename . ']'; Logger::critical($_SERVER['PHP_SELF'] . ' - ' . $error); throw new \Exception($error); } else { // missing template expected, return NULL return null; } } /** * Return the internal translator object used by this template. * * @return \SimpleSAML\Locale\Translate The translator that will be used with this template. */ public function getTranslator() { return $this->translator; } /** * Return the internal localization object used by this template. * * @return \SimpleSAML\Locale\Localization The localization object that will be used with this template. */ public function getLocalization() { return $this->localization; } /** * Get the current instance of Twig in use. * * @return \Twig\Environment The Twig instance in use, or null if Twig is not used. */ public function getTwig() { return $this->twig; } /* * Deprecated methods of this interface, all of them should go away. */ /** * @param string $name * * @return string * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguage() * instead. */ public function getAttributeTranslation($name) { return $this->translator->getAttributeTranslation($name); } /** * @return string * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguage() * instead. */ public function getLanguage() { return $this->translator->getLanguage()->getLanguage(); } /** * @param string $language * @param bool $setLanguageCookie * @return void * * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguage() * instead. */ public function setLanguage($language, $setLanguageCookie = true) { $this->translator->getLanguage()->setLanguage($language, $setLanguageCookie); } /** * @return null|string * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguageCookie() * instead. */ public static function getLanguageCookie() { return Language::getLanguageCookie(); } /** * @param string $language * @return void * * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguageCookie() * instead. */ public static function setLanguageCookie($language) { Language::setLanguageCookie($language); } /** * Wraps Language->getLanguageList * * @return array */ private function getLanguageList(): array { return $this->translator->getLanguage()->getLanguageList(); } /** * @param string $tag * * @return array|null * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::getTag() instead. */ public function getTag($tag) { return $this->translator->getTag($tag); } /** * Temporary wrapper for \SimpleSAML\Locale\Translate::getPreferredTranslation(). * * @deprecated This method will be removed in SSP 2.0. Please use * \SimpleSAML\Locale\Translate::getPreferredTranslation() instead. * * @param array $translations * @return string */ public function getTranslation($translations) { return $this->translator->getPreferredTranslation($translations); } /** * Includes a file relative to the template base directory. * This function can be used to include headers and footers etc. * * @deprecated This function will be removed in SSP 2.0. Use Twig-templates instead * @param string $file * @return void */ private function includeAtTemplateBase(string $file): void { $data = $this->data; $filename = $this->findTemplatePath($file); include($filename); } /** * Wraps Translate->includeInlineTranslation() * * @see \SimpleSAML\Locale\Translate::includeInlineTranslation() * @deprecated This method will be removed in SSP 2.0. Please use * \SimpleSAML\Locale\Translate::includeInlineTranslation() instead. * * @param string $tag * @param string $translation * @return void */ public function includeInlineTranslation($tag, $translation) { $this->translator->includeInlineTranslation($tag, $translation); } /** * @param string $file * @param \SimpleSAML\Configuration|null $otherConfig * @return void * * @deprecated This method will be removed in SSP 2.0. Please use * \SimpleSAML\Locale\Translate::includeLanguageFile() instead. */ public function includeLanguageFile($file, $otherConfig = null) { $this->translator->includeLanguageFile($file, $otherConfig); } /** * Wrap Language->isLanguageRTL * * @return bool */ private function isLanguageRTL(): bool { return $this->translator->getLanguage()->isLanguageRTL(); } /** * Merge two translation arrays. * * @param array $def The array holding string definitions. * @param array $lang The array holding translations for every string. * * @return array The recursive merge of both arrays. * @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use array_merge_recursive() instead. */ public static function lang_merge($def, $lang) { foreach ($def as $key => $value) { if (array_key_exists($key, $lang)) { $def[$key] = array_merge($value, $lang[$key]); } } return $def; } /** * Behave like Language->noop to mark a tag for translation but actually do it later. * * @see \SimpleSAML\Locale\Translate::noop() * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::noop() instead. * * @param string $tag * @return string */ public static function noop($tag) { return $tag; } /** * Wrap Language->t to translate tag into the current language, with a fallback to english. * * @see \SimpleSAML\Locale\Translate::t() * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::t() instead. * * @param string $tag * @param array $replacements * @param bool $fallbackdefault * @param array $oldreplacements * @param bool $striptags * @return string|null */ public function t( $tag, $replacements = [], $fallbackdefault = true, $oldreplacements = [], $striptags = false ) { return $this->translator->t($tag, $replacements, $fallbackdefault, $oldreplacements, $striptags); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/XHTML/IdPDisco.php����������������������������������������������0000644�0000000�0000000�00000050561�14042503475�020711� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML\XHTML; use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Session; use SimpleSAML\Utils; /** * This class implements a generic IdP discovery service, for use in various IdP * discovery service pages. This should reduce code duplication. * * Experimental support added for Extended IdP Metadata Discovery Protocol by Andreas 2008-08-28 * More information: https://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-idp-discovery.pdf * * @author Jaime Pérez <jaime.perez@uninett.no>, UNINETT AS. * @author Olav Morken, UNINETT AS. * @author Andreas Åkre Solberg <andreas@uninett.no>, UNINETT AS. * @package SimpleSAMLphp */ class IdPDisco { /** * An instance of the configuration class. * * @var \SimpleSAML\Configuration */ protected $config; /** * The identifier of this discovery service. * * @var string */ protected $instance; /** * An instance of the metadata handler, which will allow us to fetch metadata about IdPs. * * @var \SimpleSAML\Metadata\MetaDataStorageHandler */ protected $metadata; /** * The users session. * * @var \SimpleSAML\Session */ protected $session; /** * The metadata sets we find allowed entities in, in prioritized order. * * @var array */ protected $metadataSets; /** * The entity id of the SP which accesses this IdP discovery service. * * @var string */ protected $spEntityId; /** * HTTP parameter from the request, indicating whether the discovery service * can interact with the user or not. * * @var boolean */ protected $isPassive; /** * The SP request to set the IdPentityID... * * @var string|null */ protected $setIdPentityID = null; /** * The name of the query parameter which should contain the users choice of IdP. * This option default to 'entityID' for Shibboleth compatibility. * * @var string */ protected $returnIdParam; /** * The list of scoped idp's. The intersection between the metadata idpList * and scopedIDPList (given as a $_GET IDPList[] parameter) is presented to * the user. If the intersection is empty the metadata idpList is used. * * @var array */ protected $scopedIDPList = []; /** * The URL the user should be redirected to after choosing an IdP. * * @var string */ protected $returnURL; /** * 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. * * @throws \Exception If the request is invalid. */ public function __construct(array $metadataSets, $instance) { assert(is_string($instance)); // initialize standard classes $this->config = Configuration::getInstance(); $this->metadata = MetaDataStorageHandler::getMetadataHandler(); $this->session = Session::getSessionFromRequest(); $this->instance = $instance; $this->metadataSets = $metadataSets; $this->log('Accessing discovery service.'); // standard discovery service parameters if (!array_key_exists('entityID', $_GET)) { throw new \Exception('Missing parameter: entityID'); } else { $this->spEntityId = $_GET['entityID']; } if (!array_key_exists('returnIDParam', $_GET)) { $this->returnIdParam = 'entityID'; } else { $this->returnIdParam = $_GET['returnIDParam']; } $this->log('returnIdParam initially set to [' . $this->returnIdParam . ']'); if (!array_key_exists('return', $_GET)) { throw new \Exception('Missing parameter: return'); } else { $this->returnURL = Utils\HTTP::checkURLAllowed($_GET['return']); } $this->isPassive = false; if (array_key_exists('isPassive', $_GET)) { if ($_GET['isPassive'] === 'true') { $this->isPassive = true; } } $this->log('isPassive initially set to [' . ($this->isPassive ? 'TRUE' : 'FALSE') . ']'); if (array_key_exists('IdPentityID', $_GET)) { $this->setIdPentityID = $_GET['IdPentityID']; } if (array_key_exists('IDPList', $_REQUEST)) { $this->scopedIDPList = $_REQUEST['IDPList']; } } /** * Log a message. * * This is an helper function for logging messages. It will prefix the messages with our * discovery service type. * * @param string $message The message which should be logged. * @return void */ protected function log($message) { Logger::info('idpDisco.' . $this->instance . ': ' . $message); } /** * Retrieve cookie with the given name. * * This function will retrieve a cookie with the given name for the current discovery * service type. * * @param string $name The name of the cookie. * * @return string|null The value of the cookie with the given name, or null if no cookie with that name exists. */ protected function getCookie($name) { $prefixedName = 'idpdisco_' . $this->instance . '_' . $name; if (array_key_exists($prefixedName, $_COOKIE)) { return $_COOKIE[$prefixedName]; } else { return null; } } /** * Save cookie with the given name and value. * * This function will save a cookie with the given name and value for the current discovery * service type. * * @param string $name The name of the cookie. * @param string $value The value of the cookie. * @return void */ protected function setCookie($name, $value) { $prefixedName = 'idpdisco_' . $this->instance . '_' . $name; $params = [ // we save the cookies for 90 days 'lifetime' => (60 * 60 * 24 * 90), // the base path for cookies. This should be the installation directory for SimpleSAMLphp 'path' => $this->config->getBasePath(), 'httponly' => false, ]; Utils\HTTP::setCookie($prefixedName, $value, $params, false); } /** * Validates the given IdP entity id. * * Takes a string with the IdP entity id, and returns the entity id if it is valid, or * null if not. * * @param string|null $idp The entity id we want to validate. This can be null, in which case we will return null. * * @return string|null The entity id if it is valid, null if not. */ protected function validateIdP($idp) { if ($idp === null) { return null; } if (!$this->config->getBoolean('idpdisco.validate', true)) { return $idp; } foreach ($this->metadataSets as $metadataSet) { try { $this->metadata->getMetaData($idp, $metadataSet); return $idp; } catch (\Exception $e) { // continue } } $this->log('Unable to validate IdP entity id [' . $idp . '].'); // the entity id wasn't valid return null; } /** * Retrieve the users choice of IdP. * * This function finds out which IdP the user has manually chosen, if any. * * @return string|null The entity id of the IdP the user has chosen, or null if the user has made no choice. */ protected function getSelectedIdP() { /* Parameter set from the Extended IdP Metadata Discovery Service Protocol, indicating that the user prefers * this IdP. */ if (!empty($this->setIdPentityID)) { return $this->validateIdP($this->setIdPentityID); } // user has clicked on a link, or selected the IdP from a drop-down list if (array_key_exists('idpentityid', $_GET)) { return $this->validateIdP($_GET['idpentityid']); } /* Search for the IdP selection from the form used by the links view. This form uses a name which equals * idp_<entityid>, so we search for that. * * Unfortunately, php replaces periods in the name with underscores, and there is no reliable way to get them * back. Therefore we do some quick and dirty parsing of the query string. */ $qstr = $_SERVER['QUERY_STRING']; $matches = []; if (preg_match('/(?:^|&)idp_([^=]+)=/', $qstr, $matches)) { return $this->validateIdP(urldecode($matches[1])); } // no IdP chosen return null; } /** * Retrieve the users saved choice of IdP. * * @return string|null The entity id of the IdP the user has saved, or null if the user hasn't saved any choice. */ protected function getSavedIdP() { if (!$this->config->getBoolean('idpdisco.enableremember', false)) { // saving of IdP choices is disabled return null; } if ($this->getCookie('remember') === '1') { $this->log('Return previously saved IdP because of remember cookie set to 1'); return $this->getPreviousIdP(); } if ($this->isPassive) { $this->log('Return previously saved IdP because of isPassive'); return $this->getPreviousIdP(); } return null; } /** * Retrieve the previous IdP the user used. * * @return string|null The entity id of the previous IdP the user used, or null if this is the first time. */ protected function getPreviousIdP() { return $this->validateIdP($this->getCookie('lastidp')); } /** * Retrieve a recommended IdP based on the IP address of the client. * * @return string|null The entity ID of the IdP if one is found, or null if not. */ protected function getFromCIDRhint() { foreach ($this->metadataSets as $metadataSet) { $idp = $this->metadata->getPreferredEntityIdFromCIDRhint($metadataSet, $_SERVER['REMOTE_ADDR']); if (!empty($idp)) { return $idp; } } return null; } /** * Try to determine which IdP the user should most likely use. * * This function will first look at the previous IdP the user has chosen. If the user * hasn't chosen an IdP before, it will look at the IP address. * * @return string|null The entity id of the IdP the user should most likely use. */ protected function getRecommendedIdP() { $idp = $this->getPreviousIdP(); if ($idp !== null) { $this->log('Preferred IdP from previous use [' . $idp . '].'); return $idp; } $idp = $this->getFromCIDRhint(); if (!empty($idp)) { $this->log('Preferred IdP from CIDR hint [' . $idp . '].'); return $idp; } return null; } /** * Save the current IdP choice to a cookie. * * @param string $idp The entityID of the IdP. * @return void */ protected function setPreviousIdP($idp) { assert(is_string($idp)); $this->log('Choice made [' . $idp . '] Setting cookie.'); $this->setCookie('lastidp', $idp); } /** * Determine whether the choice of IdP should be saved. * * @return boolean True if the choice should be saved, false otherwise. */ protected function saveIdP() { if (!$this->config->getBoolean('idpdisco.enableremember', false)) { // saving of IdP choices is disabled return false; } if (array_key_exists('remember', $_GET)) { return true; } return false; } /** * Determine which IdP the user should go to, if any. * * @return string|null The entity id of the IdP the user should be sent to, or null if the user should choose. */ protected function getTargetIdP() { // first, check if the user has chosen an IdP $idp = $this->getSelectedIdP(); if ($idp !== null) { // the user selected this IdP. Save the choice in a cookie $this->setPreviousIdP($idp); if ($this->saveIdP()) { $this->setCookie('remember', '1'); } else { $this->setCookie('remember', '0'); } return $idp; } $this->log('getSelectedIdP() returned null'); // check if the user has saved an choice earlier $idp = $this->getSavedIdP(); if ($idp !== null) { $this->log('Using saved choice [' . $idp . '].'); return $idp; } // the user has made no choice return null; } /** * Retrieve the list of IdPs which are stored in the metadata. * * @return array An array with entityid => metadata mappings. */ protected function getIdPList() { $idpList = []; foreach ($this->metadataSets as $metadataSet) { $newList = $this->metadata->getList($metadataSet); /* * Note that we merge the entities in reverse order. This ensures that it is the entity in the first * metadata set that "wins" if two metadata sets have the same entity. */ $idpList = array_merge($newList, $idpList); } return $idpList; } /** * Return the list of scoped idp * * @return array An array of IdP entities */ protected function getScopedIDPList() { return $this->scopedIDPList; } /** * Filter the list of IdPs. * * This method returns the IdPs that comply with the following conditions: * - The IdP does not have the 'hide.from.discovery' configuration option. * * @param array $list An associative array containing metadata for the IdPs to apply the filtering to. * * @return array An associative array containing metadata for the IdPs that were not filtered out. */ protected function filterList($list) { foreach ($list as $entity => $metadata) { if (array_key_exists('hide.from.discovery', $metadata) && $metadata['hide.from.discovery'] === true) { unset($list[$entity]); } } return $list; } /** * Check if an IdP is set or if the request is passive, and redirect accordingly. * * @return void If there is no IdP targeted and this is not a passive request. */ protected function start() { $idp = $this->getTargetIdP(); if ($idp !== null) { $extDiscoveryStorage = $this->config->getString('idpdisco.extDiscoveryStorage', null); if ($extDiscoveryStorage !== null) { $this->log('Choice made [' . $idp . '] (Forwarding to external discovery storage)'); Utils\HTTP::redirectTrustedURL($extDiscoveryStorage, [ 'entityID' => $this->spEntityId, 'IdPentityID' => $idp, 'returnIDParam' => $this->returnIdParam, 'isPassive' => 'true', 'return' => $this->returnURL ]); } else { $this->log( 'Choice made [' . $idp . '] (Redirecting the user back. returnIDParam=' . $this->returnIdParam . ')' ); Utils\HTTP::redirectTrustedURL($this->returnURL, [$this->returnIdParam => $idp]); } } if ($this->isPassive) { $this->log('Choice not made. (Redirecting the user back without answer)'); Utils\HTTP::redirectTrustedURL($this->returnURL); } } /** * Handles a request to this discovery service. * * The IdP disco parameters should be set before calling this function. * @return void */ 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 . ')' ); Utils\HTTP::redirectTrustedURL( $this->returnURL, [$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 Template($this->config, $templateFile, 'disco'); $fallbackLanguage = 'en'; $defaultLanguage = $this->config->getString('language.default', $fallbackLanguage); $translator = $t->getTranslator(); $language = $translator->getLanguage()->getLanguage(); $tryLanguages = [0 => $language, 1 => $defaultLanguage, 2 => $fallbackLanguage]; $newlist = []; foreach ($idpList as $entityid => $data) { $newlist[$entityid]['entityid'] = $entityid; foreach ($tryLanguages as $lang) { if ($name = $this->getEntityDisplayName($data, $lang)) { $newlist[$entityid]['name'] = $name; continue; } } if (empty($newlist[$entityid]['name'])) { $newlist[$entityid]['name'] = $entityid; } foreach ($tryLanguages as $lang) { if (!empty($data['description'][$lang])) { $newlist[$entityid]['description'] = $data['description'][$lang]; continue; } } if (!empty($data['icon'])) { $newlist[$entityid]['icon'] = $data['icon']; $newlist[$entityid]['iconurl'] = Utils\HTTP::resolveURL($data['icon']); } } usort( $newlist, /** * @param array $idpentry1 * @param array $idpentry2 * @return int */ function (array $idpentry1, array $idpentry2) { return strcasecmp($idpentry1['name'], $idpentry2['name']); } ); $t->data['idplist'] = $newlist; $t->data['preferredidp'] = $preferredIdP; $t->data['return'] = $this->returnURL; $t->data['returnIDParam'] = $this->returnIdParam; $t->data['entityID'] = $this->spEntityId; $t->data['urlpattern'] = htmlspecialchars(Utils\HTTP::getSelfURLNoQuery()); $t->data['rememberenabled'] = $this->config->getBoolean('idpdisco.enableremember', false); $t->show(); } /** * @param array $idpData * @param string $language * @return string|null */ private function getEntityDisplayName(array $idpData, string $language): ?string { if (isset($idpData['UIInfo']['DisplayName'][$language])) { return $idpData['UIInfo']['DisplayName'][$language]; } elseif (isset($idpData['name'][$language])) { return $idpData['name'][$language]; } elseif (isset($idpData['OrganizationDisplayName'][$language])) { return $idpData['OrganizationDisplayName'][$language]; } return null; } } �����������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/XHTML/TemplateControllerInterface.php���������������������������0000644�0000000�0000000�00000001462�14042503475�024707� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML\XHTML; use Twig\Environment; /** * Interface that allows modules to run several hooks for templates. * * @package SimpleSAMLphp */ interface TemplateControllerInterface { /** * Implement to modify the twig environment after its initialization (e.g. add filters or extensions). * * @param \Twig\Environment $twig The current twig environment. * * @return void */ public function setUpTwig(Environment &$twig); /** * Implement to add, delete or modify the data passed to the template. * * This method will be called right before displaying the template. * * @param array $data The current data used by the template. * * @return void */ public function display(&$data); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/XHTML/TemplateLoader.php����������������������������������������0000644�0000000�0000000�00000005441�14042503475�022152� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML\XHTML; use SimpleSAML\Module; /** * This class extends the Twig\Loader\FilesystemLoader so that we can load templates from modules in twig, even * when the main template is not part of a module (or the same one). * * @package simplesamlphp/simplesamlphp * * @psalm-suppress DeprecatedInterface This suppress may be removed when Twig 3.0 becomes the default */ class TemplateLoader extends \Twig\Loader\FilesystemLoader { /** * This method adds a namespace dynamically so that we can load templates from modules whenever we want. * * {@inheritdoc} * * @param string $name * @param bool $throw * @return string|false|null */ protected function findTemplate($name, $throw = true) { list($namespace, $shortname) = $this->parseModuleName($name); if (!in_array($namespace, $this->paths, true) && $namespace !== self::MAIN_NAMESPACE) { $this->addPath(self::getModuleTemplateDir($namespace), $namespace); } return parent::findTemplate($name, $throw); } /** * Parse the name of a template in a module. * * @param string $name The full name of the template, including namespace and template name / path. * @param string $default * * @return array An array with the corresponding namespace and name of the template. The namespace defaults to * \Twig\Loader\FilesystemLoader::MAIN_NAMESPACE, if none was specified in $name. */ protected function parseModuleName($name, $default = self::MAIN_NAMESPACE) { if (strpos($name, ':')) { // we have our old SSP format list($namespace, $shortname) = explode(':', $name, 2); $shortname = strtr($shortname, [ '.tpl.php' => '.twig', '.php' => '.twig', ]); return [$namespace, $shortname]; } return [$default, $name]; } /** * Get the template directory of a module, if it exists. * * @param string $module * @return string The templates directory of a module. * * @throws \InvalidArgumentException If the module is not enabled or it has no templates directory. */ public static function getModuleTemplateDir($module) { if (!Module::isModuleEnabled($module)) { throw new \InvalidArgumentException('The module \'' . $module . '\' is not enabled.'); } $moduledir = Module::getModuleDir($module); // check if module has a /templates dir, if so, append $templatedir = $moduledir . '/templates'; if (!is_dir($templatedir)) { throw new \InvalidArgumentException('The module \'' . $module . '\' has no templates directory.'); } return $templatedir; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/Module.php������������������������������������������������������0000644�0000000�0000000�00000051447�14042503475�017610� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML; use SimpleSAML\Kernel; use SimpleSAML\Utils; use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Helper class for accessing information about modules. * * @author Olav Morken <olav.morken@uninett.no>, UNINETT AS. * @author Boy Baukema, SURFnet. * @author Jaime Perez <jaime.perez@uninett.no>, UNINETT AS. * @package SimpleSAMLphp */ class Module { /** * Index pages: file names to attempt when accessing directories. * * @var array */ public static $indexFiles = ['index.php', 'index.html', 'index.htm', 'index.txt']; /** * MIME Types * * The key is the file extension and the value the corresponding MIME type. * * @var array */ public static $mimeTypes = [ 'bmp' => 'image/x-ms-bmp', 'css' => 'text/css', 'gif' => 'image/gif', 'htm' => 'text/html', 'html' => 'text/html', 'shtml' => 'text/html', 'ico' => 'image/vnd.microsoft.icon', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'js' => 'text/javascript', 'pdf' => 'application/pdf', 'png' => 'image/png', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', 'swf' => 'application/x-shockwave-flash', 'swfl' => 'application/x-shockwave-flash', 'txt' => 'text/plain', 'xht' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml', ]; /** * A list containing the modules currently installed. * * @var array */ public static $modules = []; /** * A cache containing specific information for modules, like whether they are enabled or not, or their hooks. * * @var array */ public static $module_info = []; /** * Retrieve the base directory for a module. * * The returned path name will be an absolute path. * * @param string $module Name of the module * * @return string The base directory of a module. */ public static function getModuleDir($module) { $baseDir = dirname(dirname(dirname(__FILE__))) . '/modules'; $moduleDir = $baseDir . '/' . $module; return $moduleDir; } /** * Determine whether a module is enabled. * * Will return false if the given module doesn't exist. * * @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) { $config = Configuration::getOptionalConfig(); return self::isModuleEnabledWithConf($module, $config->getArray('module.enable', [])); } /** * Handler for module requests. * * This controller receives requests for pages hosted by modules, and processes accordingly. Depending on the * configuration and the actual request, it will run a PHP script and exit, or return a Response produced either * by another controller or by a static file. * * @param Request|null $request The request to process. Defaults to the current one. * * @return Response|BinaryFileResponse Returns a Response object that can be sent to the browser. * @throws Error\BadRequest In case the request URI is malformed. * @throws Error\NotFound In case the request URI is invalid or the resource it points to cannot be found. */ public static function process(Request $request = null) { if ($request === null) { $request = Request::createFromGlobals(); } if ($request->server->get('PATH_INFO') === '/') { throw new Error\NotFound('No PATH_INFO to module.php'); } $url = $request->server->get('PATH_INFO'); assert(substr($url, 0, 1) === '/'); /* clear the PATH_INFO option, so that a script can detect whether it is called with anything following the *'.php'-ending. */ unset($_SERVER['PATH_INFO']); $modEnd = strpos($url, '/', 1); if ($modEnd === false) { $modEnd = strlen($url); $module = substr($url, 1); $url = ''; } else { $module = substr($url, 1, $modEnd - 1); $url = substr($url, $modEnd + 1); } if (!self::isModuleEnabled($module)) { throw new Error\NotFound('The module \'' . $module . '\' was either not found, or wasn\'t enabled.'); } /* Make sure that the request isn't suspicious (contains references to current directory or parent directory or * anything like that. Searching for './' in the URL will detect both '../' and './'. Searching for '\' will * detect attempts to use Windows-style paths. */ if (strpos($url, '\\') !== false) { throw new Error\BadRequest('Requested URL contained a backslash.'); } elseif (strpos($url, './') !== false) { throw new Error\BadRequest('Requested URL contained \'./\'.'); } $config = Configuration::getInstance(); // rebuild REQUEST_URI and SCRIPT_NAME just in case we need to. // This is needed for server aliases and rewrites $translated_uri = $config->getBasePath() . 'module.php/' . $module . '/' . $url; $request->server->set('REQUEST_URI', $translated_uri); $request->server->set('SCRIPT_NAME', $config->getBasePath() . 'module.php'); // strip any NULL files (form file fields with nothing selected) // because initialize() will throw an error on them $request_files = array_filter( $request->files->all(), function ($val) { return !is_null($val); } ); $request->initialize( $request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request_files, $request->server->all(), $request->getContent() ); if ($config->getBoolean('usenewui', false) === true) { try { $kernel = new Kernel($module); $response = $kernel->handle($request); $kernel->terminate($request, $response); return $response; } catch (FileLocatorFileNotFoundException $e) { // no routes configured for this module, fall back to the old system } catch (NotFoundHttpException $e) { // this module has been migrated, but the route wasn't found } } $moduleDir = self::getModuleDir($module) . '/www/'; // check for '.php/' in the path, the presence of which indicates that another php-script should handle the // request for ($phpPos = strpos($url, '.php/'); $phpPos !== false; $phpPos = strpos($url, '.php/', $phpPos + 1)) { $newURL = substr($url, 0, $phpPos + 4); $param = substr($url, $phpPos + 4); if (is_file($moduleDir . $newURL)) { /* $newPath points to a normal file. Point execution to that file, and save the remainder of the path * in PATH_INFO. */ $url = $newURL; $request->server->set('PATH_INFO', $param); $_SERVER['PATH_INFO'] = $param; break; } } $path = $moduleDir . $url; if ($path[strlen($path) - 1] === '/') { // path ends with a slash - directory reference. Attempt to find index file in directory foreach (self::$indexFiles as $if) { if (file_exists($path . $if)) { $path .= $if; break; } } } if (is_dir($path)) { /* Path is a directory - maybe no index file was found in the previous step, or maybe the path didn't end * with a slash. Either way, we don't do directory listings. */ throw new Error\NotFound('Directory listing not available.'); } if (!file_exists($path)) { // file not found Logger::info('Could not find file \'' . $path . '\'.'); throw new Error\NotFound('The URL wasn\'t found in the module.'); } if (mb_strtolower(substr($path, -4), 'UTF-8') === '.php') { // PHP file - attempt to run it /* In some environments, $_SERVER['SCRIPT_NAME'] is already set with $_SERVER['PATH_INFO']. Check for that * case, and append script name only if necessary. * * Contributed by Travis Hegner. */ $script = "/$module/$url"; if (strpos($request->getScriptName(), $script) === false) { $request->server->set('SCRIPT_NAME', $request->getScriptName() . '/' . $module . '/' . $url); } require($path); exit(); } // some other file type - attempt to serve it // find MIME type for file, based on extension $contentType = null; if (preg_match('#\.([^/\.]+)$#D', $path, $type)) { $type = strtolower($type[1]); if (array_key_exists($type, self::$mimeTypes)) { $contentType = self::$mimeTypes[$type]; } } if ($contentType === null) { /* We were unable to determine the MIME type from the file extension. Fall back to mime_content_type (if it * exists). */ if (function_exists('mime_content_type')) { $contentType = mime_content_type($path); } else { // mime_content_type doesn't exist. Return a default MIME type Logger::warning('Unable to determine mime content type of file: ' . $path); $contentType = 'application/octet-stream'; } } /** @psalm-var \SimpleSAML\Configuration $assetConfig */ $assetConfig = $config->getConfigItem('assets'); /** @psalm-var \SimpleSAML\Configuration $cacheConfig */ $cacheConfig = $assetConfig->getConfigItem('caching'); $response = new BinaryFileResponse($path); $response->setCache([ // "public" allows response caching even if the request was authenticated, // which is exactly what we want for static resources 'public' => true, 'max_age' => strval($cacheConfig->getInteger('max_age', 86400)) ]); $response->setAutoLastModified(); if ($cacheConfig->getBoolean('etag', false)) { $response->setAutoEtag(); } $response->isNotModified($request); $response->headers->set('Content-Type', $contentType); $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE); $response->prepare($request); return $response; } /** * @param string $module * @param array $mod_config * @return bool */ private static function isModuleEnabledWithConf(string $module, array $mod_config): bool { if (isset(self::$module_info[$module]['enabled'])) { return self::$module_info[$module]['enabled']; } if (!empty(self::$modules) && !in_array($module, self::$modules, true)) { return false; } $moduleDir = self::getModuleDir($module); if (!is_dir($moduleDir)) { self::$module_info[$module]['enabled'] = false; return false; } if (isset($mod_config[$module])) { if (is_bool($mod_config[$module])) { self::$module_info[$module]['enabled'] = $mod_config[$module]; return $mod_config[$module]; } throw new \Exception("Invalid module.enable value for the '$module' module."); } if ( assert_options(ASSERT_ACTIVE) && !file_exists($moduleDir . '/default-enable') && !file_exists($moduleDir . '/default-disable') ) { Logger::error("Missing default-enable or default-disable file for the module $module"); } if (file_exists($moduleDir . '/enable')) { self::$module_info[$module]['enabled'] = true; return true; } if (!file_exists($moduleDir . '/disable') && file_exists($moduleDir . '/default-enable')) { self::$module_info[$module]['enabled'] = true; return true; } self::$module_info[$module]['enabled'] = false; return false; } /** * Get available modules. * * @return array One string for each module. * * @throws \Exception If we cannot open the module's directory. */ public static function getModules() { if (!empty(self::$modules)) { return self::$modules; } $path = self::getModuleDir('.'); $dh = scandir($path); if ($dh === false) { throw new \Exception('Unable to open module directory "' . $path . '".'); } foreach ($dh as $f) { if ($f[0] === '.') { continue; } if (!is_dir($path . '/' . $f)) { continue; } self::$modules[] = $f; } return self::$modules; } /** * Resolve module class. * * This function takes a string on the form "<module>:<class>" and converts it to a class * name. It can also check that the given class is a subclass of a specific class. The * resolved classname will be "\SimleSAML\Module\<module>\<$type>\<class>. * * It is also possible to specify a full classname instead of <module>:<class>. * * An exception will be thrown if the class can't be resolved. * * @param string $id The string we should resolve. * @param string $type The type of the class. * @param string|null $subclass The class should be a subclass of this class. Optional. * * @return string The classname. * * @throws \Exception If the class cannot be resolved. */ public static function resolveClass($id, $type, $subclass = null) { assert(is_string($id)); assert(is_string($type)); assert(is_string($subclass) || $subclass === null); $tmp = explode(':', $id, 2); if (count($tmp) === 1) { // no module involved $className = $tmp[0]; if (!class_exists($className)) { throw new \Exception("Could not resolve '$id': no class named '$className'."); } } else { // should be a module // make sure empty types are handled correctly $type = (empty($type)) ? '\\' : '\\' . $type . '\\'; $className = 'SimpleSAML\\Module\\' . $tmp[0] . $type . $tmp[1]; if (!class_exists($className)) { // check for the old-style class names $type = str_replace('\\', '_', $type); $oldClassName = 'sspmod_' . $tmp[0] . $type . $tmp[1]; if (!class_exists($oldClassName)) { throw new \Exception("Could not resolve '$id': no class named '$className' or '$oldClassName'."); } $className = $oldClassName; } } if ($subclass !== null && !is_subclass_of($className, $subclass)) { throw new \Exception( 'Could not resolve \'' . $id . '\': The class \'' . $className . '\' isn\'t a subclass of \'' . $subclass . '\'.' ); } return $className; } /** * Get absolute URL to a specified module resource. * * This function creates an absolute URL to a resource stored under ".../modules/<module>/www/". * * @param string $resource Resource path, on the form "<module name>/<resource>" * @param array $parameters Extra parameters which should be added to the URL. Optional. * * @return string The absolute URL to the given resource. */ public static function getModuleURL($resource, array $parameters = []) { assert(is_string($resource)); assert($resource[0] !== '/'); $url = Utils\HTTP::getBaseURL() . 'module.php/' . $resource; if (!empty($parameters)) { $url = Utils\HTTP::addURLParameters($url, $parameters); } return $url; } /** * Get the available hooks for a given module. * * @param string $module The module where we should look for hooks. * * @return array An array with the hooks available for this module. Each element is an array with two keys: 'file' * points to the file that contains the hook, and 'func' contains the name of the function implementing that hook. * When there are no hooks defined, an empty array is returned. */ public static function getModuleHooks($module) { if (isset(self::$modules[$module]['hooks'])) { return self::$modules[$module]['hooks']; } $hook_dir = self::getModuleDir($module) . '/hooks'; if (!is_dir($hook_dir)) { return []; } $hooks = []; $files = scandir($hook_dir); foreach ($files as $file) { if ($file[0] === '.') { continue; } if (!preg_match('/hook_(\w+)\.php/', $file, $matches)) { continue; } $hook_name = $matches[1]; $hook_func = $module . '_hook_' . $hook_name; $hooks[$hook_name] = ['file' => $hook_dir . '/' . $file, 'func' => $hook_func]; } return $hooks; } /** * Call a hook in all enabled modules. * * This function iterates over all enabled modules and calls a hook in each module. * * @param string $hook The name of the hook. * @param mixed &$data The data which should be passed to each hook. Will be passed as a reference. * @return void * * @throws \SimpleSAML\Error\Exception If an invalid hook is found in a module. */ public static function callHooks($hook, &$data = null) { assert(is_string($hook)); $modules = self::getModules(); $config = Configuration::getOptionalConfig()->getArray('module.enable', []); sort($modules); foreach ($modules as $module) { if (!self::isModuleEnabledWithConf($module, $config)) { continue; } if (!isset(self::$module_info[$module]['hooks'])) { self::$module_info[$module]['hooks'] = self::getModuleHooks($module); } if ( !isset(self::$module_info[$module]['hooks'][$hook]) || empty(self::$module_info[$module]['hooks'][$hook]) ) { continue; } require_once(self::$module_info[$module]['hooks'][$hook]['file']); if (!is_callable(self::$module_info[$module]['hooks'][$hook]['func'])) { throw new Error\Exception('Invalid hook \'' . $hook . '\' for module \'' . $module . '\'.'); } $fn = self::$module_info[$module]['hooks'][$hook]['func']; $fn($data); } } /** * Handle a valid request for a module that lacks a trailing slash. * * This method add the trailing slash and redirects to the resulting URL. * * @param Request $request The request to process by this controller method. * * @return RedirectResponse A redirection to the URI specified in the request, but with a trailing slash. */ public static function addTrailingSlash(Request $request) { // Must be of form /{module} - append a slash return new RedirectResponse($request->getRequestUri() . '/', 308); } /** * Handle a valid request that ends with a trailing slash. * * This method removes the trailing slash and redirects to the resulting URL. * * @param Request $request The request to process by this controller method. * * @return RedirectResponse A redirection to the URI specified in the request, but without the trailing slash. */ public static function removeTrailingSlash(Request $request) { $pathInfo = $request->server->get('PATH_INFO'); $url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $request->getRequestUri()); return new RedirectResponse($url, 308); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/Stats/����������������������������������������������������������0000755�0000000�0000000�00000000000�14042503475�016735� 5����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/Stats/Output.php������������������������������������������������0000644�0000000�0000000�00000001070�14042503475�020744� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML\Stats; use SimpleSAML\Configuration; /** * Interface for statistics outputs. * * @package SimpleSAMLphp */ abstract class Output { /** * Initialize the output. * * @param \SimpleSAML\Configuration $config The configuration for this output. */ public function __construct(Configuration $config) { // do nothing by default } /** * Write a stats event. * * @param array $data The event. */ abstract public function emit(array $data); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������simplesamlphp-1.19.1/lib/SimpleSAML/Utilities.php���������������������������������������������������0000644�0000000�0000000�00000061547�14042503475�020340� 0����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php declare(strict_types=1); namespace SimpleSAML; use SimpleSAML\Error\Error; /** * Misc static functions that is used several places.in example parsing and id generation. * * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @package SimpleSAMLphp * * @deprecated This entire class will be removed in SimpleSAMLphp 2.0. */ class Utilities { /** * @deprecated This property will be removed in SSP 2.0. Please use SimpleSAML\Logger::isErrorMasked() instead. * @var int */ public static $logMask = 0; /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getSelfHost() instead. * @return string */ public static function getSelfHost() { return \SimpleSAML\Utils\HTTP::getSelfHost(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getSelfURLHost() instead. * @return string */ public static function selfURLhost() { return \SimpleSAML\Utils\HTTP::getSelfURLHost(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::isHTTPS() instead. * @return bool */ public static function isHTTPS() { return \SimpleSAML\Utils\HTTP::isHTTPS(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getSelfURLNoQuery() * instead. * @return string */ public static function selfURLNoQuery() { return \SimpleSAML\Utils\HTTP::getSelfURLNoQuery(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getSelfHostWithPath() * instead. * @return string */ public static function getSelfHostWithPath() { return \SimpleSAML\Utils\HTTP::getSelfHostWithPath(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getFirstPathElement() * instead. * @param bool $trailingslash * @return string */ public static function getFirstPathElement($trailingslash = true) { return \SimpleSAML\Utils\HTTP::getFirstPathElement($trailingslash); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getSelfURL() instead. * @return string */ public static function selfURL() { return \SimpleSAML\Utils\HTTP::getSelfURL(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getBaseURL() instead. * @return string */ public static function getBaseURL() { return \SimpleSAML\Utils\HTTP::getBaseURL(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::addURLParameters() instead. * @param string $url * @param array $parameters * @return string */ public static function addURLparameter($url, $parameters) { return \SimpleSAML\Utils\HTTP::addURLParameters($url, $parameters); } /** * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Utils\HTTP::checkURLAllowed() instead. * @param string $url * @param array|null $trustedSites * @return string */ public static function checkURLAllowed($url, array $trustedSites = null) { return \SimpleSAML\Utils\HTTP::checkURLAllowed($url, $trustedSites); } /** * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Auth\State::parseStateID() instead. * @param string $stateId * @return array */ public static function parseStateID($stateId) { return \SimpleSAML\Auth\State::parseStateID($stateId); } /** * @deprecated This method will be removed in SSP 2.0. * @param string|null $start * @param string|null $end * @return bool */ public static function checkDateConditions($start = null, $end = null) { $currentTime = time(); if (!empty($start)) { $startTime = \SAML2\Utils::xsDateTimeToTimestamp($start); // Allow for a 10 minute difference in Time if (($startTime < 0) || (($startTime - 600) > $currentTime)) { return false; } } if (!empty($end)) { $endTime = \SAML2\Utils::xsDateTimeToTimestamp($end); if (($endTime < 0) || ($endTime <= $currentTime)) { return false; } } return true; } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Random::generateID() instead. * @return string */ public static function generateID() { return \SimpleSAML\Utils\Random::generateID(); } /** * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Utils\Time::generateTimestamp() * instead. * @param int|null $instant * @return string */ public static function generateTimestamp($instant = null) { return \SimpleSAML\Utils\Time::generateTimestamp($instant); } /** * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Utils\Time::parseDuration() instead. * @param string $duration * @param int|null $timestamp * @return int */ public static function parseDuration($duration, $timestamp = null) { return \SimpleSAML\Utils\Time::parseDuration($duration, $timestamp); } /** * @deprecated This method will be removed in SSP 2.0. Please raise a SimpleSAML\Error\Error exception instead. * @param string $trackId * @param int|null $errorCode * @param \Exception|null $e * @throws \SimpleSAML\Error\Error * @return void */ public static function fatalError($trackId = 'na', $errorCode = null, \Exception $e = null) { throw new \SimpleSAML\Error\Error($errorCode, $e); } /** * @deprecated This method will be removed in version 2.0. Use SimpleSAML\Utils\Net::ipCIDRcheck() instead. * @param string $cidr * @param string|null $ip * @return bool */ public static function ipCIDRcheck($cidr, $ip = null) { return \SimpleSAML\Utils\Net::ipCIDRcheck($cidr, $ip); } /** * @param string $url * @param array $parameters * @return void */ private static function doRedirect(string $url, array $parameters = []): void { if (!empty($parameters)) { $url = self::addURLparameter($url, $parameters); } /* Set the HTTP result code. This is either 303 See Other or * 302 Found. HTTP 303 See Other is sent if the HTTP version * is HTTP/1.1 and the request type was a POST request. */ if ($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' && $_SERVER['REQUEST_METHOD'] === 'POST' ) { $code = 303; } else { $code = 302; } if (strlen($url) > 2048) { \SimpleSAML\Logger::warning('Redirecting to a URL longer than 2048 bytes.'); } // Set the location header header('Location: '.$url, true, $code); // Disable caching of this response header('Pragma: no-cache'); header('Cache-Control: no-cache, must-revalidate'); // Show a minimal web page with a clickable link to the URL echo '<?xml version="1.0" encoding="UTF-8"?>'."\n"; echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"'. ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n"; echo '<html xmlns="http://www.w3.org/1999/xhtml">'; echo '<head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Redirect '; echo ''; echo '

Redirect

'; echo '

'; echo 'You were redirected to: '; echo ''.htmlspecialchars($url).''; echo ''; echo '

'; echo ''; echo ''; // End script execution exit; } /** * @deprecated 1.12.0 This method will be removed from the API. Instead, use the redirectTrustedURL() or * redirectUntrustedURL() functions accordingly. * @param string $url * @param array $parameters * @param array|null $allowed_redirect_hosts * @return void */ public static function redirect($url, $parameters = [], $allowed_redirect_hosts = null) { assert(is_string($url)); assert(strlen($url) > 0); assert(is_array($parameters)); if ($allowed_redirect_hosts !== null) { $url = self::checkURLAllowed($url, $allowed_redirect_hosts); } else { $url = self::normalizeURL($url); } self::doRedirect($url, $parameters); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::redirectTrustedURL() * instead. * @param string $url * @param array $parameters * @return void */ public static function redirectTrustedURL($url, $parameters = []) { \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, $parameters); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::redirectUntrustedURL() * instead. * @param string $url * @param array $parameters * @return void */ public static function redirectUntrustedURL($url, $parameters = []) { \SimpleSAML\Utils\HTTP::redirectUntrustedURL($url, $parameters); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Arrays::transpose() instead. * @param array $in * @return mixed */ public static function transposeArray($in) { return \SimpleSAML\Utils\Arrays::transpose($in); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::isDOMNodeOfType() * instead. * @param \DOMNode $element * @param string $name * @param string $nsURI * @return bool */ public static function isDOMElementOfType(\DOMNode $element, $name, $nsURI) { return \SimpleSAML\Utils\XML::isDOMNodeOfType($element, $name, $nsURI); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::getDOMChildren() instead. * @param \DOMElement $element * @param string $localName * @param string $namespaceURI * @return array */ public static function getDOMChildren(\DOMElement $element, $localName, $namespaceURI) { return \SimpleSAML\Utils\XML::getDOMChildren($element, $localName, $namespaceURI); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::getDOMText() instead. * @param \DOMNode $element * @return string */ public static function getDOMText($element) { return \SimpleSAML\Utils\XML::getDOMText($element); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getAcceptLanguage() * instead. * @return array */ public static function getAcceptLanguage() { return \SimpleSAML\Utils\HTTP::getAcceptLanguage(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::isValid() instead. * @param string $xml * @param string $schema * @return string|false */ public static function validateXML($xml, $schema) { $result = \SimpleSAML\Utils\XML::isValid($xml, $schema); return ($result === true) ? '' : $result; } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::checkSAMLMessage() instead. * @param string $message * @param string $type * @return void */ public static function validateXMLDocument($message, $type) { \SimpleSAML\Utils\XML::checkSAMLMessage($message, $type); } /** * @deprecated This method will be removed in SSP 2.0. Please use openssl_random_pseudo_bytes() instead. * @param int $length * @return string */ public static function generateRandomBytes($length) { assert(is_int($length)); return openssl_random_pseudo_bytes($length); } /** * @deprecated This method will be removed in SSP 2.0. Please use bin2hex() instead. * @param string $bytes * @return string */ public static function stringToHex($bytes) { $ret = ''; for ($i = 0; $i < strlen($bytes); $i++) { $ret .= sprintf('%02x', ord($bytes[$i])); } return $ret; } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\System::resolvePath() instead. * @param string $path * @param string|null $base * @return string */ public static function resolvePath($path, $base = null) { return \SimpleSAML\Utils\System::resolvePath($path, $base); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::resolveURL() instead. * @param string $url * @param string|null $base * @return string */ public static function resolveURL($url, $base = null) { return \SimpleSAML\Utils\HTTP::resolveURL($url, $base); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::normalizeURL() instead. * @param string $url * @return string */ public static function normalizeURL($url) { return \SimpleSAML\Utils\HTTP::normalizeURL($url); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::parseQueryString() instead. * @param string $query_string * @return array */ public static function parseQueryString($query_string) { return \SimpleSAML\Utils\HTTP::parseQueryString($query_string); } /** * @deprecated This method will be removed in SSP 2.0. Please use * SimpleSAML\Utils\Attributes::normalizeAttributesArray() instead. * @param array $attributes * @return array */ public static function parseAttributes($attributes) { return \SimpleSAML\Utils\Attributes::normalizeAttributesArray($attributes); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Config::getSecretSalt() instead. * @return string */ public static function getSecretSalt() { return \SimpleSAML\Utils\Config::getSecretSalt(); } /** * @deprecated This method will be removed in SSP 2.0. Please call error_get_last() directly. * @return string */ public static function getLastError() { if (!function_exists('error_get_last')) { return '[Cannot get error message]'; } $error = error_get_last(); if ($error === null) { return '[No error message found]'; } return $error['message']; } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Config::getCertPath() instead. * @param string $path * @return string */ public static function resolveCert($path) { return \SimpleSAML\Utils\Config::getCertPath($path); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::loadPublicKey() instead. * @param \SimpleSAML\Configuration $metadata * @param bool $required * @param string $prefix * @return array|null */ public static function loadPublicKey(\SimpleSAML\Configuration $metadata, $required = false, $prefix = '') { return \SimpleSAML\Utils\Crypto::loadPublicKey($metadata, $required, $prefix); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::loadPrivateKey() instead. * @param \SimpleSAML\Configuration $metadata * @param bool $required * @param string $prefix * @return array|null */ public static function loadPrivateKey(\SimpleSAML\Configuration $metadata, $required = false, $prefix = '') { return \SimpleSAML\Utils\Crypto::loadPrivateKey($metadata, $required, $prefix); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::formatDOMElement() instead. * @param \DOMElement $root * @param string $indentBase * @return void */ public static function formatDOMElement(\DOMElement $root, $indentBase = '') { \SimpleSAML\Utils\XML::formatDOMElement($root, $indentBase); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::formatXMLString() instead. * @param string $xml * @param string $indentBase * @return string */ public static function formatXMLString($xml, $indentBase = '') { return \SimpleSAML\Utils\XML::formatXMLString($xml, $indentBase); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Arrays::arrayize() instead. * @param mixed $data * @param int $index * @return array */ public static function arrayize($data, $index = 0) { return \SimpleSAML\Utils\Arrays::arrayize($data, $index); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Auth::isAdmin() instead. * @return bool */ public static function isAdmin() { return \SimpleSAML\Utils\Auth::isAdmin(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Auth::getAdminLoginURL instead(); * @param string|null $returnTo * @return string */ public static function getAdminLoginURL($returnTo = null) { return \SimpleSAML\Utils\Auth::getAdminLoginURL($returnTo); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Auth::requireAdmin() instead. * @return void */ public static function requireAdmin() { \SimpleSAML\Utils\Auth::requireAdmin(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::submitPOSTData() instead. * @param string $destination * @param array $post * @return void */ public static function postRedirect($destination, $post) { \SimpleSAML\Utils\HTTP::submitPOSTData($destination, $post); } /** * @deprecated This method will be removed in SSP 2.0. PLease use SimpleSAML\Utils\HTTP::getPOSTRedirectURL() * instead. * @param string $destination * @param array $post * @return string */ public static function createPostRedirectLink($destination, $post) { return \SimpleSAML\Utils\HTTP::getPOSTRedirectURL($destination, $post); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getPOSTRedirectURL() * instead. * @param string $destination * @param array $post * @return string * @throws Error If the current session is a transient session. */ public static function createHttpPostRedirectLink($destination, $post) { assert(is_string($destination)); assert(is_array($post)); $postId = \SimpleSAML\Utils\Random::generateID(); $postData = [ 'post' => $post, 'url' => $destination, ]; $session = \SimpleSAML\Session::getSessionFromRequest(); if ($session->isTransient()) { throw new Error('Cannot save data to a transient session'); } $session->setData('core_postdatalink', $postId, $postData); $redirInfo = base64_encode(\SimpleSAML\Utils\Crypto::aesEncrypt($session->getSessionId().':'.$postId)); $url = \SimpleSAML\Module::getModuleURL('core/postredirect.php', ['RedirInfo' => $redirInfo]); $url = preg_replace("#^https:#", "http:", $url); return $url; } /** * @deprecated This method will be removed in SSP 2.0. * @param string $certificate * @param string $caFile * @return void */ public static function validateCA($certificate, $caFile) { \SimpleSAML\XML\Validator::validateCertificate($certificate, $caFile); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Time::initTimezone() instead. * @return void */ public static function initTimezone() { \SimpleSAML\Utils\Time::initTimezone(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\System::writeFile() instead. * @param string $filename * @param string $data * @param int $mode * @return void */ public static function writeFile($filename, $data, $mode = 0600) { \SimpleSAML\Utils\System::writeFile($filename, $data, $mode); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\System::getTempDir instead. * @return string */ public static function getTempDir() { return \SimpleSAML\Utils\System::getTempDir(); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Logger::maskErrors() instead. * @param int $mask * @return void */ public static function maskErrors($mask) { \SimpleSAML\Logger::maskErrors($mask); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Logger::popErrorMask() instead. * @return void */ public static function popErrorMask() { \SimpleSAML\Logger::popErrorMask(); } /** * @deprecated This method will be removed in SSP 2.0. Please use * SimpleSAML\Utils\Config\Metadata::getDefaultEndpoint() instead. * @param array $endpoints * @param array|null $bindings * @return array|null */ public static function getDefaultEndpoint(array $endpoints, array $bindings = null) { return \SimpleSAML\Utils\Config\Metadata::getDefaultEndpoint($endpoints, $bindings); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::checkSessionCookie() * instead. * @param string|null $retryURL * @return void */ public static function checkCookie($retryURL = null) { \SimpleSAML\Utils\HTTP::checkSessionCookie($retryURL); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\XML::debugSAMLMessage() instead. * @param string|\DOMElement $message * @param string $type * @return void */ public static function debugMessage($message, $type) { \SimpleSAML\Utils\XML::debugSAMLMessage($message, $type); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::fetch() instead. * @param string $path * @param array $context * @param bool $getHeaders * @return string|array */ public static function fetch($path, $context = [], $getHeaders = false) { return \SimpleSAML\Utils\HTTP::fetch($path, $context, $getHeaders); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::aesEncrypt() instead. * @param string $clear * @return string */ public static function aesEncrypt($clear) { return \SimpleSAML\Utils\Crypto::aesEncrypt($clear); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\Crypto::aesDecrypt() instead. * @param string $encData * @return string */ public static function aesDecrypt($encData) { return \SimpleSAML\Utils\Crypto::aesDecrypt($encData); } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\System::getOS() instead. * @return bool */ public static function isWindowsOS() { return \SimpleSAML\Utils\System::getOS() === \SimpleSAML\Utils\System::WINDOWS; } /** * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::setCookie() instead. * @param string $name * @param string|null $value * @param array|null $params * @param bool $throw * @return void */ public static function setCookie($name, $value, array $params = null, $throw = true) { \SimpleSAML\Utils\HTTP::setCookie($name, $value, $params, $throw); } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/0000755000000000000000000000000014042503475016737 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Utils/Config.php0000644000000000000000000000610414042503475020656 0ustar rootroot */ public static function getCertPath($path) { if (!is_string($path)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $globalConfig = Configuration::getInstance(); $base = $globalConfig->getPathValue('certdir', 'cert/'); return System::resolvePath($path, $base); } /** * Retrieve the secret salt. * * This function retrieves the value which is configured as the secret salt. It will check that the value exists * and is set to a non-default value. If it isn't, an exception will be thrown. * * The secret salt can be used as a component in hash functions, to make it difficult to test all possible values * in order to retrieve the original value. It can also be used as a simple method for signing data, by hashing the * data together with the salt. * * @return string The secret salt. * @throws \InvalidArgumentException If the secret salt hasn't been configured. * * @author Olav Morken, UNINETT AS */ public static function getSecretSalt() { $secretSalt = Configuration::getInstance()->getString('secretsalt'); if ($secretSalt === 'defaultsecretsalt') { throw new \InvalidArgumentException('The "secretsalt" configuration option must be set to a secret value.'); } return $secretSalt; } /** * Returns the path to the config dir * * If the SIMPLESAMLPHP_CONFIG_DIR environment variable has been set, it takes precedence over the default * $simplesamldir/config directory. * * @return string The path to the configuration directory. */ public static function getConfigDir() { $configDir = dirname(dirname(dirname(__DIR__))) . '/config'; /** @var string|false $configDirEnv */ $configDirEnv = getenv('SIMPLESAMLPHP_CONFIG_DIR'); if ($configDirEnv === false) { $configDirEnv = getenv('REDIRECT_SIMPLESAMLPHP_CONFIG_DIR'); } if ($configDirEnv !== false) { if (!is_dir($configDirEnv)) { throw new \InvalidArgumentException( sprintf( 'Config directory specified by environment variable SIMPLESAMLPHP_CONFIG_DIR is not a ' . 'directory. Given: "%s"', $configDirEnv ) ); } $configDir = $configDirEnv; } return $configDir; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Time.php0000644000000000000000000001305514042503475020352 0ustar rootroot */ public static function generateTimestamp($instant = null) { if ($instant === null) { $instant = time(); } return gmdate('Y-m-d\TH:i:s\Z', $instant); } /** * Initialize the timezone. * * This function should be called before any calls to date(). * * @author Olav Morken, UNINETT AS * * @throws \SimpleSAML\Error\Exception If the timezone set in the configuration is invalid. * * @return void */ public static function initTimezone() { if (self::$tz_initialized) { return; } $globalConfig = Configuration::getInstance(); $timezone = $globalConfig->getString('timezone', null); if ($timezone !== null) { if (!date_default_timezone_set($timezone)) { throw new Error\Exception('Invalid timezone set in the "timezone" option in config.php.'); } self::$tz_initialized = true; return; } // we don't have a timezone configured Logger::maskErrors(E_ALL); $serverTimezone = date_default_timezone_get(); Logger::popErrorMask(); // set the timezone to the default date_default_timezone_set($serverTimezone); self::$tz_initialized = true; } /** * Interpret a ISO8601 duration value relative to a given timestamp. Please note no fractions are allowed, neither * durations specified in the formats PYYYYMMDDThhmmss nor P[YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]. * * @param string $duration The duration, as a string. * @param int $timestamp The unix timestamp we should apply the duration to. Optional, default to the current * time. * * @return int The new timestamp, after the duration is applied. * @throws \InvalidArgumentException If $duration is not a valid ISO 8601 duration or if the input parameters do * not have the right data types. */ public static function parseDuration($duration, $timestamp = null) { if (!(is_string($duration) && (is_int($timestamp) || is_null($timestamp)))) { throw new \InvalidArgumentException('Invalid input parameters'); } // parse the duration. We use a very strict pattern $durationRegEx = '#^(-?)P(?:(?:(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)' . '(?:[.,]\d+)?S)?)?)|(?:(\\d+)W))$#D'; if (!preg_match($durationRegEx, $duration, $matches)) { throw new \InvalidArgumentException('Invalid ISO 8601 duration: ' . $duration); } $durYears = (empty($matches[2]) ? 0 : (int) $matches[2]); $durMonths = (empty($matches[3]) ? 0 : (int) $matches[3]); $durDays = (empty($matches[4]) ? 0 : (int) $matches[4]); $durHours = (empty($matches[5]) ? 0 : (int) $matches[5]); $durMinutes = (empty($matches[6]) ? 0 : (int) $matches[6]); $durSeconds = (empty($matches[7]) ? 0 : (int) $matches[7]); $durWeeks = (empty($matches[8]) ? 0 : (int) $matches[8]); if (!empty($matches[1])) { // negative $durYears = -$durYears; $durMonths = -$durMonths; $durDays = -$durDays; $durHours = -$durHours; $durMinutes = -$durMinutes; $durSeconds = -$durSeconds; $durWeeks = -$durWeeks; } if ($timestamp === null) { $timestamp = time(); } if ($durYears !== 0 || $durMonths !== 0) { /* Special handling of months and years, since they aren't a specific interval, but * instead depend on the current time. */ /* We need the year and month from the timestamp. Unfortunately, PHP doesn't have the * gmtime function. Instead we use the gmdate function, and split the result. */ $yearmonth = explode(':', gmdate('Y:n', $timestamp)); $year = (int) ($yearmonth[0]); $month = (int) ($yearmonth[1]); // remove the year and month from the timestamp $timestamp -= gmmktime(0, 0, 0, $month, 1, $year); // add years and months, and normalize the numbers afterwards $year += $durYears; $month += $durMonths; while ($month > 12) { $year += 1; $month -= 12; } while ($month < 1) { $year -= 1; $month += 12; } // add year and month back into timestamp $timestamp += gmmktime(0, 0, 0, $month, 1, $year); } // add the other elements $timestamp += $durWeeks * 7 * 24 * 60 * 60; $timestamp += $durDays * 24 * 60 * 60; $timestamp += $durHours * 60 * 60; $timestamp += $durMinutes * 60; $timestamp += $durSeconds; return $timestamp; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Attributes.php0000644000000000000000000001207514042503475021603 0ustar rootroot * @package SimpleSAML */ class Attributes { /** * Look for an attribute in a normalized attributes array, failing if it's not there. * * @param array $attributes The normalized array containing attributes. * @param string $expected The name of the attribute we are looking for. * @param bool $allow_multiple Whether to allow multiple values in the attribute or not. * * @return mixed The value of the attribute we are expecting. If the attribute has multiple values and * $allow_multiple is set to true, the first value will be returned. * * @throws \InvalidArgumentException If $attributes is not an array or $expected is not a string. * @throws \SimpleSAML\Error\Exception If the expected attribute was not found in the attributes array. */ public static function getExpectedAttribute($attributes, $expected, $allow_multiple = false) { if (!is_array($attributes)) { throw new \InvalidArgumentException( 'The attributes array is not an array, it is: ' . print_r($attributes, true) . '.' ); } if (!is_string($expected)) { throw new \InvalidArgumentException( 'The expected attribute is not a string, it is: ' . print_r($expected, true) . '.' ); } if (!array_key_exists($expected, $attributes)) { throw new Error\Exception("No such attribute '" . $expected . "' found."); } $attribute = $attributes[$expected]; if (!is_array($attribute)) { throw new \InvalidArgumentException('The attributes array is not normalized, values should be arrays.'); } if (count($attribute) === 0) { throw new Error\Exception("Empty attribute '" . $expected . "'.'"); } elseif (count($attribute) > 1) { if ($allow_multiple === false) { throw new \SimpleSAML\Error\Exception( 'More than one value found for the attribute, multiple values not allowed.' ); } } return reset($attribute); } /** * Validate and normalize an array with attributes. * * This function takes in an associative array with attributes, and parses and validates * this array. On success, it will return a normalized array, where each attribute name * is an index to an array of one or more strings. On failure an exception will be thrown. * This exception will contain an message describing what is wrong. * * @param array $attributes The array containing attributes that we should validate and normalize. * * @return array The normalized attributes array. * @throws \InvalidArgumentException If input is not an array, array keys are not strings or attribute values are * not strings. * * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function normalizeAttributesArray($attributes) { if (!is_array($attributes)) { throw new \InvalidArgumentException( 'The attributes array is not an array, it is: ' . print_r($attributes, true) . '".' ); } $newAttrs = []; foreach ($attributes as $name => $values) { if (!is_string($name)) { throw new \InvalidArgumentException('Invalid attribute name: "' . print_r($name, true) . '".'); } $values = Arrays::arrayize($values); foreach ($values as $value) { if (!is_string($value)) { throw new \InvalidArgumentException( 'Invalid attribute value for attribute ' . $name . ': "' . print_r($value, true) . '".' ); } } $newAttrs[$name] = $values; } return $newAttrs; } /** * Extract an attribute's namespace, or revert to default. * * This function takes in a namespaced attribute name and splits it in a namespace/attribute name tuple. * When no namespace is found in the attribute name, it will be namespaced with the default namespace. * This default namespace can be overriden by supplying a second parameter to this function. * * @param string $name The namespaced attribute name. * @param string $defaultns The default namespace that should be used when no namespace is found. * * @return array The attribute name, split to the namespace and the actual attribute name. */ public static function getAttributeNamespace($name, $defaultns) { $slash = strrpos($name, '/'); if ($slash !== false) { $defaultns = substr($name, 0, $slash); $name = substr($name, $slash + 1); } return [htmlspecialchars($defaultns), htmlspecialchars($name)]; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/HttpAdapter.php0000644000000000000000000001270114042503475021671 0ustar rootroot= 12.13.2) even though its chrome version is old $matches = []; if (preg_match('|UCBrowser/(\d+\.\d+\.\d+)[\.\d]*|', $useragent, $matches)) { return version_compare($matches[1], '12.13.2', '>='); } // Chrome 50-69 may have broken SameSite=None and don't require it to be set if (strpos($useragent, "Chrome/5") !== false || strpos($useragent, "Chrome/6") !== false) { return false; } return true; } /** * Obtain a URL where we can redirect to securely post a form with the given data to a specific destination. * * @param string $destination The destination URL. * @param array $data An associative array containing the data to be posted to $destination. * * @throws Error\Exception If the current session is transient. * @return string A URL which allows to securely post a form to $destination. * * @author Jaime Perez, UNINETT AS */ private static function getSecurePOSTRedirectURL(string $destination, array $data): string { $session = Session::getSessionFromRequest(); $id = self::savePOSTData($session, $destination, $data); if ($session->isTransient()) { // this is a transient session, it is pointless to continue throw new Error\Exception('Cannot save POST data to a transient session.'); } /** @var string $session_id */ $session_id = $session->getSessionId(); // encrypt the session ID and the random ID $info = base64_encode(Crypto::aesEncrypt($session_id . ':' . $id)); $url = Module::getModuleURL('core/postredirect.php', ['RedirInfo' => $info]); return preg_replace('#^https:#', 'http:', $url); } /** * Retrieve Host value from $_SERVER environment variables. * * @return string The current host name, including the port if needed. It will use localhost when unable to * determine the current host. * * @author Olav Morken, UNINETT AS */ private static function getServerHost(): string { if (array_key_exists('HTTP_HOST', $_SERVER)) { $current = $_SERVER['HTTP_HOST']; } elseif (array_key_exists('SERVER_NAME', $_SERVER)) { $current = $_SERVER['SERVER_NAME']; } else { // almost certainly not what you want, but... $current = 'localhost'; } if (strstr($current, ":")) { $decomposed = explode(":", $current); $port = array_pop($decomposed); if (!is_numeric($port)) { array_push($decomposed, $port); } $current = implode(":", $decomposed); } return $current; } /** * Retrieve HTTPS status from $_SERVER environment variables. * * @return boolean True if the request was performed through HTTPS, false otherwise. * * @author Olav Morken, UNINETT AS */ public static function getServerHTTPS() { if (!array_key_exists('HTTPS', $_SERVER)) { // not an https-request return false; } if ($_SERVER['HTTPS'] === 'off') { // IIS with HTTPS off return false; } // otherwise, HTTPS will be non-empty return !empty($_SERVER['HTTPS']); } /** * Retrieve the port number from $_SERVER environment variables. * * @return string The port number prepended by a colon, if it is different than the default port for the protocol * (80 for HTTP, 443 for HTTPS), or an empty string otherwise. * * @author Olav Morken, UNINETT AS */ public static function getServerPort() { $default_port = self::getServerHTTPS() ? '443' : '80'; $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $default_port; // Take care of edge-case where SERVER_PORT is an integer $port = strval($port); if ($port !== $default_port) { return ':' . $port; } return ''; } /** * Verify that a given URL is valid. * * @param string $url The URL we want to verify. * * @return boolean True if the given URL is valid, false otherwise. */ public static function isValidURL($url) { $url = filter_var($url, FILTER_VALIDATE_URL); if ($url === false) { return false; } $scheme = parse_url($url, PHP_URL_SCHEME); if (is_string($scheme) && in_array(strtolower($scheme), ['http', 'https'], true)) { return true; } return false; } /** * This function redirects the user to the specified address. * * This function will use the "HTTP 303 See Other" redirection if the current request used the POST method and the * HTTP version is 1.1. Otherwise, a "HTTP 302 Found" redirection will be used. * * The function will also generate a simple web page with a clickable link to the target page. * * @param string $url The URL we should redirect to. This URL may include query parameters. If this URL is a * relative URL (starting with '/'), then it will be turned into an absolute URL by prefixing it with the * absolute URL to the root of the website. * @param string[] $parameters An array with extra query string parameters which should be appended to the URL. The * name of the parameter is the array index. The value of the parameter is the value stored in the index. Both * the name and the value will be urlencoded. If the value is NULL, then the parameter will be encoded as just * the name, without a value. * * @return void This function never returns. * @throws \InvalidArgumentException If $url is not a string or is empty, or $parameters is not an array. * @throws \SimpleSAML\Error\Exception If $url is not a valid HTTP URL. * * @author Olav Morken, UNINETT AS * @author Mads Freek Petersen * @author Jaime Perez, UNINETT AS */ private static function redirect(string $url, array $parameters = []): void { if (empty($url)) { throw new \InvalidArgumentException('Invalid input parameters.'); } if (!self::isValidURL($url)) { throw new Error\Exception('Invalid destination URL.'); } if (!empty($parameters)) { $url = self::addURLParameters($url, $parameters); } /* Set the HTTP result code. This is either 303 See Other or * 302 Found. HTTP 303 See Other is sent if the HTTP version * is HTTP/1.1 and the request type was a POST request. */ if ( $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' && $_SERVER['REQUEST_METHOD'] === 'POST' ) { $code = 303; } else { $code = 302; } if (strlen($url) > 2048) { Logger::warning('Redirecting to a URL longer than 2048 bytes.'); } if (!headers_sent()) { // set the location header header('Location: ' . $url, true, $code); // disable caching of this response header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); } // show a minimal web page with a clickable link to the URL echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; echo " \n"; echo ' ' . "\n"; echo ' ' . "\n"; echo " Redirect\n"; echo " \n"; echo " \n"; echo "

Redirect

\n"; echo '

You were redirected to: '; echo htmlspecialchars($url) . "\n"; echo ' ' . "\n"; echo "

\n"; echo " \n"; echo ''; // end script execution exit; } /** * Save the given HTTP POST data and the destination where it should be posted to a given session. * * @param \SimpleSAML\Session $session The session where to temporarily store the data. * @param string $destination The destination URL where the form should be posted. * @param array $data An associative array with the data to be posted to $destination. * * @return string A random identifier that can be used to retrieve the data from the current session. * * @author Andjelko Horvat * @author Jaime Perez, UNINETT AS */ private static function savePOSTData(Session $session, string $destination, array $data): string { // generate a random ID to avoid replay attacks $id = Random::generateID(); $postData = [ 'post' => $data, 'url' => $destination, ]; // save the post data to the session, tied to the random ID $session->setData('core_postdatalink', $id, $postData); return $id; } /** * Add one or more query parameters to the given URL. * * @param string $url The URL the query parameters should be added to. * @param array $parameters The query parameters which should be added to the url. This should be an associative * array. * * @return string The URL with the new query parameters. * @throws \InvalidArgumentException If $url is not a string or $parameters is not an array. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ public static function addURLParameters($url, $parameters) { if (!is_string($url) || !is_array($parameters)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $queryStart = strpos($url, '?'); if ($queryStart === false) { $oldQuery = []; $url .= '?'; } else { /** @var string|false $oldQuery */ $oldQuery = substr($url, $queryStart + 1); if ($oldQuery === false) { $oldQuery = []; } else { $oldQuery = self::parseQueryString($oldQuery); } $url = substr($url, 0, $queryStart + 1); } /** @var array $oldQuery */ $query = array_merge($oldQuery, $parameters); $url .= http_build_query($query, '', '&'); return $url; } /** * Check for session cookie, and show missing-cookie page if it is missing. * * @param string|null $retryURL The URL the user should access to retry the operation. Defaults to null. * * @return void If there is a session cookie, nothing will be returned. Otherwise, the user will be redirected to a * page telling about the missing cookie. * @throws \InvalidArgumentException If $retryURL is neither a string nor null. * * @author Olav Morken, UNINETT AS */ public static function checkSessionCookie($retryURL = null) { if (!is_null($retryURL) && !is_string($retryURL)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $session = Session::getSessionFromRequest(); if ($session->hasSessionCookie()) { return; } // we didn't have a session cookie. Redirect to the no-cookie page $url = Module::getModuleURL('core/no_cookie.php'); if ($retryURL !== null) { $url = self::addURLParameters($url, ['retryURL' => $retryURL]); } self::redirectTrustedURL($url); } /** * Check if a URL is valid and is in our list of allowed URLs. * * @param string $url The URL to check. * @param array $trustedSites An optional white list of domains. If none specified, the 'trusted.url.domains' * configuration directive will be used. * * @return string The normalized URL itself if it is allowed. An empty string if the $url parameter is empty as * defined by the empty() function. * @throws \InvalidArgumentException If the URL is malformed. * @throws Error\Exception If the URL is not allowed by configuration. * * @author Jaime Perez, UNINETT AS */ public static function checkURLAllowed($url, array $trustedSites = null) { if (empty($url)) { return ''; } $url = self::normalizeURL($url); if (!self::isValidURL($url)) { throw new Error\Exception('Invalid URL: ' . $url); } // get the white list of domains if ($trustedSites === null) { $trustedSites = Configuration::getInstance()->getValue('trusted.url.domains', []); } // validates the URL's host is among those allowed if (is_array($trustedSites)) { $components = parse_url($url); $hostname = $components['host']; // check for userinfo if ( (isset($components['user']) && strpos($components['user'], '\\') !== false) || (isset($components['pass']) && strpos($components['pass'], '\\') !== false) ) { throw new Error\Exception('Invalid URL: ' . $url); } // allow URLs with standard ports specified (non-standard ports must then be allowed explicitly) if ( isset($components['port']) && (($components['scheme'] === 'http' && $components['port'] !== 80) || ($components['scheme'] === 'https' && $components['port'] !== 443)) ) { $hostname = $hostname . ':' . $components['port']; } $self_host = self::getSelfHostWithNonStandardPort(); $trustedRegex = Configuration::getInstance()->getValue('trusted.url.regex', false); $trusted = false; if ($trustedRegex) { // add self host to the white list $trustedSites[] = preg_quote($self_host); foreach ($trustedSites as $regex) { // Add start and end delimiters. $regex = "@^{$regex}$@"; if (preg_match($regex, $hostname)) { $trusted = true; break; } } } else { // add self host to the white list $trustedSites[] = $self_host; $trusted = in_array($hostname, $trustedSites, true); } // throw exception due to redirection to untrusted site if (!$trusted) { throw new Error\Exception('URL not allowed: ' . $url); } } return $url; } /** * Helper function to retrieve a file or URL with proxy support, also * supporting proxy basic authorization.. * * An exception will be thrown if we are unable to retrieve the data. * * @param string $url The path or URL we should fetch. * @param array $context Extra context options. This parameter is optional. * @param boolean $getHeaders Whether to also return response headers. Optional. * * @return string|array An array if $getHeaders is set, containing the data and the headers respectively; string * otherwise. * @throws \InvalidArgumentException If the input parameters are invalid. * @throws Error\Exception If the file or URL cannot be retrieved. * * @author Andjelko Horvat * @author Olav Morken, UNINETT AS * @author Marco Ferrante, University of Genova */ public static function fetch($url, $context = [], $getHeaders = false) { if (!is_string($url)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $config = Configuration::getInstance(); $proxy = $config->getString('proxy', null); if ($proxy !== null) { if (!isset($context['http']['proxy'])) { $context['http']['proxy'] = $proxy; } $proxy_auth = $config->getString('proxy.auth', false); if ($proxy_auth !== false) { $context['http']['header'] = "Proxy-Authorization: Basic " . base64_encode($proxy_auth); } if (!isset($context['http']['request_fulluri'])) { $context['http']['request_fulluri'] = true; } /* * If the remote endpoint over HTTPS uses the SNI extension (Server Name Indication RFC 4366), the proxy * could introduce a mismatch between the names in the Host: HTTP header and the SNI_server_name in TLS * negotiation (thanks to Cristiano Valli @ GARR-IDEM to have pointed this problem). * See: https://bugs.php.net/bug.php?id=63519 * These controls will force the same value for both fields. * Marco Ferrante (marco@csita.unige.it), Nov 2012 */ if ( preg_match('#^https#i', $url) && defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME ) { // extract the hostname $hostname = parse_url($url, PHP_URL_HOST); if (!empty($hostname)) { $context['ssl'] = [ 'SNI_server_name' => $hostname, 'SNI_enabled' => true, ]; } else { Logger::warning('Invalid URL format or local URL used through a proxy'); } } } $context = stream_context_create($context); $data = @file_get_contents($url, false, $context); if ($data === false) { $error = error_get_last(); throw new Error\Exception('Error fetching ' . var_export($url, true) . ':' . (is_array($error) ? $error['message'] : 'no error available')); } // data and headers if ($getHeaders) { /** * @psalm-suppress UndefinedVariable Remove when Psalm >= 3.0.17 */ if (!empty($http_response_header)) { $headers = []; /** * @psalm-suppress UndefinedVariable Remove when Psalm >= 3.0.17 */ foreach ($http_response_header as $h) { if (preg_match('@^HTTP/1\.[01]\s+\d{3}\s+@', $h)) { $headers = []; // reset $headers[0] = $h; continue; } $bits = explode(':', $h, 2); if (count($bits) === 2) { $headers[strtolower($bits[0])] = trim($bits[1]); } } } else { // no HTTP headers, probably a different protocol, e.g. file $headers = null; } return [$data, $headers]; } return $data; } /** * This function parses the Accept-Language HTTP header and returns an associative array with each language and the * score for that language. If a language includes a region, then the result will include both the language with * the region and the language without the region. * * The returned array will be in the same order as the input. * * @return array An associative array with each language and the score for that language. * * @author Olav Morken, UNINETT AS */ public static function getAcceptLanguage() { if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) { // no Accept-Language header, return an empty set return []; } $languages = explode(',', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])); $ret = []; foreach ($languages as $l) { $opts = explode(';', $l); $l = trim(array_shift($opts)); // the language is the first element $q = 1.0; // iterate over all options, and check for the quality option foreach ($opts as $o) { $o = explode('=', $o); if (count($o) < 2) { // skip option with no value continue; } $name = trim($o[0]); $value = trim($o[1]); if ($name === 'q') { $q = (float) $value; } } // remove the old key to ensure that the element is added to the end unset($ret[$l]); // set the quality in the result $ret[$l] = $q; if (strpos($l, '-')) { // the language includes a region part // extract the language without the region $l = explode('-', $l); $l = $l[0]; // add this language to the result (unless it is defined already) if (!array_key_exists($l, $ret)) { $ret[$l] = $q; } } } return $ret; } /** * Try to guess the base SimpleSAMLphp path from the current request. * * This method offers just a guess, so don't rely on it. * * @return string The guessed base path that should correspond to the root installation of SimpleSAMLphp. */ public static function guessBasePath() { if (!array_key_exists('REQUEST_URI', $_SERVER) || !array_key_exists('SCRIPT_FILENAME', $_SERVER)) { return '/'; } // get the name of the current script $path = explode('/', $_SERVER['SCRIPT_FILENAME']); $script = array_pop($path); // get the portion of the URI up to the script, i.e.: /simplesaml/some/directory/script.php if (!preg_match('#^/(?:[^/]+/)*' . $script . '#', $_SERVER['REQUEST_URI'], $matches)) { return '/'; } $uri_s = explode('/', $matches[0]); $file_s = explode('/', $_SERVER['SCRIPT_FILENAME']); // compare both arrays from the end, popping elements matching out of them while ($uri_s[count($uri_s) - 1] === $file_s[count($file_s) - 1]) { array_pop($uri_s); array_pop($file_s); } // we are now left with the minimum part of the URI that does not match anything in the file system, use it return join('/', $uri_s) . '/'; } /** * Retrieve the base URL of the SimpleSAMLphp installation. The URL will always end with a '/'. For example: * https://idp.example.org/simplesaml/ * * @return string The absolute base URL for the SimpleSAMLphp installation. * @throws \SimpleSAML\Error\CriticalConfigurationError If 'baseurlpath' has an invalid format. * * @author Olav Morken, UNINETT AS */ public static function getBaseURL() { $globalConfig = Configuration::getInstance(); $baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/'); if (preg_match('#^https?://.*/?$#D', $baseURL, $matches)) { // full URL in baseurlpath, override local server values return rtrim($baseURL, '/') . '/'; } elseif ( (preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) || (preg_match('#^\*(.*)/$#D', $baseURL, $matches)) || ($baseURL === '') ) { // get server values $protocol = 'http'; $protocol .= (self::getServerHTTPS()) ? 's' : ''; $protocol .= '://'; $hostname = self::getServerHost(); $port = self::getServerPort(); $path = $globalConfig->getBasePath(); return $protocol . $hostname . $port . $path; } else { /* * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful * with the configuration. Use a guessed base path instead of the one provided. */ $c = $globalConfig->toArray(); $c['baseurlpath'] = self::guessBasePath(); throw new Error\CriticalConfigurationError( 'Invalid value for \'baseurlpath\' in config.php. Valid format is in the form: ' . '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.', null, $c ); } } /** * Retrieve the first element of the URL path. * * @param boolean $leadingSlash Whether to add a leading slash to the element or not. Defaults to true. * * @return string The first element of the URL path, with an optional, leading slash. * * @author Andreas Solberg, UNINETT AS */ public static function getFirstPathElement($leadingSlash = true) { if (preg_match('|^/(.*?)/|', $_SERVER['SCRIPT_NAME'], $matches)) { return ($leadingSlash ? '/' : '') . $matches[1]; } return ''; } /** * Create a link which will POST data. * * @param string $destination The destination URL. * @param array $data The name-value pairs which will be posted to the destination. * * @return string A URL which can be accessed to post the data. * @throws \InvalidArgumentException If $destination is not a string or $data is not an array. * * @author Andjelko Horvat * @author Jaime Perez, UNINETT AS */ public static function getPOSTRedirectURL($destination, $data) { if (!is_string($destination) || !is_array($data)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $config = Configuration::getInstance(); $allowed = $config->getBoolean('enable.http_post', false); if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) { // we need to post the data to HTTP $url = self::getSecurePOSTRedirectURL($destination, $data); } else { // post the data directly $session = Session::getSessionFromRequest(); $id = self::savePOSTData($session, $destination, $data); $url = Module::getModuleURL('core/postredirect.php', ['RedirId' => $id]); } return $url; } /** * Retrieve our own host. * * E.g. www.example.com * * @return string The current host. * * @author Jaime Perez, UNINETT AS */ public static function getSelfHost() { $decomposed = explode(':', self::getSelfHostWithNonStandardPort()); return array_shift($decomposed); } /** * Retrieve our own host, including the port in case the it is not standard for the protocol in use. That is port * 80 for HTTP and port 443 for HTTPS. * * E.g. www.example.com:8080 * * @return string The current host, followed by a colon and the port number, in case the port is not standard for * the protocol. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ public static function getSelfHostWithNonStandardPort() { $url = self::getBaseURL(); /** @var int $colon getBaseURL() will allways return a valid URL */ $colon = strpos($url, '://'); $start = $colon + 3; $length = strcspn($url, '/', $start); return substr($url, $start, $length); } /** * Retrieve our own host together with the URL path. Please note this function will return the base URL for the * current SP, as defined in the global configuration. * * @return string The current host (with non-default ports included) plus the URL path. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ public static function getSelfHostWithPath() { $baseurl = explode("/", self::getBaseURL()); $elements = array_slice($baseurl, 3 - count($baseurl), count($baseurl) - 4); $path = implode("/", $elements); return self::getSelfHostWithNonStandardPort() . "/" . $path; } /** * Retrieve the current URL using the base URL in the configuration, if possible. * * This method will try to see if the current script is part of SimpleSAMLphp. In that case, it will use the * 'baseurlpath' configuration option to rebuild the current URL based on that. If the current script is NOT * part of SimpleSAMLphp, it will just return the current URL. * * Note that this method does NOT make use of the HTTP X-Forwarded-* set of headers. * * @return string The current URL, including query parameters. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function getSelfURL() { $cfg = Configuration::getInstance(); $baseDir = $cfg->getBaseDir(); $cur_path = realpath($_SERVER['SCRIPT_FILENAME']); // make sure we got a string from realpath() $cur_path = is_string($cur_path) ? $cur_path : ''; // find the path to the current script relative to the www/ directory of SimpleSAMLphp $rel_path = str_replace($baseDir . 'www' . DIRECTORY_SEPARATOR, '', $cur_path); // convert that relative path to an HTTP query $url_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path); // find where the relative path starts in the current request URI $uri_pos = (!empty($url_path)) ? strpos($_SERVER['REQUEST_URI'] ?? '', $url_path) : false; if ($cur_path == $rel_path || $uri_pos === false) { /* * We were accessed from an external script. This can happen in the following cases: * * - $_SERVER['SCRIPT_FILENAME'] points to a script that doesn't exist. E.g. functional testing. In this * case, realpath() returns false and str_replace an empty string, so we compare them loosely. * * - The URI requested does not belong to a script in the www/ directory of SimpleSAMLphp. In that case, * removing SimpleSAMLphp's base dir from the current path yields the same path, so $cur_path and * $rel_path are equal. * * - The request URI does not match the current script. Even if the current script is located in the www/ * directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false. * * It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the * current URI, so we need to build it back from the PHP environment, unless we have a base URL specified * for this case in the configuration. First, check if that's the case. */ /** @var \SimpleSAML\Configuration $appcfg */ $appcfg = $cfg->getConfigItem('application'); $appurl = $appcfg->getString('baseURL', ''); if (!empty($appurl)) { $protocol = parse_url($appurl, PHP_URL_SCHEME); $hostname = parse_url($appurl, PHP_URL_HOST); $port = parse_url($appurl, PHP_URL_PORT); $port = !empty($port) ? ':' . $port : ''; } else { // no base URL specified for app, just use the current URL $protocol = self::getServerHTTPS() ? 'https' : 'http'; $hostname = self::getServerHost(); $port = self::getServerPort(); } return $protocol . '://' . $hostname . $port . $_SERVER['REQUEST_URI']; } return self::getBaseURL() . $url_path . substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path)); } /** * Retrieve the current URL using the base URL in the configuration, containing the protocol, the host and * optionally, the port number. * * @return string The current URL without path or query parameters. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ public static function getSelfURLHost() { $url = self::getSelfURL(); /** @var int $colon getBaseURL() will allways return a valid URL */ $colon = strpos($url, '://'); $start = $colon + 3; $length = strcspn($url, '/', $start) + $start; return substr($url, 0, $length); } /** * Retrieve the current URL using the base URL in the configuration, without the query parameters. * * @return string The current URL, not including query parameters. * * @author Andreas Solberg, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function getSelfURLNoQuery() { $url = self::getSelfURL(); $pos = strpos($url, '?'); if (!$pos) { return $url; } return substr($url, 0, $pos); } /** * This function checks if we are using HTTPS as protocol. * * @return boolean True if the HTTPS is used, false otherwise. * * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function isHTTPS() { return strpos(self::getSelfURL(), 'https://') === 0; } /** * Normalizes a URL to an absolute URL and validate it. In addition to resolving the URL, this function makes sure * that it is a link to an http or https site. * * @param string $url The relative URL. * * @return string An absolute URL for the given relative URL. * @throws \InvalidArgumentException If $url is not a string or a valid URL. * * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function normalizeURL($url) { if (!is_string($url)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $url = self::resolveURL($url, self::getSelfURL()); // verify that the URL is to a http or https site if (!preg_match('@^https?://@i', $url)) { throw new \InvalidArgumentException('Invalid URL: ' . $url); } return $url; } /** * Parse a query string into an array. * * This function parses a query string into an array, similar to the way the builtin 'parse_str' works, except it * doesn't handle arrays, and it doesn't do "magic quotes". * * Query parameters without values will be set to an empty string. * * @param string $query_string The query string which should be parsed. * * @return array The query string as an associative array. * @throws \InvalidArgumentException If $query_string is not a string. * * @author Olav Morken, UNINETT AS */ public static function parseQueryString($query_string) { if (!is_string($query_string)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $res = []; if (empty($query_string)) { return $res; } foreach (explode('&', $query_string) as $param) { $param = explode('=', $param); $name = urldecode($param[0]); if (count($param) === 1) { $value = ''; } else { $value = urldecode($param[1]); } $res[$name] = $value; } return $res; } /** * This function redirects to the specified URL without performing any security checks. Please, do NOT use this * function with user supplied URLs. * * This function will use the "HTTP 303 See Other" redirection if the current request used the POST method and the * HTTP version is 1.1. Otherwise, a "HTTP 302 Found" redirection will be used. * * The function will also generate a simple web page with a clickable link to the target URL. * * @param string $url The URL we should redirect to. This URL may include query parameters. If this URL is a * relative URL (starting with '/'), then it will be turned into an absolute URL by prefixing it with the absolute * URL to the root of the website. * @param string[] $parameters An array with extra query string parameters which should be appended to the URL. The * name of the parameter is the array index. The value of the parameter is the value stored in the index. Both the * name and the value will be urlencoded. If the value is NULL, then the parameter will be encoded as just the * name, without a value. * * @return void This function never returns. * @throws \InvalidArgumentException If $url is not a string or $parameters is not an array. * * @author Jaime Perez, UNINETT AS */ public static function redirectTrustedURL($url, $parameters = []) { if (!is_string($url) || !is_array($parameters)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $url = self::normalizeURL($url); self::redirect($url, $parameters); } /** * This function redirects to the specified URL after performing the appropriate security checks on it. * Particularly, it will make sure that the provided URL is allowed by the 'trusted.url.domains' directive in the * configuration. * * If the aforementioned option is not set or the URL does correspond to a trusted site, it performs a redirection * to it. If the site is not trusted, an exception will be thrown. * * @param string $url The URL we should redirect to. This URL may include query parameters. If this URL is a * relative URL (starting with '/'), then it will be turned into an absolute URL by prefixing it with the absolute * URL to the root of the website. * @param string[] $parameters An array with extra query string parameters which should be appended to the URL. The * name of the parameter is the array index. The value of the parameter is the value stored in the index. Both the * name and the value will be urlencoded. If the value is NULL, then the parameter will be encoded as just the * name, without a value. * * @return void This function never returns. * @throws \InvalidArgumentException If $url is not a string or $parameters is not an array. * * @author Jaime Perez, UNINETT AS */ public static function redirectUntrustedURL($url, $parameters = []) { if (!is_string($url) || !is_array($parameters)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $url = self::checkURLAllowed($url); self::redirect($url, $parameters); } /** * Resolve a (possibly relative) URL relative to a given base URL. * * This function supports these forms of relative URLs: * - ^\w+: Absolute URL. E.g. "http://www.example.com:port/path?query#fragment". * - ^// Same protocol. E.g. "//www.example.com:port/path?query#fragment" * - ^/ Same protocol and host. E.g. "/path?query#fragment". * - ^? Same protocol, host and path, replace query string & fragment. E.g. "?query#fragment". * - ^# Same protocol, host, path and query, replace fragment. E.g. "#fragment". * - The rest: Relative to the base path. * * @param string $url The relative URL. * @param string $base The base URL. Defaults to the base URL of this installation of SimpleSAMLphp. * * @return string An absolute URL for the given relative URL. * @throws \InvalidArgumentException If the base URL cannot be parsed into a valid URL, or the given parameters * are not strings. * * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function resolveURL($url, $base = null) { if ($base === null) { $base = self::getBaseURL(); } if (!is_string($url) || !is_string($base)) { throw new \InvalidArgumentException('Invalid input parameters.'); } if (!preg_match('/^((((\w+:)\/\/[^\/]+)(\/[^?#]*))(?:\?[^#]*)?)(?:#.*)?/', $base, $baseParsed)) { throw new \InvalidArgumentException('Unable to parse base url: ' . $base); } $baseDir = dirname($baseParsed[5] . 'filename'); $baseScheme = $baseParsed[4]; $baseHost = $baseParsed[3]; $basePath = $baseParsed[2]; $baseQuery = $baseParsed[1]; if (preg_match('$^\w+:$', $url)) { return $url; } if (substr($url, 0, 2) === '//') { return $baseScheme . $url; } if ($url[0] === '/') { return $baseHost . $url; } if ($url[0] === '?') { return $basePath . $url; } if ($url[0] === '#') { return $baseQuery . $url; } // we have a relative path. Remove query string/fragment and save it as $tail $queryPos = strpos($url, '?'); $fragmentPos = strpos($url, '#'); if ($queryPos !== false || $fragmentPos !== false) { if ($queryPos === false) { $tailPos = $fragmentPos; } elseif ($fragmentPos === false) { $tailPos = $queryPos; } elseif ($queryPos < $fragmentPos) { $tailPos = $queryPos; } else { $tailPos = $fragmentPos; } $tail = substr($url, $tailPos); $dir = substr($url, 0, $tailPos); } else { $dir = $url; $tail = ''; } $dir = System::resolvePath($dir, $baseDir); return $baseHost . $dir . $tail; } /** * Set a cookie. * * @param string $name The name of the cookie. * @param string|NULL $value The value of the cookie. Set to NULL to delete the cookie. * @param array|NULL $params Cookie parameters. * @param bool $throw Whether to throw exception if setcookie() fails. * * @throws \InvalidArgumentException If any parameter has an incorrect type. * @throws \SimpleSAML\Error\CannotSetCookie If the headers were already sent and the cookie cannot be set. * * @return void * * @author Andjelko Horvat * @author Jaime Perez, UNINETT AS */ public static function setCookie($name, $value, $params = null, $throw = true) { if ( !(is_string($name) // $name must be a string && (is_string($value) || is_null($value)) // $value can be a string or null && (is_array($params) || is_null($params)) // $params can be an array or null && is_bool($throw)) // $throw must be boolean ) { throw new \InvalidArgumentException('Invalid input parameters.'); } $default_params = [ 'lifetime' => 0, 'expire' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httponly' => true, 'raw' => false, 'samesite' => null, ]; if ($params !== null) { $params = array_merge($default_params, $params); } else { $params = $default_params; } // Do not set secure cookie if not on HTTPS if ($params['secure'] && !self::isHTTPS()) { if ($throw) { throw new Error\CannotSetCookie( 'Setting secure cookie on plain HTTP is not allowed.', Error\CannotSetCookie::SECURE_COOKIE ); } Logger::warning('Error setting cookie: setting secure cookie on plain HTTP is not allowed.'); return; } if ($value === null) { $expire = time() - 365 * 24 * 60 * 60; $value = strval($value); } elseif (isset($params['expire'])) { $expire = intval($params['expire']); } elseif ($params['lifetime'] === 0) { $expire = 0; } else { $expire = time() + intval($params['lifetime']); } if (version_compare(PHP_VERSION, '7.3.0', '>=')) { /* use the new options array for PHP >= 7.3 */ if ($params['raw']) { /** @psalm-suppress InvalidArgument */ $success = @setrawcookie( $name, $value, [ 'expires' => $expire, 'path' => $params['path'], 'domain' => $params['domain'], 'secure' => $params['secure'], 'httponly' => $params['httponly'], 'samesite' => $params['samesite'], ] ); } else { /** @psalm-suppress InvalidArgument */ $success = @setcookie( $name, $value, [ 'expires' => $expire, 'path' => $params['path'], 'domain' => $params['domain'], 'secure' => $params['secure'], 'httponly' => $params['httponly'], 'samesite' => $params['samesite'], ] ); } } else { /* in older versions of PHP we need a nasty hack to set RFC6265bis SameSite attribute */ if ($params['samesite'] !== null && !preg_match('/;\s+samesite/i', $params['path'])) { $params['path'] .= '; SameSite=' . $params['samesite']; } if ($params['raw']) { $success = @setrawcookie( $name, $value, $expire, $params['path'], $params['domain'], $params['secure'], $params['httponly'] ); } else { $success = @setcookie( $name, $value, $expire, $params['path'], $params['domain'], $params['secure'], $params['httponly'] ); } } if (!$success) { if ($throw) { throw new Error\CannotSetCookie( 'Headers already sent.', Error\CannotSetCookie::HEADERS_SENT ); } Logger::warning('Error setting cookie: headers already sent.'); } } /** * Submit a POST form to a specific destination. * * This function never returns. * * @param string $destination The destination URL. * @param array $data An associative array with the data to be posted to $destination. * * @throws \InvalidArgumentException If $destination is not a string or $data is not an array. * @throws \SimpleSAML\Error\Exception If $destination is not a valid HTTP URL. * * @return void * * @author Olav Morken, UNINETT AS * @author Andjelko Horvat * @author Jaime Perez, UNINETT AS */ public static function submitPOSTData($destination, $data) { if (!is_string($destination) || !is_array($data)) { throw new \InvalidArgumentException('Invalid input parameters.'); } if (!self::isValidURL($destination)) { throw new Error\Exception('Invalid destination URL.'); } $config = Configuration::getInstance(); $allowed = $config->getBoolean('enable.http_post', false); if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) { // we need to post the data to HTTP self::redirect(self::getSecurePOSTRedirectURL($destination, $data)); } $p = new Template($config, 'post.php'); $p->data['destination'] = $destination; $p->data['post'] = $data; $p->show(); exit(0); } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/EMail.php0000644000000000000000000002232414042503475020442 0ustar rootroot * @package SimpleSAMLphp */ class EMail { /** @var array Dictionary with multivalues */ private $data = []; /** @var string Introduction text */ private $text = ''; /** @var PHPMailer The mailer instance */ private $mail; /** * Constructor * * If $from or $to is not provided, the technicalcontact_email * from the configuration is used. * * @param string $subject The subject of the e-mail * @param string $from The from-address (both envelope and header) * @param string $to The recipient * * @throws \PHPMailer\PHPMailer\Exception */ public function __construct($subject, $from = null, $to = null) { $this->mail = new PHPMailer(true); $this->mail->Subject = $subject; $this->mail->setFrom($from ?: static::getDefaultMailAddress()); $this->mail->addAddress($to ?: static::getDefaultMailAddress()); static::initFromConfig($this); } /** * Get the default e-mail address from the configuration * This is used both as source and destination address * unless something else is provided at the constructor. * * It will refuse to return the SimpleSAMLphp default address, * which is na@example.org. * * @return string Default mail address */ public static function getDefaultMailAddress() { $config = Configuration::getInstance(); $address = $config->getString('technicalcontact_email', 'na@example.org'); $address = preg_replace('/^mailto:/i', '', $address); if ('na@example.org' === $address) { throw new \Exception('technicalcontact_email must be changed from the default value'); } return $address; } /** * Set the data that should be embedded in the e-mail body * * @param array $data The data that should be embedded in the e-mail body * @return void */ public function setData(array $data) { /* * Convert every non-array value to an array with the original * as its only element. This guarantees that every value of $data * can be iterated over. */ $this->data = array_map( /** * @param mixed $v * @return array */ function ($v) { return is_array($v) ? $v : [$v]; }, $data ); } /** * Set an introduction text for the e-mail * * @param string $text Introduction text * @return void */ public function setText($text) { $this->text = $text; } /** * Add a Reply-To address to the mail * * @param string $address Reply-To e-mail address * @return void */ public function addReplyTo($address) { $this->mail->addReplyTo($address); } /** * Send the mail * * @param bool $plainTextOnly Do not send HTML payload * @return void * * @throws \PHPMailer\PHPMailer\Exception */ public function send($plainTextOnly = false) { if ($plainTextOnly) { $this->mail->isHTML(false); $this->mail->Body = $this->generateBody('mailtxt.twig'); } else { $this->mail->isHTML(true); $this->mail->Body = $this->generateBody('mailhtml.twig'); $this->mail->AltBody = $this->generateBody('mailtxt.twig'); } $this->mail->send(); } /** * Sets the method by which the email will be sent. Currently supports what * PHPMailer supports: sendmail, mail and smtp. * * @param string $transportMethod the transport method * @param array $transportOptions options for the transport method * * @return void * * @throws \InvalidArgumentException */ public function setTransportMethod($transportMethod, array $transportOptions = []) { assert(is_string($transportMethod)); switch (strtolower($transportMethod)) { // smtp transport method case 'smtp': $this->mail->isSMTP(); // set the host (required) if (isset($transportOptions['host'])) { $this->mail->Host = $transportOptions['host']; } else { // throw an exception otherwise throw new \InvalidArgumentException("Missing Required Email Transport Parameter 'host'"); } // set the port (optional, assume standard SMTP port 25 if not provided) $this->mail->Port = (isset($transportOptions['port'])) ? (int)$transportOptions['port'] : 25; // smtp auth: enabled if username or password is set if (isset($transportOptions['username']) || isset($transportOptions['password'])) { $this->mail->SMTPAuth = true; } // smtp auth: username if (isset($transportOptions['username'])) { $this->mail->Username = $transportOptions['username']; } // smtp auth: password if (isset($transportOptions['password'])) { $this->mail->Password = $transportOptions['password']; } // smtp security: encryption type if (isset($transportOptions['secure'])) { $this->mail->SMTPSecure = $transportOptions['secure']; } // smtp security: enable or disable smtp auto tls if (isset($transportOptions['autotls'])) { $this->mail->SMTPAutoTLS = (bool)$transportOptions['autotls']; } break; //mail transport method case 'mail': $this->mail->isMail(); break; // sendmail transport method case 'sendmail': $this->mail->isSendmail(); // override the default path of the sendmail executable if (isset($transportOptions['path'])) { $this->mail->Sendmail = $transportOptions['path']; } break; default: throw new \InvalidArgumentException( "Invalid Mail Transport Method - Check 'mail.transport.method' Configuration Option" ); } } /** * Initializes the provided EMail object with the configuration provided from the SimpleSAMLphp configuration. * * @param EMail $EMail * @return EMail * @throws \Exception */ public static function initFromConfig(EMail $EMail) { $config = Configuration::getInstance(); $EMail->setTransportMethod( $config->getString('mail.transport.method', 'mail'), $config->getArrayize('mail.transport.options', []) ); return $EMail; } /** * Generate the body of the e-mail * * @param string $template The name of the template to use * * @return string The body of the e-mail */ public function generateBody($template) { $config = Configuration::getInstance(); $newui = $config->getBoolean('usenewui', false); if ($newui === false) { $result = ' SimpleSAMLphp Email report

' . htmlspecialchars($this->mail->Subject) . '

"' . htmlspecialchars($this->text) . '"
'; foreach ($this->data as $name => $values) { $result .= '

' . htmlspecialchars($name) . '

    '; foreach ($values as $value) { $result .= '
  • ' . htmlspecialchars($value) . '
  • '; } $result .= '
'; } } else { $t = new Template($config, $template); $twig = $t->getTwig(); if (!isset($twig)) { throw new \Exception( 'Even though we explicitly configure that we want Twig,' . ' the Template class does not give us Twig. This is a bug.' ); } $result = $twig->render($template, [ 'subject' => $this->mail->Subject, 'text' => $this->text, 'data' => $this->data ]); } return $result; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Arrays.php0000644000000000000000000000320314042503475020707 0ustar rootroot * @author Jaime Perez, UNINETT AS */ public static function arrayize($data, $index = 0) { return (is_array($data)) ? $data : [$index => $data]; } /** * This function transposes a two-dimensional array, so that $a['k1']['k2'] becomes $a['k2']['k1']. * * @param array $array The two-dimensional array to transpose. * * @return mixed The transposed array, or false if $array is not a valid two-dimensional array. * * @author Andreas Solberg, UNINETT AS */ public static function transpose($array) { if (!is_array($array)) { return false; } $ret = []; foreach ($array as $k1 => $a2) { if (!is_array($a2)) { return false; } foreach ($a2 as $k2 => $v) { if (!array_key_exists($k2, $ret)) { $ret[$k2] = []; } $ret[$k2][$k1] = $v; } } return $ret; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/System.php0000644000000000000000000002140614042503475020737 0ustar rootroot */ public static function getOS() { if (stristr(PHP_OS, 'LINUX')) { return self::LINUX; } if (stristr(PHP_OS, 'DARWIN')) { return self::OSX; } if (stristr(PHP_OS, 'WIN')) { return self::WINDOWS; } if (stristr(PHP_OS, 'BSD')) { return self::BSD; } if (stristr(PHP_OS, 'UNIX')) { return self::UNIX; } if (stristr(PHP_OS, 'HP-UX')) { return self::HPUX; } if (stristr(PHP_OS, 'IRIX')) { return self::IRIX; } if (stristr(PHP_OS, 'SUNOS')) { return self::SUNOS; } return false; } /** * This function retrieves the path to a directory where temporary files can be saved. * * @return string Path to a temporary directory, without a trailing directory separator. * @throws Error\Exception If the temporary directory cannot be created or it exists and cannot be written * to by the current user. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS * @author Aaron St. Clair, ECRS AS */ public static function getTempDir() { $globalConfig = Configuration::getInstance(); $tempDir = rtrim( $globalConfig->getString( 'tempdir', sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'simplesaml' ), DIRECTORY_SEPARATOR ); /** * If the temporary directory does not exist then attempt to create it. If the temporary directory * already exists then verify the current user can write to it. Otherwise, throw an error. */ if (!is_dir($tempDir)) { if (!mkdir($tempDir, 0700, true)) { $error = error_get_last(); throw new Error\Exception( 'Error creating temporary directory "' . $tempDir . '": ' . (is_array($error) ? $error['message'] : 'no error available') ); } } elseif (!is_writable($tempDir)) { throw new Error\Exception( 'Temporary directory "' . $tempDir . '" cannot be written to by the current user' . (function_exists('posix_getuid') ? ' "' . posix_getuid() . '"' : '') ); } return $tempDir; } /** * Resolve a (possibly) relative path from the given base path. * * A path which starts with a stream wrapper pattern (e.g. s3://) will not be touched * and returned as is - regardles of the value given as base path. * If it starts with a '/' it is assumed to be absolute, all others are assumed to be * relative. The default base path is the root of the SimpleSAMLphp installation. * * @param string $path The path we should resolve. * @param string|null $base The base path, where we should search for $path from. Default value is the root of the * SimpleSAMLphp installation. * * @return string An absolute path referring to $path. * * @author Olav Morken, UNINETT AS */ public static function resolvePath($path, $base = null) { if ($base === null) { $config = Configuration::getInstance(); $base = $config->getBaseDir(); } // normalise directory separator $base = str_replace('\\', '/', $base); $path = str_replace('\\', '/', $path); // remove trailing slashes $base = rtrim($base, '/'); $path = rtrim($path, '/'); // check for absolute path if (substr($path, 0, 1) === '/') { // absolute path. */ $ret = '/'; } elseif (static::pathContainsDriveLetter($path)) { $ret = ''; } else { // path relative to base $ret = $base; } if (static::pathContainsStreamWrapper($path)) { $ret = $path; } else { $path = explode('/', $path); foreach ($path as $d) { if ($d === '.') { continue; } elseif ($d === '..') { $ret = dirname($ret); } else { if ($ret && substr($ret, -1) !== '/') { $ret .= '/'; } $ret .= $d; } } } return $ret; } /** * Atomically write a file. * * This is a helper function for writing data atomically to a file. It does this by writing the file data to a * temporary file, then renaming it to the required file name. * * @param string $filename The path to the file we want to write to. * @param string $data The data we should write to the file. * @param int $mode The permissions to apply to the file. Defaults to 0600. * * @throws \InvalidArgumentException If any of the input parameters doesn't have the proper types. * @throws Error\Exception If the file cannot be saved, permissions cannot be changed or it is not * possible to write to the target file. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS * @author Andjelko Horvat * @author Jaime Perez, UNINETT AS * * @return void */ public static function writeFile($filename, $data, $mode = 0600) { if (!is_string($filename) || !is_string($data) || !is_numeric($mode)) { throw new \InvalidArgumentException('Invalid input parameters'); } $tmpFile = self::getTempDir() . DIRECTORY_SEPARATOR . rand(); $res = @file_put_contents($tmpFile, $data); if ($res === false) { $error = error_get_last(); throw new Error\Exception( 'Error saving file "' . $tmpFile . '": ' . (is_array($error) ? $error['message'] : 'no error available') ); } if (self::getOS() !== self::WINDOWS) { if (!chmod($tmpFile, $mode)) { unlink($tmpFile); $error = error_get_last(); //$error = (is_array($error) ? $error['message'] : 'no error available'); throw new Error\Exception( 'Error changing file mode of "' . $tmpFile . '": ' . (is_array($error) ? $error['message'] : 'no error available') ); } } if (!rename($tmpFile, $filename)) { unlink($tmpFile); $error = error_get_last(); throw new Error\Exception( 'Error moving "' . $tmpFile . '" to "' . $filename . '": ' . (is_array($error) ? $error['message'] : 'no error available') ); } if (function_exists('opcache_invalidate')) { opcache_invalidate($filename); } } /** * Check if the supplied path is an absolute path. * * @param string $path * * @return bool */ public static function isAbsolutePath(string $path): bool { return (0 === strpos($path, '/') || self::pathContainsDriveLetter($path)); } /** * Check if the supplied path contains a Windows-style drive letter. * * @param string $path * * @return bool */ private static function pathContainsDriveLetter(string $path): bool { $letterAsciiValue = ord(strtoupper(substr($path, 0, 1))); return substr($path, 1, 1) === ':' && $letterAsciiValue >= 65 && $letterAsciiValue <= 90; } /** * Check if the supplied path contains a stream wrapper * @param string $path * @return bool */ private static function pathContainsStreamWrapper(string $path): bool { return preg_match('/^[\w\d]*:\/{2}/', $path) === 1; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/XML.php0000644000000000000000000004156714042503475020125 0ustar rootroot * @author Jaime Perez, UNINETT AS */ public static function checkSAMLMessage($message, $type) { $allowed_types = ['saml20', 'saml11', 'saml-meta']; if (!(is_string($message) && in_array($type, $allowed_types, true))) { throw new \InvalidArgumentException('Invalid input parameters.'); } // a SAML message should not contain a doctype-declaration if (strpos($message, 'getArrayize('debug', ['validatexml' => false]); $enabled = Configuration::getInstance()->getBoolean('debug.validatexml', false); if ( !( in_array('validatexml', $debug, true) || (array_key_exists('validatexml', $debug) && ($debug['validatexml'] === true)) ) ) { // XML validation is disabled return; } $result = true; switch ($type) { case 'saml11': $result = self::isValid($message, 'oasis-sstc-saml-schema-protocol-1.1.xsd'); break; case 'saml20': $result = self::isValid($message, 'saml-schema-protocol-2.0.xsd'); break; case 'saml-meta': $result = self::isValid($message, 'saml-schema-metadata-2.0.xsd'); } if (is_string($result)) { Logger::warning($result); } } /** * Helper function to log SAML messages that we send or receive. * * @param string|\DOMElement $message The message, as an string containing the XML or an XML element. * @param string $type Whether this message is sent or received, encrypted or decrypted. The following * values are supported: * - 'in': for messages received. * - 'out': for outgoing messages. * - 'decrypt': for decrypted messages. * - 'encrypt': for encrypted messages. * * @throws \InvalidArgumentException If $type is not a string or $message is neither a string nor a \DOMElement. * * @return void * * @author Olav Morken, UNINETT AS */ public static function debugSAMLMessage($message, $type) { if (!(is_string($type) && (is_string($message) || $message instanceof DOMElement))) { throw new \InvalidArgumentException('Invalid input parameters.'); } // see if debugging is enabled for SAML messages $debug = Configuration::getInstance()->getArrayize('debug', ['saml' => false]); if ( !(in_array('saml', $debug, true) // implicitly enabled || (array_key_exists('saml', $debug) && $debug['saml'] === true) // explicitly enabled // TODO: deprecate the old style and remove it in 2.0 || (array_key_exists(0, $debug) && $debug[0] === true)) // old style 'debug' ) { // debugging messages is disabled return; } if ($message instanceof DOMElement) { $message = $message->ownerDocument->saveXML($message); } switch ($type) { case 'in': Logger::debug('Received message:'); break; case 'out': Logger::debug('Sending message:'); break; case 'decrypt': Logger::debug('Decrypted message:'); break; case 'encrypt': Logger::debug('Encrypted message:'); break; default: assert(false); } $str = self::formatXMLString($message); foreach (explode("\n", $str) as $line) { Logger::debug($line); } } /** * Format a DOM element. * * This function takes in a DOM element, and inserts whitespace to make it more readable. Note that whitespace * added previously will be removed. * * @param \DOMNode $root The root element which should be formatted. * @param string $indentBase The indentation this element should be assumed to have. Defaults to an empty * string. * * @throws \InvalidArgumentException If $root is not a DOMElement or $indentBase is not a string. * * @return void * * @author Olav Morken, UNINETT AS */ public static function formatDOMElement(DOMNode $root, $indentBase = '') { if (!is_string($indentBase)) { throw new \InvalidArgumentException('Invalid input parameters'); } // check what this element contains $fullText = ''; // all text in this element $textNodes = []; // text nodes which should be deleted $childNodes = []; // other child nodes for ($i = 0; $i < $root->childNodes->length; $i++) { /** @var \DOMNode $child */ $child = $root->childNodes->item($i); if ($child instanceof DOMText) { $textNodes[] = $child; $fullText .= $child->wholeText; } elseif ($child instanceof DOMComment || $child instanceof DOMElement) { $childNodes[] = $child; } else { // unknown node type. We don't know how to format this return; } } $fullText = trim($fullText); if (strlen($fullText) > 0) { // we contain textelf $hasText = true; } else { $hasText = false; } $hasChildNode = (count($childNodes) > 0); if ($hasText && $hasChildNode) { // element contains both text and child nodes - we don't know how to format this one return; } // remove text nodes foreach ($textNodes as $node) { $root->removeChild($node); } if ($hasText) { // only text - add a single text node to the element with the full text $root->appendChild(new DOMText($fullText)); return; } if (!$hasChildNode) { // empty node. Nothing to do return; } /* Element contains only child nodes - add indentation before each one, and * format child elements. */ $childIndentation = $indentBase . ' '; foreach ($childNodes as $node) { // add indentation before node $root->insertBefore(new DOMText("\n" . $childIndentation), $node); // format child elements if ($node instanceof \DOMElement) { self::formatDOMElement($node, $childIndentation); } } // add indentation before closing tag $root->appendChild(new DOMText("\n" . $indentBase)); } /** * Format an XML string. * * This function formats an XML string using the formatDOMElement() function. * * @param string $xml An XML string which should be formatted. * @param string $indentBase Optional indentation which should be applied to all the output. Optional, defaults * to ''. * * @return string The formatted string. * @throws \InvalidArgumentException If the parameters are not strings. * @throws \DOMException If the input does not parse correctly as an XML string. * * @author Olav Morken, UNINETT AS */ public static function formatXMLString($xml, $indentBase = '') { if (!is_string($xml) || !is_string($indentBase)) { throw new \InvalidArgumentException('Invalid input parameters'); } try { $doc = DOMDocumentFactory::fromString($xml); } catch (\Exception $e) { throw new \DOMException('Error parsing XML string.'); } $root = $doc->firstChild; self::formatDOMElement($root, $indentBase); return $doc->saveXML($root); } /** * This function finds direct descendants of a DOM element with the specified * localName and namespace. They are returned in an array. * * This function accepts the same shortcuts for namespaces as the isDOMNodeOfType function. * * @param \DOMNode $element The element we should look in. * @param string $localName The name the element should have. * @param string $namespaceURI The namespace the element should have. * * @return array Array with the matching elements in the order they are found. An empty array is * returned if no elements match. * @throws \InvalidArgumentException If $element is not an instance of DOMElement, $localName is not a string or * $namespaceURI is not a string. */ public static function getDOMChildren(DOMNode $element, $localName, $namespaceURI) { if (!is_string($localName) || !is_string($namespaceURI)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $ret = []; for ($i = 0; $i < $element->childNodes->length; $i++) { /** @var \DOMNode $child */ $child = $element->childNodes->item($i); // skip text nodes and comment elements if ($child instanceof DOMText || $child instanceof DOMComment) { continue; } if (self::isDOMNodeOfType($child, $localName, $namespaceURI) === true) { $ret[] = $child; } } return $ret; } /** * This function extracts the text from DOMElements which should contain only text content. * * @param \DOMElement $element The element we should extract text from. * * @return string The text content of the element. * @throws \SimpleSAML\Error\Exception If the element contains a non-text child node. * * @author Olav Morken, UNINETT AS */ public static function getDOMText(DOMElement $element) { $txt = ''; for ($i = 0; $i < $element->childNodes->length; $i++) { /** @var \DOMElement $child */ $child = $element->childNodes->item($i); if (!($child instanceof DOMText)) { throw new Error\Exception($element->localName . ' contained a non-text child node.'); } $txt .= $child->wholeText; } $txt = trim($txt); return $txt; } /** * This function checks if the DOMElement has the correct localName and namespaceURI. * * We also define the following shortcuts for namespaces: * - '@ds': 'http://www.w3.org/2000/09/xmldsig#' * - '@md': 'urn:oasis:names:tc:SAML:2.0:metadata' * - '@saml1': 'urn:oasis:names:tc:SAML:1.0:assertion' * - '@saml1md': 'urn:oasis:names:tc:SAML:profiles:v1metadata' * - '@saml1p': 'urn:oasis:names:tc:SAML:1.0:protocol' * - '@saml2': 'urn:oasis:names:tc:SAML:2.0:assertion' * - '@saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol' * * @param \DOMNode $element The element we should check. * @param string $name The local name the element should have. * @param string $nsURI The namespaceURI the element should have. * * @return boolean True if both namespace and local name matches, false otherwise. * @throws \InvalidArgumentException If the namespace shortcut is unknown. * * @author Andreas Solberg, UNINETT AS * @author Olav Morken, UNINETT AS */ public static function isDOMNodeOfType(DOMNode $element, $name, $nsURI) { if (!is_string($name) || !is_string($nsURI) || strlen($nsURI) === 0) { // most likely a comment-node return false; } // check if the namespace is a shortcut, and expand it if it is if ($nsURI[0] === '@') { // the defined shortcuts $shortcuts = [ '@ds' => 'http://www.w3.org/2000/09/xmldsig#', '@md' => 'urn:oasis:names:tc:SAML:2.0:metadata', '@saml1' => 'urn:oasis:names:tc:SAML:1.0:assertion', '@saml1md' => 'urn:oasis:names:tc:SAML:profiles:v1metadata', '@saml1p' => 'urn:oasis:names:tc:SAML:1.0:protocol', '@saml2' => 'urn:oasis:names:tc:SAML:2.0:assertion', '@saml2p' => 'urn:oasis:names:tc:SAML:2.0:protocol', '@shibmd' => 'urn:mace:shibboleth:metadata:1.0', ]; // check if it is a valid shortcut if (!array_key_exists($nsURI, $shortcuts)) { throw new \InvalidArgumentException('Unknown namespace shortcut: ' . $nsURI); } // expand the shortcut $nsURI = $shortcuts[$nsURI]; } if ($element->localName !== $name) { return false; } if ($element->namespaceURI !== $nsURI) { return false; } return true; } /** * This function attempts to validate an XML string against the specified schema. It will parse the string into a * DOM document and validate this document against the schema. * * Note that this function returns values that are evaluated as a logical true, both when validation works and when * it doesn't. Please use strict comparisons to check the values returned. * * @param string|\DOMDocument $xml The XML string or document which should be validated. * @param string $schema The filename of the schema that should be used to validate the document. * * @return bool|string Returns a string with errors found if validation fails. True if validation passes ok. * @throws \InvalidArgumentException If $schema is not a string, or $xml is neither a string nor a \DOMDocument. * * @author Olav Morken, UNINETT AS */ public static function isValid($xml, $schema) { if (!(is_string($schema) && (is_string($xml) || $xml instanceof DOMDocument))) { throw new \InvalidArgumentException('Invalid input parameters.'); } Errors::begin(); if ($xml instanceof DOMDocument) { $dom = $xml; $res = true; } else { try { $dom = DOMDocumentFactory::fromString($xml); $res = true; } catch (\Exception $e) { $res = false; } } if ($res === true) { $config = Configuration::getInstance(); /** @var string $schemaPath */ $schemaPath = $config->resolvePath('schemas'); $schemaFile = $schemaPath . '/' . $schema; libxml_set_external_entity_loader( /** * @param string|null $public * @param string $system * @param array $context * @return string|null */ function (string $public = null, string $system, array $context) { if (filter_var($system, FILTER_VALIDATE_URL) === $system) { return null; } return $system; } ); /** @psalm-suppress PossiblyUndefinedVariable */ $res = $dom->schemaValidate($schemaFile); if ($res) { Errors::end(); return true; } $errorText = "Schema validation failed on XML string:\n"; } else { $errorText = "Failed to parse XML string for schema validation:\n"; } $errors = Errors::end(); $errorText .= Errors::formatErrors($errors); return $errorText; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Random.php0000644000000000000000000000143514042503475020673 0ustar rootroot * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function generateID() { return '_' . bin2hex(openssl_random_pseudo_bytes((int) ((self::ID_LENGTH - 1) / 2))); } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Config/0000755000000000000000000000000014042503475020144 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Utils/Config/Metadata.php0000644000000000000000000003126014042503475022377 0ustar rootroot */ class Metadata { /** * The string that identities Entity Categories. * * @var string */ public static $ENTITY_CATEGORY = 'http://macedir.org/entity-category'; /** * The string the identifies the REFEDS "Hide From Discovery" Entity Category. * * @var string */ public static $HIDE_FROM_DISCOVERY = 'http://refeds.org/category/hide-from-discovery'; /** * Valid options for the ContactPerson element * * The 'attributes' option isn't defined in section 2.3.2.2 of the OASIS document, but * it is required to allow additons to the main contact person element for trust * frameworks. * * @var array The valid configuration options for a contact configuration array. * @see "Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0", section 2.3.2.2. */ public static $VALID_CONTACT_OPTIONS = [ 'contactType', 'emailAddress', 'givenName', 'surName', 'telephoneNumber', 'company', 'attributes', ]; /** * @var array The valid types of contact for a contact configuration array. * @see "Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0", section 2.3.2.2. */ public static $VALID_CONTACT_TYPES = [ 'technical', 'support', 'administrative', 'billing', 'other', ]; /** * Parse and sanitize a contact from an array. * * Accepts an array with the following elements: * - contactType The type of the contact (as string). Mandatory. * - emailAddress Email address (as string), or array of email addresses. Optional. * - telephoneNumber Telephone number of contact (as string), or array of telephone numbers. Optional. * - name Full name of contact, either as , or as , . Optional. * - surName Surname of contact (as string). Optional. * - givenName Given name of contact (as string). Optional. * - company Company name of contact (as string). Optional. * * The following values are allowed as "contactType": * - technical * - support * - administrative * - billing * - other * * If given a "name" it will try to decompose it into its given name and surname, only if neither givenName nor * surName are present. It works as follows: * - "surname1 surname2, given_name1 given_name2" * givenName: "given_name1 given_name2" * surname: "surname1 surname2" * - "given_name surname" * givenName: "given_name" * surname: "surname" * * otherwise it will just return the name as "givenName" in the resulting array. * * @param array $contact The contact to parse and sanitize. * * @return array An array holding valid contact configuration options. If a key 'name' was part of the input array, * it will try to decompose the name into its parts, and place the parts into givenName and surName, if those are * missing. * @throws \InvalidArgumentException If $contact is neither an array nor null, or the contact does not conform to * valid configuration rules for contacts. */ public static function getContact($contact) { if (!(is_array($contact) || is_null($contact))) { throw new \InvalidArgumentException('Invalid input parameters'); } // check the type if (!isset($contact['contactType']) || !in_array($contact['contactType'], self::$VALID_CONTACT_TYPES, true)) { $types = join(', ', array_map( /** * @param string $t * @return string */ function ($t) { return '"' . $t . '"'; }, self::$VALID_CONTACT_TYPES )); throw new \InvalidArgumentException('"contactType" is mandatory and must be one of ' . $types . "."); } // check attributes is an associative array if (isset($contact['attributes'])) { if ( empty($contact['attributes']) || !is_array($contact['attributes']) || count(array_filter(array_keys($contact['attributes']), 'is_string')) === 0 ) { throw new \InvalidArgumentException('"attributes" must be an array and cannot be empty.'); } } // try to fill in givenName and surName from name if (isset($contact['name']) && !isset($contact['givenName']) && !isset($contact['surName'])) { // first check if it's comma separated $names = explode(',', $contact['name'], 2); if (count($names) === 2) { $contact['surName'] = preg_replace('/\s+/', ' ', trim($names[0])); $contact['givenName'] = preg_replace('/\s+/', ' ', trim($names[1])); } else { // check if it's in "given name surname" format $names = explode(' ', preg_replace('/\s+/', ' ', trim($contact['name']))); if (count($names) === 2) { $contact['givenName'] = preg_replace('/\s+/', ' ', trim($names[0])); $contact['surName'] = preg_replace('/\s+/', ' ', trim($names[1])); } else { // nothing works, return it as given name $contact['givenName'] = preg_replace('/\s+/', ' ', trim($contact['name'])); } } } // check givenName if ( isset($contact['givenName']) && ( empty($contact['givenName']) || !is_string($contact['givenName']) ) ) { throw new \InvalidArgumentException('"givenName" must be a string and cannot be empty.'); } // check surName if ( isset($contact['surName']) && ( empty($contact['surName']) || !is_string($contact['surName']) ) ) { throw new \InvalidArgumentException('"surName" must be a string and cannot be empty.'); } // check company if ( isset($contact['company']) && ( empty($contact['company']) || !is_string($contact['company']) ) ) { throw new \InvalidArgumentException('"company" must be a string and cannot be empty.'); } // check emailAddress if (isset($contact['emailAddress'])) { if ( empty($contact['emailAddress']) || !( is_string($contact['emailAddress']) || is_array($contact['emailAddress']) ) ) { throw new \InvalidArgumentException('"emailAddress" must be a string or an array and cannot be empty.'); } if (is_array($contact['emailAddress'])) { foreach ($contact['emailAddress'] as $address) { if (!is_string($address) || empty($address)) { throw new \InvalidArgumentException('Email addresses must be a string and cannot be empty.'); } } } } // check telephoneNumber if (isset($contact['telephoneNumber'])) { if ( empty($contact['telephoneNumber']) || !( is_string($contact['telephoneNumber']) || is_array($contact['telephoneNumber']) ) ) { throw new \InvalidArgumentException( '"telephoneNumber" must be a string or an array and cannot be empty.' ); } if (is_array($contact['telephoneNumber'])) { foreach ($contact['telephoneNumber'] as $address) { if (!is_string($address) || empty($address)) { throw new \InvalidArgumentException('Telephone numbers must be a string and cannot be empty.'); } } } } // make sure only valid options are outputted return array_intersect_key($contact, array_flip(self::$VALID_CONTACT_OPTIONS)); } /** * Find the default endpoint in an endpoint array. * * @param array $endpoints An array with endpoints. * @param array $bindings An array with acceptable bindings. Can be null if any binding is allowed. * * @return array|NULL The default endpoint, or null if no acceptable endpoints are used. * * @author Olav Morken, UNINETT AS */ public static function getDefaultEndpoint(array $endpoints, array $bindings = null) { $firstNotFalse = null; $firstAllowed = null; // look through the endpoint list for acceptable endpoints foreach ($endpoints as $ep) { if ($bindings !== null && !in_array($ep['Binding'], $bindings, true)) { // unsupported binding, skip it continue; } if (isset($ep['isDefault'])) { if ($ep['isDefault'] === true) { // this is the first endpoint with isDefault set to true return $ep; } // isDefault is set to false, but the endpoint is still usable as a last resort if ($firstAllowed === null) { // this is the first endpoint that we can use $firstAllowed = $ep; } } else { if ($firstNotFalse === null) { // this is the first endpoint without isDefault set $firstNotFalse = $ep; } } } if ($firstNotFalse !== null) { // we have an endpoint without isDefault set to false return $firstNotFalse; } /* $firstAllowed either contains the first endpoint we can use, or it contains null if we cannot use any of the * endpoints. Either way we return its value. */ return $firstAllowed; } /** * Determine if an entity should be hidden in the discovery service. * * This method searches for the "Hide From Discovery" REFEDS Entity Category, and tells if the entity should be * hidden or not depending on it. * * @see https://refeds.org/category/hide-from-discovery * * @param array $metadata An associative array with the metadata representing an entity. * * @return boolean True if the entity should be hidden, false otherwise. */ public static function isHiddenFromDiscovery(array $metadata) { if (!isset($metadata['EntityAttributes'][self::$ENTITY_CATEGORY])) { return false; } return in_array(self::$HIDE_FROM_DISCOVERY, $metadata['EntityAttributes'][self::$ENTITY_CATEGORY], true); } /** * This method parses the different possible values of the NameIDPolicy metadata configuration. * * @param mixed $nameIdPolicy * * @return null|array */ public static function parseNameIdPolicy($nameIdPolicy) { $policy = null; if (is_string($nameIdPolicy)) { // handle old configurations where 'NameIDPolicy' was used to specify just the format $policy = ['Format' => $nameIdPolicy, 'AllowCreate' => true]; } elseif (is_array($nameIdPolicy)) { // handle current configurations specifying an array in the NameIDPolicy config option $nameIdPolicy_cf = Configuration::loadFromArray($nameIdPolicy); $policy = [ 'Format' => $nameIdPolicy_cf->getString('Format', Constants::NAMEID_TRANSIENT), 'AllowCreate' => $nameIdPolicy_cf->getBoolean('AllowCreate', true), ]; $spNameQualifier = $nameIdPolicy_cf->getString('SPNameQualifier', false); if ($spNameQualifier !== false) { $policy['SPNameQualifier'] = $spNameQualifier; } } elseif ($nameIdPolicy === null) { // when NameIDPolicy is unset or set to null, default to transient as before $policy = ['Format' => Constants::NAMEID_TRANSIENT, 'AllowCreate' => true]; } return $policy; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/ClearableState.php0000644000000000000000000000060214042503475022321 0ustar rootroot * @author Olav Morken, UNINETT AS * @author Brook Schofield, GÉANT * @author Jaime Perez, UNINETT AS */ public static function ipCIDRcheck($cidr, $ip = null) { if ($ip === null) { $ip = $_SERVER['REMOTE_ADDR']; } if (strpos($cidr, '/') === false) { return false; } list ($net, $mask) = explode('/', $cidr); $mask = intval($mask); $ip_ip = []; $ip_net = []; if (strstr($ip, ':') || strstr($net, ':')) { // Validate IPv6 with inet_pton, convert to hex with bin2hex // then store as a long with hexdec $ip_pack = @inet_pton($ip); $net_pack = @inet_pton($net); if ($ip_pack === false || $net_pack === false) { // not valid IPv6 address (warning silenced) return false; } $ip_ip = str_split(bin2hex($ip_pack), 8); foreach ($ip_ip as &$value) { $value = hexdec($value); } $ip_net = str_split(bin2hex($net_pack), 8); foreach ($ip_net as &$value) { $value = hexdec($value); } } else { $ip_ip[0] = ip2long($ip); $ip_net[0] = ip2long($net); } for ($i = 0; $mask > 0 && $i < sizeof($ip_ip); $i++) { if ($mask > 32) { $iteration_mask = 32; } else { $iteration_mask = $mask; } $mask -= 32; $ip_mask = ~((1 << (32 - $iteration_mask)) - 1); $ip_net_mask = intval($ip_net[$i]) & $ip_mask; $ip_ip_mask = intval($ip_ip[$i]) & $ip_mask; if ($ip_ip_mask != $ip_net_mask) { return false; } } return true; } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Crypto.php0000644000000000000000000004436614042503475020745 0ustar rootroot * @author Jaime Perez, UNINETT AS */ public static function aesDecrypt($ciphertext) { return self::aesDecryptInternal($ciphertext, Config::getSecretSalt()); } /** * Encrypt data using AES-256-CBC and the key provided as a parameter. * * @param string $data The data to encrypt. * @param string $secret The secret to use to encrypt the data. * * @return string An HMAC of the encrypted data, the IV and the encrypted data, concatenated. * @throws \InvalidArgumentException If $data is not a string. * @throws Error\Exception If the openssl module is not loaded. * * @see \SimpleSAML\Utils\Crypto::aesEncrypt() */ private static function aesEncryptInternal(string $data, string $secret): string { if (!function_exists("openssl_encrypt")) { throw new Error\Exception('The openssl PHP module is not loaded.'); } // derive encryption and authentication keys from the secret $key = openssl_digest($secret, 'sha512'); // generate a random IV $iv = openssl_random_pseudo_bytes(16); // encrypt the message /** @var string|false $ciphertext */ $ciphertext = openssl_encrypt( $data, 'AES-256-CBC', substr($key, 0, 64), defined('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : 1, $iv ); if ($ciphertext === false) { throw new Error\Exception("Failed to encrypt plaintext."); } // return the ciphertext with proper authentication return hash_hmac('sha256', $iv . $ciphertext, substr($key, 64, 64), true) . $iv . $ciphertext; } /** * Encrypt data using AES-256-CBC and the system-wide secret salt as key. * * @param string $data The data to encrypt. * * @return string An HMAC of the encrypted data, the IV and the encrypted data, concatenated. * @throws \InvalidArgumentException If $data is not a string. * @throws Error\Exception If the openssl module is not loaded. * * @author Andreas Solberg, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function aesEncrypt($data) { return self::aesEncryptInternal($data, Config::getSecretSalt()); } /** * Convert data from DER to PEM encoding. * * @param string $der Data encoded in DER format. * @param string $type The type of data we are encoding, as expressed by the PEM header. Defaults to "CERTIFICATE". * @return string The same data encoded in PEM format. * @see RFC7648 for known types and PEM format specifics. */ public static function der2pem($der, $type = 'CERTIFICATE') { return "-----BEGIN " . $type . "-----\n" . chunk_split(base64_encode($der), 64, "\n") . "-----END " . $type . "-----\n"; } /** * Load a private key from metadata. * * This function loads a private key from a metadata array. It looks 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. Defaults to false. * @param string $prefix The prefix which should be used when reading from the metadata * array. Defaults to ''. * @param bool $full_path Whether the filename found in the configuration contains the * full path to the private key or not. Default to false. * * @return array|NULL Extracted private key, or NULL if no private key is present. * @throws \InvalidArgumentException If $required is not boolean or $prefix is not a string. * @throws 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 */ public static function loadPrivateKey(Configuration $metadata, $required = false, $prefix = '', $full_path = false) { if (!is_bool($required) || !is_string($prefix) || !is_bool($full_path)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $file = $metadata->getString($prefix . 'privatekey', null); if ($file === null) { // no private key found if ($required) { throw new Error\Exception('No private key found in metadata.'); } else { return null; } } if (!$full_path) { $file = Config::getCertPath($file); } $data = @file_get_contents($file); if ($data === false) { throw new Error\Exception('Unable to load private key from file "' . $file . '"'); } $ret = [ 'PEM' => $data, 'password' => $metadata->getString($prefix . 'privatekey_pass', null), ]; return $ret; } /** * 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. (deprecated) * * 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. (Deprecated. Only present if this is a * certificate.) * * @param \SimpleSAML\Configuration $metadata The metadata. * @param bool $required Whether the public 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 Error\Exception If no public 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(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 (!empty($keys)) { 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 [ 'certData' => $certData, 'PEM' => $pem, 'certFingerprint' => [$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 ['certFingerprint' => $fps]; } // no public key/certificate available if ($required) { throw new Error\Exception('No public key / certificate found in metadata.'); } else { return null; } } /** * Convert from PEM to DER encoding. * * @param string $pem Data encoded in PEM format. * @return string The same data encoded in DER format. * @throws \InvalidArgumentException If $pem is not encoded in PEM format. * @see RFC7648 for PEM format specifics. */ public static function pem2der($pem) { $pem = trim($pem); $begin = "-----BEGIN "; $end = "-----END "; $lines = explode("\n", $pem); $last = count($lines) - 1; if (strpos($lines[0], $begin) !== 0) { throw new \InvalidArgumentException("pem2der: input is not encoded in PEM format."); } unset($lines[0]); if (strpos($lines[$last], $end) !== 0) { throw new \InvalidArgumentException("pem2der: input is not encoded in PEM format."); } unset($lines[$last]); return base64_decode(implode($lines)); } /** * This function hashes a password with a given algorithm. * * @param string $password The password to hash. * @param string|null $algorithm @deprecated The hashing algorithm, uppercase, optionally * prepended with 'S' (salted). See hash_algos() for a complete list of hashing algorithms. * @param string|null $salt @deprecated An optional salt to use. * * @return string The hashed password. * @throws \InvalidArgumentException If the input parameter is not a string. * @throws Error\Exception If the algorithm specified is not supported. * * @see hash_algos() * * @author Dyonisius Visser, TERENA * @author Jaime Perez, UNINETT AS */ public static function pwHash($password, $algorithm = null, $salt = null) { if (!is_null($algorithm)) { // @deprecated Old-style if (!is_string($algorithm) || !is_string($password)) { throw new \InvalidArgumentException('Invalid input parameters.'); } // hash w/o salt if (in_array(strtolower($algorithm), hash_algos(), true)) { $alg_str = '{' . str_replace('SHA1', 'SHA', $algorithm) . '}'; // LDAP compatibility $hash = hash(strtolower($algorithm), $password, true); return $alg_str . base64_encode($hash); } // hash w/ salt if ($salt === null) { // no salt provided, generate one // default 8 byte salt, but 4 byte for LDAP SHA1 hashes $bytes = ($algorithm == 'SSHA1') ? 4 : 8; $salt = openssl_random_pseudo_bytes($bytes); } if ($algorithm[0] == 'S' && in_array(substr(strtolower($algorithm), 1), hash_algos(), true)) { $alg = substr(strtolower($algorithm), 1); // 'sha256' etc $alg_str = '{' . str_replace('SSHA1', 'SSHA', $algorithm) . '}'; // LDAP compatibility $hash = hash($alg, $password . $salt, true); return $alg_str . base64_encode($hash . $salt); } throw new Error\Exception('Hashing algorithm \'' . strtolower($algorithm) . '\' is not supported'); } else { if (!is_string($password)) { throw new \InvalidArgumentException('Invalid input parameter.'); } elseif (!is_string($hash = password_hash($password, PASSWORD_DEFAULT))) { throw new \InvalidArgumentException('Error while hashing password.'); } return $hash; } } /** * Compare two strings securely. * * This method checks if two strings are equal in constant time, avoiding timing attacks. Use it every time we need * to compare a string with a secret that shouldn't be leaked, i.e. when verifying passwords, one-time codes, etc. * * @param string $known A known string. * @param string $user A user-provided string to compare with the known string. * * @return bool True if both strings are equal, false otherwise. */ public static function secureCompare($known, $user) { return hash_equals($known, $user); } /** * This function checks if a password is valid * * @param string $hash The password as it appears in password file, optionally prepended with algorithm. * @param string $password The password to check in clear. * * @return boolean True if the hash corresponds with the given password, false otherwise. * @throws \InvalidArgumentException If the input parameters are not strings. * @throws Error\Exception If the algorithm specified is not supported. * * @author Dyonisius Visser, TERENA */ public static function pwValid($hash, $password) { if (!is_string($hash) || !is_string($password)) { throw new \InvalidArgumentException('Invalid input parameters.'); } // Prior to PHP 7.4 password_get_info() would set the algo to 0 instead of NULL when it's not detected $info = password_get_info($password); if ($info['algo'] !== null && $info['algo'] !== 0) { throw new Error\Exception("Cannot use a hash value for authentication."); } if (password_verify($password, $hash)) { return true; } // return $hash === $password // @deprecated remove everything below this line for 2.0 // match algorithm string (e.g. '{SSHA256}', '{MD5}') if (preg_match('/^{(.*?)}(.*)$/', $hash, $matches)) { // LDAP compatibility $alg = preg_replace('/^(S?SHA)$/', '${1}1', $matches[1]); // hash w/o salt if (in_array(strtolower($alg), hash_algos(), true)) { return self::secureCompare($hash, self::pwHash($password, $alg)); } // hash w/ salt if ($alg[0] === 'S' && in_array(substr(strtolower($alg), 1), hash_algos(), true)) { $php_alg = substr(strtolower($alg), 1); // get hash length of this algorithm to learn how long the salt is $hash_length = strlen(hash($php_alg, '', true)); $salt = substr(base64_decode($matches[2]), $hash_length); return self::secureCompare($hash, self::pwHash($password, $alg, $salt)); } throw new Error\Exception('Hashing algorithm \'' . strtolower($alg) . '\' is not supported'); } else { return $hash === $password; } } } simplesamlphp-1.19.1/lib/SimpleSAML/Utils/Auth.php0000644000000000000000000000606314042503475020356 0ustar rootroot $returnTo]); } /** * Retrieve an admin logout URL. * * @param string|NULL $returnTo The URL the user should arrive on after admin authentication. Defaults to null. * * @return string A URL which can be used for logging out. * @throws \InvalidArgumentException If $returnTo is neither a string nor null. */ public static function getAdminLogoutURL($returnTo = null) { if (!(is_string($returnTo) || is_null($returnTo))) { throw new \InvalidArgumentException('Invalid input parameters.'); } $as = new Authentication\Simple('admin'); return $as->getLogoutURL($returnTo = null); } /** * Check whether the current user is admin. * * @return boolean True if the current user is an admin user, false otherwise. * * @author Olav Morken, UNINETT AS */ public static function isAdmin() { $session = Session::getSessionFromRequest(); return $session->isValid('admin') || $session->isValid('login-admin'); } /** * Require admin access to the current page. * * This is a helper function for limiting a page to those with administrative access. It will redirect the user to * a login page if the current user doesn't have admin access. * * @return void This function will only return if the user is admin. * @throws \SimpleSAML\Error\Exception If no "admin" authentication source was configured. * * @author Olav Morken, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function requireAdmin() { if (self::isAdmin()) { return; } // not authenticated as admin user, start authentication if (Authentication\Source::getById('admin') !== null) { $as = new Authentication\Simple('admin'); $as->login(); } else { throw new Error\Exception( 'Cannot find "admin" auth source, and admin privileges are required.' ); } } } simplesamlphp-1.19.1/lib/SimpleSAML/Bindings/0000755000000000000000000000000014042503475017374 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Bindings/Shib13/0000755000000000000000000000000014042503475020425 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php0000644000000000000000000001231014042503475022560 0ustar rootroot * @package SimpleSAMLphp * @deprecated This class will be removed in a future release */ namespace SimpleSAML\Bindings\Shib13; use SAML2\DOMDocumentFactory; use SimpleSAML\Configuration; use SimpleSAML\Metadata\MetaDataStorageHandler; use SimpleSAML\Utils; use SimpleSAML\XML\Shib13\AuthnResponse; use SimpleSAML\XML\Signer; class HTTPPost { /** * @var \SimpleSAML\Configuration */ private $configuration; /** * @var \SimpleSAML\Metadata\MetaDataStorageHandler */ private $metadata; /** * Constructor for the \SimpleSAML\Bindings\Shib13\HTTPPost class. * * @param \SimpleSAML\Configuration $configuration The configuration to use. * @param \SimpleSAML\Metadata\MetaDataStorageHandler $metadatastore A store where to find metadata. */ public function __construct( Configuration $configuration, MetaDataStorageHandler $metadatastore ) { $this->configuration = $configuration; $this->metadata = $metadatastore; } /** * Send an authenticationResponse using HTTP-POST. * * @param string $response The response which should be sent. * @param \SimpleSAML\Configuration $idpmd The metadata of the IdP which is sending the response. * @param \SimpleSAML\Configuration $spmd The metadata of the SP which is receiving the response. * @param string|null $relayState The relaystate for the SP. * @param string $shire The shire which should receive the response. * @return void */ public function sendResponse( $response, Configuration $idpmd, Configuration $spmd, $relayState, $shire ) { Utils\XML::checkSAMLMessage($response, 'saml11'); $privatekey = Utils\Crypto::loadPrivateKey($idpmd, true); $publickey = Utils\Crypto::loadPublicKey($idpmd, true); $responsedom = DOMDocumentFactory::fromString(str_replace("\r", "", $response)); $responseroot = $responsedom->getElementsByTagName('Response')->item(0); $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); /* Determine what we should sign - either the Response element or the Assertion. The default is to sign the * Assertion, but that can be overridden by the 'signresponse' option in the SP metadata or * 'saml20.signresponse' in the global configuration. * * TODO: neither 'signresponse' nor 'shib13.signresponse' are valid options any longer. Remove! */ if ($spmd->hasValue('signresponse')) { $signResponse = $spmd->getBoolean('signresponse'); } else { $signResponse = $this->configuration->getBoolean('shib13.signresponse', true); } // check if we have an assertion to sign. Force to sign the response if not if ($firstassertionroot === null) { $signResponse = true; } $signer = new Signer([ 'privatekey_array' => $privatekey, 'publickey_array' => $publickey, 'id' => ($signResponse ? 'ResponseID' : 'AssertionID'), ]); if ($idpmd->hasValue('certificatechain')) { $signer->addCertificate($idpmd->getString('certificatechain')); } if ($signResponse) { // sign the response - this must be done after encrypting the assertion // we insert the signature before the saml2p:Status element $statusElements = Utils\XML::getDOMChildren($responseroot, 'Status', '@saml1p'); assert(count($statusElements) === 1); $signer->sign($responseroot, $responseroot, $statusElements[0]); } else { // Sign the assertion $signer->sign($firstassertionroot, $firstassertionroot); } $response = $responsedom->saveXML(); Utils\XML::debugSAMLMessage($response, 'out'); Utils\HTTP::submitPOSTData($shire, [ 'TARGET' => $relayState, 'SAMLResponse' => base64_encode($response), ]); } /** * Decode a received response. * * @param array $post POST data received. * @return \SimpleSAML\XML\Shib13\AuthnResponse The response decoded into an object. * @throws \Exception If there is no SAMLResponse parameter. */ public function decodeResponse($post) { assert(is_array($post)); if (!array_key_exists('SAMLResponse', $post)) { throw new \Exception('Missing required SAMLResponse parameter.'); } $rawResponse = $post['SAMLResponse']; $samlResponseXML = base64_decode($rawResponse); Utils\XML::debugSAMLMessage($samlResponseXML, 'in'); Utils\XML::checkSAMLMessage($samlResponseXML, 'saml11'); $samlResponse = new AuthnResponse(); $samlResponse->setXML($samlResponseXML); if (array_key_exists('TARGET', $post)) { $samlResponse->setRelayState($post['TARGET']); } return $samlResponse; } } simplesamlphp-1.19.1/lib/SimpleSAML/Bindings/Shib13/Artifact.php0000644000000000000000000001421614042503475022677 0ustar rootroot'. ''. ''; foreach ($artifacts as $a) { $msg .= ''.htmlspecialchars($a).''; } $msg .= ''. ''. ''; return $msg; } /** * Extract the response element from the SOAP response. * * @param string $soapResponse The SOAP response. * @return string The element, as a string. * @throws Error\Exception */ private static function extractResponse(string $soapResponse): string { try { $doc = DOMDocumentFactory::fromString($soapResponse); } catch (\Exception $e) { throw new Error\Exception('Error parsing SAML 1 artifact response.'); } $soapEnvelope = $doc->firstChild; if (!Utils\XML::isDOMNodeOfType($soapEnvelope, 'Envelope', 'http://schemas.xmlsoap.org/soap/envelope/')) { throw new Error\Exception('Expected artifact response to contain a element.'); } $soapBody = Utils\XML::getDOMChildren($soapEnvelope, 'Body', 'http://schemas.xmlsoap.org/soap/envelope/'); if (count($soapBody) === 0) { throw new Error\Exception('Couldn\'t find in .'); } $soapBody = $soapBody[0]; $responseElement = Utils\XML::getDOMChildren($soapBody, 'Response', 'urn:oasis:names:tc:SAML:1.0:protocol'); if (count($responseElement) === 0) { throw new Error\Exception('Couldn\'t find in .'); } $responseElement = $responseElement[0]; /* * Save the element. Note that we need to import it * into a new document, in order to preserve namespace declarations. */ $newDoc = DOMDocumentFactory::create(); $newDoc->appendChild($newDoc->importNode($responseElement, true)); $responseXML = $newDoc->saveXML(); return $responseXML; } /** * 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 element, as an XML string. * @throws Error\Exception */ public static function receive(Configuration $spMetadata, Configuration $idpMetadata) { $artifacts = self::getArtifacts(); $request = self::buildRequest($artifacts); Utils\XML::debugSAMLMessage($request, 'out'); /** @var array $url */ $url = $idpMetadata->getDefaultEndpoint( 'ArtifactResolutionService', ['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 = Utils\System::getTempDir().DIRECTORY_SEPARATOR.sha1($certData).'.crt'; if (!file_exists($file)) { Utils\System::writeFile($file, $certData); } $spKeyCertFile = Utils\Config::getCertPath($spMetadata->getString('privatekey')); $opts = [ 'ssl' => [ 'verify_peer' => true, 'cafile' => $file, 'local_cert' => $spKeyCertFile, 'capture_peer_cert' => true, 'capture_peer_chain' => true, ], 'http' => [ 'method' => 'POST', 'content' => $request, 'header' => 'SOAPAction: http://www.oasis-open.org/committees/security'."\r\n". 'Content-Type: text/xml', ], ]; // Fetch the artifact /** @var string $response */ $response = Utils\HTTP::fetch($url, $opts); Utils\XML::debugSAMLMessage($response, 'in'); // Find the response in the SOAP message $response = self::extractResponse($response); return $response; } } simplesamlphp-1.19.1/lib/SimpleSAML/Memcache.php0000644000000000000000000004325714042503475020065 0ustar rootrootget($key); if ($serializedInfo === false) { // either the server is down, or we don't have the value stored on that server $mustUpdate = true; $up = $server->getStats(); if ($up !== false) { $allDown = false; } continue; } $allDown = false; // unserialize the object /** @var string $serializedInfo */ $info = unserialize($serializedInfo); /* * Make sure that this is an array with two keys: * - 'timestamp': The time the data was saved. * - 'data': The data. */ if (!is_array($info)) { Logger::warning( 'Retrieved invalid data from a memcache server. Data was not an array.' ); continue; } if (!array_key_exists('timestamp', $info)) { Logger::warning( 'Retrieved invalid data from a memcache server. Missing timestamp.' ); continue; } if (!array_key_exists('data', $info)) { Logger::warning( 'Retrieved invalid data from a memcache server. Missing data.' ); continue; } if ($latestInfo === null) { // first info found $latestInfo = $serializedInfo; $latestTime = $info['timestamp']; $latestData = $info['data']; continue; } if ($info['timestamp'] === $latestTime && $serializedInfo === $latestInfo) { // this data matches the data from the other server(s) continue; } // different data from different servers. We need to update at least one of them to maintain sync $mustUpdate = true; // update if data in $info is newer than $latestData if ($latestTime < $info['timestamp']) { $latestInfo = $serializedInfo; $latestTime = $info['timestamp']; $latestData = $info['data']; } } if ($latestData === null) { if ($allDown) { // all servers are down, panic! $e = new Error\Error('MEMCACHEDOWN', null, 503); throw new Error\Exception('All memcache servers are down', 503, $e); } // we didn't find any data matching the key Logger::debug("key $key not found in memcache"); return null; } if ($mustUpdate) { // we found data matching the key, but some of the servers need updating Logger::debug("Memcache servers out of sync for $key, forcing sync"); self::set($key, $latestData); } return $latestData; } /** * Save a key-value pair to the memcache servers. * * @param string $key The key of the data. * @param mixed $value The value of the data. * @param integer|null $expire The expiration timestamp of the data. * @return void */ public static function set($key, $value, $expire = null) { Logger::debug("saving key $key to memcache"); $savedInfo = [ 'timestamp' => microtime(true), 'data' => $value ]; if ($expire === null) { $expire = self::getExpireTime(); } $savedInfoSerialized = serialize($savedInfo); // store this object to all groups of memcache servers foreach (self::getMemcacheServers() as $server) { if (self::$extension === \Memcached::class) { $server->set($key, $savedInfoSerialized, $expire); } else { $server->set($key, $savedInfoSerialized, 0, $expire); } } } /** * Delete a key-value pair from the memcache servers. * * @param string $key The key we should delete. * @return void */ public static function delete($key) { assert(is_string($key)); Logger::debug("deleting key $key from memcache"); // store this object to all groups of memcache servers foreach (self::getMemcacheServers() as $server) { $server->delete($key); } } /** * This function adds a server from the 'memcache_store.servers' * configuration option to a Memcache object. * * The server parameter is an array with the following keys: * - hostname * Hostname or ip address to the memcache server. * - port (optional) * port number the memcache server is running on. This * defaults to memcache.default_port if no value is given. * The default value of memcache.default_port is 11211. * - weight (optional) * The weight of this server in the load balancing * cluster. * - timeout (optional) * The timeout for contacting this server, in seconds. * The default value is 3 seconds. * * @param \Memcache|\Memcached $memcache The Memcache object we should add this server to. * @param array $server An associative array with the configuration options for the server to add. * @return void * * @throws \Exception If any configuration option for the server is invalid. */ private static function addMemcacheServer($memcache, array $server): void { // the hostname option is required if (!array_key_exists('hostname', $server)) { throw new \Exception( "hostname setting missing from server in the 'memcache_store.servers' configuration option." ); } $hostname = $server['hostname']; // the hostname must be a valid string if (!is_string($hostname)) { throw new \Exception( "Invalid hostname for server in the 'memcache_store.servers' configuration option. The hostname is" . ' supposed to be a string.' ); } // check if the user has specified a port number if (strpos($hostname, 'unix:///') === 0) { // force port to be 0 for sockets $port = 0; } elseif (array_key_exists('port', $server)) { // get the port number from the array, and validate it $port = (int) $server['port']; if (($port <= 0) || ($port > 65535)) { throw new \Exception( "Invalid port for server in the 'memcache_store.servers' configuration option. The port number" . ' is supposed to be an integer between 0 and 65535.' ); } } else { // use the default port number from the ini-file $port = (int) ini_get('memcache.default_port'); if ($port <= 0 || $port > 65535) { // invalid port number from the ini-file. fall back to the default $port = 11211; } } // check if the user has specified a weight for this server if (array_key_exists('weight', $server)) { // get the weight and validate it $weight = (int) $server['weight']; if ($weight <= 0) { throw new \Exception( "Invalid weight for server in the 'memcache_store.servers' configuration option. The weight is" . ' supposed to be a positive integer.' ); } } else { // use a default weight of 1 $weight = 1; } // check if the user has specified a timeout for this server if (array_key_exists('timeout', $server)) { // get the timeout and validate it $timeout = (int) $server['timeout']; if ($timeout <= 0) { throw new \Exception( "Invalid timeout for server in the 'memcache_store.servers' configuration option. The timeout is" . ' supposed to be a positive integer.' ); } } else { // use a default timeout of 3 seconds $timeout = 3; } // add this server to the Memcache object if ($memcache instanceof \Memcached) { $memcache->addServer($hostname, $port); } else { $memcache->addServer($hostname, $port, true, $weight, $timeout, $timeout, true); } } /** * This function takes in a list of servers belonging to a group and * creates a Memcache object from the servers in the group. * * @param array $group Array of servers which should be created as a group. * @param string $index The index for this group. Specify if persistent connections are desired. * * @return \Memcache|\Memcached A Memcache object of the servers in the group * * @throws \Exception If the servers configuration is invalid. */ private static function loadMemcacheServerGroup(array $group, string $index = null) { if (class_exists(\Memcached::class)) { if (is_string($index)) { $memcache = new \Memcached($index); } else { $memcache = new \Memcached(); } if (array_key_exists('options', $group)) { $memcache->setOptions($group['options']); unset($group['options']); } self::$extension = \Memcached::class; $servers = $memcache->getServerList(); if (count($servers) === count($group) && !$memcache->isPristine()) { return $memcache; } $memcache->resetServerList(); } elseif (class_exists(\Memcache::class)) { $memcache = new \Memcache(); self::$extension = \Memcache::class; } else { throw new \Exception( 'Missing Memcached implementation. You must install either the Memcache or Memcached extension.' ); } if (self::$extension === \Memcache::class) { Logger::warning( "The use of PHP-extension memcache is deprecated. Please migrate to the memcached extension." ); } // iterate over all the servers in the group and add them to the Memcache object foreach ($group as $index => $server) { // make sure that we don't have an index. An index would be a sign of invalid configuration if (!is_int($index)) { throw new \Exception( "Invalid index on element in the 'memcache_store.servers' configuration option. Perhaps you" . ' have forgotten to add an array(...) around one of the server groups? The invalid index was: ' . $index ); } // make sure that the server object is an array. Each server is an array with name-value pairs if (!is_array($server)) { throw new \Exception( 'Invalid value for the server with index ' . $index . '. Remeber that the \'memcache_store.servers\' configuration option' . ' contains an array of arrays of arrays.' ); } self::addMemcacheServer($memcache, $server); } /** @var \Memcache|\Memcached */ return $memcache; } /** * This function gets a list of all configured memcache servers. This list is initialized based * on the content of 'memcache_store.servers' in the configuration. * * @return \Memcache[]|\Memcached[] Array with Memcache objects. * * @throws \Exception If the servers configuration is invalid. */ private static function getMemcacheServers(): array { // check if we have loaded the servers already if (self::$serverGroups != null) { return self::$serverGroups; } // initialize the servers-array self::$serverGroups = []; // load the configuration $config = Configuration::getInstance(); $groups = $config->getArray('memcache_store.servers'); // iterate over all the groups in the 'memcache_store.servers' configuration option foreach ($groups as $index => $group) { /* * Make sure that the group is an array. Each group is an array of servers. Each server is * an array of name => value pairs for that server. */ if (!is_array($group)) { throw new \Exception( "Invalid value for the server with index " . $index . ". Remeber that the 'memcache_store.servers' configuration option" . ' contains an array of arrays of arrays.' ); } // make sure that the group doesn't have an index. An index would be a sign of invalid configuration if (is_int($index)) { $index = null; } // parse and add this group to the server group list self::$serverGroups[] = self::loadMemcacheServerGroup($group, $index); } return self::$serverGroups; } /** * This is a helper-function which returns the expire value of data * we should store to the memcache servers. * * The value is set depending on the configuration. If no value is * set in the configuration, then we will use a default value of 0. * 0 means that the item will never expire. * * @return integer The value which should be passed in the set(...) calls to the memcache objects. * * @throws \Exception If the option 'memcache_store.expires' has a negative value. */ private static function getExpireTime(): int { // get the configuration instance $config = Configuration::getInstance(); assert($config instanceof Configuration); // get the expire-value from the configuration $expire = $config->getInteger('memcache_store.expires', 0); // it must be a positive integer if ($expire < 0) { throw new \Exception( "The value of 'memcache_store.expires' in the configuration can't be a negative integer." ); } /* If the configuration option is 0, then we should return 0. This allows the user to specify that the data * shouldn't expire. */ if ($expire == 0) { return 0; } /* The expire option is given as the number of seconds into the future an item should expire. We convert this * to an actual timestamp. */ return (time() + $expire); } /** * This function retrieves statistics about all memcache server groups. * * @return array Array with the names of each stat and an array with the value for each server group. * * @throws \Exception If memcache server status couldn't be retrieved. */ public static function getStats() { $ret = []; foreach (self::getMemcacheServers() as $sg) { $stats = method_exists($sg, 'getExtendedStats') ? $sg->getExtendedStats() : $sg->getStats(); foreach ($stats as $server => $data) { if ($data === false) { throw new \Exception('Failed to get memcache server status.'); } } $stats = Utils\Arrays::transpose($stats); $ret = array_merge_recursive($ret, $stats); } return $ret; } /** * Retrieve statistics directly in the form returned by getExtendedStats, for * all server groups. * * @return array An array with the extended stats output for each server group. */ public static function getRawStats() { $ret = []; foreach (self::getMemcacheServers() as $sg) { $stats = method_exists($sg, 'getExtendedStats') ? $sg->getExtendedStats() : $sg->getStats(); $ret[] = $stats; } return $ret; } } simplesamlphp-1.19.1/lib/SimpleSAML/Kernel.php0000644000000000000000000001130314042503475017566 0ustar rootrootmodule = $module; $env = getenv('APP_ENV') ?: (getenv('SYMFONY_ENV') ?: 'prod'); parent::__construct($env, false); } /** * @return string */ public function getCacheDir() { $configuration = Configuration::getInstance(); $cachePath = $configuration->getString('tempdir') . '/cache/' . $this->module; if (System::isAbsolutePath($cachePath)) { return $cachePath; } return $configuration->getBaseDir() . '/' . $cachePath; } /** * @return string */ public function getLogDir() { $configuration = Configuration::getInstance(); $loggingPath = $configuration->getString('loggingdir'); if (System::isAbsolutePath($loggingPath)) { return $loggingPath; } return $configuration->getBaseDir() . '/' . $loggingPath; } /** * {@inheritdoc} */ public function registerBundles() { return [ new FrameworkBundle(), ]; } /** * Get the module loaded in this kernel. * * @return string */ public function getModule() { return $this->module; } /** * Configures the container. * * @param ContainerBuilder $container * @param LoaderInterface $loader * @return void */ protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) { $configuration = Configuration::getInstance(); $baseDir = $configuration->getBaseDir(); $loader->load($baseDir . '/routing/services/*' . self::CONFIG_EXTS, 'glob'); $confDir = Module::getModuleDir($this->module) . '/routing/services'; if (is_dir($confDir)) { $loader->load($confDir . '/**/*' . self::CONFIG_EXTS, 'glob'); } $c->loadFromExtension('framework', [ 'secret' => Configuration::getInstance()->getString('secretsalt'), ]); $this->registerModuleControllers($c); } /** * Import routes. * * @param RouteCollectionBuilder $routes * @return void */ protected function configureRoutes(RouteCollectionBuilder $routes) { $configuration = Configuration::getInstance(); $baseDir = $configuration->getBaseDir(); $routes->import($baseDir . '/routing/routes/*' . self::CONFIG_EXTS, '/', 'glob'); $confDir = Module::getModuleDir($this->module) . '/routing/routes'; if (is_dir($confDir)) { $routes->import($confDir . '/**/*' . self::CONFIG_EXTS, $this->module, 'glob'); } else { // Remain backwards compatible by checking for routers in the old location (1.18 style) $confDir = Module::getModuleDir($this->module); $routes->import($confDir . '/routes' . self::CONFIG_EXTS, $this->module, 'glob'); } } /** * @param ContainerBuilder $container * @return void */ private function registerModuleControllers(ContainerBuilder $container): void { try { $definition = new Definition(); $definition->setAutowired(true); $definition->setPublic(true); $controllerDir = Module::getModuleDir($this->module) . '/lib/Controller'; if (!is_dir($controllerDir)) { return; } $loader = new DirectoryLoader( $container, new FileLocator($controllerDir . '/') ); $loader->registerClasses( $definition, 'SimpleSAML\\Module\\' . $this->module . '\\Controller\\', $controllerDir . '/*' ); } catch (FileLocatorFileNotFoundException $e) { } } } simplesamlphp-1.19.1/lib/SimpleSAML/Locale/0000755000000000000000000000000014042503475017036 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Locale/Localization.php0000644000000000000000000002062514042503475022204 0ustar rootroot * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML\Locale; use Gettext\Translations; use Gettext\Translator; use SimpleSAML\Configuration; use SimpleSAML\Logger; class Localization { /** * The configuration to use. * * @var \SimpleSAML\Configuration */ private $configuration; /** * The default gettext domain. * * @var string */ public const DEFAULT_DOMAIN = 'messages'; /** * Old internationalization backend included in SimpleSAMLphp. * * @var string */ public const SSP_I18N_BACKEND = 'SimpleSAMLphp'; /** * An internationalization backend implemented purely in PHP. * * @var string */ public const GETTEXT_I18N_BACKEND = 'gettext/gettext'; /** * The default locale directory * * @var string */ private $localeDir; /** * Where specific domains are stored * * @var array */ private $localeDomainMap = []; /** * Pointer to currently active translator * * @var \Gettext\Translator */ private $translator; /** * Pointer to current Language * * @var Language */ private $language; /** * Language code representing the current Language * * @var string */ private $langcode; /** * The language backend to use * * @var string */ public $i18nBackend; /** * Constructor * * @param \SimpleSAML\Configuration $configuration Configuration object */ public function __construct(Configuration $configuration) { $this->configuration = $configuration; /** @var string $locales */ $locales = $this->configuration->resolvePath('locales'); $this->localeDir = $locales; $this->language = new Language($configuration); $this->langcode = $this->language->getPosixLanguage($this->language->getLanguage()); $this->i18nBackend = ( $this->configuration->getBoolean('usenewui', false) ? self::GETTEXT_I18N_BACKEND : self::SSP_I18N_BACKEND ); $this->setupL10N(); } /** * Dump the default locale directory * * @return string */ public function getLocaleDir() { return $this->localeDir; } /** * Get the default locale dir for a specific module aka. domain * * @param string $domain Name of module/domain * * @return string */ public function getDomainLocaleDir($domain) { /** @var string $base */ $base = $this->configuration->resolvePath('modules'); $localeDir = $base . '/' . $domain . '/locales'; return $localeDir; } /** * Add a new translation domain from a module * (We're assuming that each domain only exists in one place) * * @param string $module Module name * @param string $localeDir Absolute path if the module is housed elsewhere * @return void */ public function addModuleDomain($module, $localeDir = null) { if (!$localeDir) { $localeDir = $this->getDomainLocaleDir($module); } $this->addDomain($localeDir, $module); } /** * Add a new translation domain * (We're assuming that each domain only exists in one place) * * @param string $localeDir Location of translations * @param string $domain Domain at location * @return void */ public function addDomain($localeDir, $domain) { $this->localeDomainMap[$domain] = $localeDir; Logger::debug("Localization: load domain '$domain' at '$localeDir'"); $this->loadGettextGettextFromPO($domain); } /** * Get and check path of localization file * * @param string $domain Name of localization domain * @throws \Exception If the path does not exist even for the default, fallback language * * @return string */ public function getLangPath($domain = self::DEFAULT_DOMAIN) { $langcode = explode('_', $this->langcode); $langcode = $langcode[0]; $localeDir = $this->localeDomainMap[$domain]; $langPath = $localeDir . '/' . $langcode . '/LC_MESSAGES/'; Logger::debug("Trying langpath for '$langcode' as '$langPath'"); if (is_dir($langPath) && is_readable($langPath)) { return $langPath; } // Some langcodes have aliases.. $alias = $this->language->getLanguageCodeAlias($langcode); if (isset($alias)) { $langPath = $localeDir . '/' . $alias . '/LC_MESSAGES/'; Logger::debug("Trying langpath for alternative '$alias' as '$langPath'"); if (is_dir($langPath) && is_readable($langPath)) { return $langPath; } } // Language not found, fall back to default $defLangcode = $this->language->getDefaultLanguage(); $langPath = $localeDir . '/' . $defLangcode . '/LC_MESSAGES/'; if (is_dir($langPath) && is_readable($langPath)) { // Report that the localization for the preferred language is missing $error = "Localization not found for langcode '$langcode' at '$langPath', falling back to langcode '" . $defLangcode . "'"; Logger::error($_SERVER['PHP_SELF'] . ' - ' . $error); return $langPath; } // Locale for default language missing even, error out $error = "Localization directory missing/broken for langcode '$langcode' and domain '$domain'"; Logger::critical($_SERVER['PHP_SELF'] . ' - ' . $error); throw new \Exception($error); } /** * Setup the translator * @return void */ private function setupTranslator(): void { $this->translator = new Translator(); $this->translator->register(); } /** * Load translation domain from Gettext/Gettext using .po * * Note: Since Twig I18N does not support domains, all loaded files are * merged. Use contexts if identical strings need to be disambiguated. * * @param string $domain Name of domain * @param boolean $catchException Whether to catch an exception on error or return early * @return void * * @throws \Exception If something is wrong with the locale file for the domain and activated language */ private function loadGettextGettextFromPO(string $domain = self::DEFAULT_DOMAIN, bool $catchException = true): void { try { $langPath = $this->getLangPath($domain); } catch (\Exception $e) { $error = "Something went wrong when trying to get path to language file, cannot load domain '$domain'."; Logger::debug($_SERVER['PHP_SELF'] . ' - ' . $error); if ($catchException) { // bail out! return; } else { throw $e; } } $poFile = $domain . '.po'; $poPath = $langPath . $poFile; if (file_exists($poPath) && is_readable($poPath)) { $translations = Translations::fromPoFile($poPath); $this->translator->loadTranslations($translations); } else { $error = "Localization file '$poFile' not found in '$langPath', falling back to default"; Logger::debug($_SERVER['PHP_SELF'] . ' - ' . $error); } } /** * Test to check if backend is set to default * * (if false: backend unset/there's an error) * * @return bool */ public function isI18NBackendDefault() { if ($this->i18nBackend === $this::SSP_I18N_BACKEND) { return true; } return false; } /** * Set up L18N if configured or fallback to old system * @return void */ private function setupL10N(): void { if ($this->i18nBackend === self::SSP_I18N_BACKEND) { Logger::debug("Localization: using old system"); return; } $this->setupTranslator(); // setup default domain $this->addDomain($this->localeDir, self::DEFAULT_DOMAIN); } /** * Show which domains are registered * * @return array */ public function getRegisteredDomains() { return $this->localeDomainMap; } } simplesamlphp-1.19.1/lib/SimpleSAML/Locale/Translate.php0000644000000000000000000004554614042503475021522 0ustar rootroot * @author Hanne Moa, UNINETT AS. * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML\Locale; use Gettext\BaseTranslator; use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Module; class Translate { /** * The configuration to be used for this translator. * * @var \SimpleSAML\Configuration */ private $configuration; /** * Associative array of languages. * * @var array */ private $langtext = []; /** * Associative array of dictionaries. * * @var array */ private $dictionaries = []; /** * The default dictionary. * * @var string|null */ private $defaultDictionary = null; /** * The language object we'll use internally. * * @var \SimpleSAML\Locale\Language */ private $language; /** * Constructor * * @param \SimpleSAML\Configuration $configuration Configuration object * @param string|null $defaultDictionary The default dictionary where tags will come from. */ public function __construct(Configuration $configuration, $defaultDictionary = null) { $this->configuration = $configuration; $this->language = new Language($configuration); if ($defaultDictionary !== null && substr($defaultDictionary, -4) === '.php') { // TODO: drop this entire if clause for 2.0 // for backwards compatibility - print warning $backtrace = debug_backtrace(); $where = $backtrace[0]['file'] . ':' . $backtrace[0]['line']; Logger::warning( 'Deprecated use of new SimpleSAML\Locale\Translate(...) at ' . $where . '. The last parameter is now a dictionary name, which should not end in ".php".' ); $this->defaultDictionary = substr($defaultDictionary, 0, -4); } else { $this->defaultDictionary = $defaultDictionary; } } /** * Return the internal language object used by this translator. * * @return \SimpleSAML\Locale\Language */ public function getLanguage() { return $this->language; } /** * This method retrieves a dictionary with the name given. * * @param string $name The name of the dictionary, as the filename in the dictionary directory, without the * '.php' ending. * * @return array An associative array with the dictionary. */ private function getDictionary(string $name): array { if (!array_key_exists($name, $this->dictionaries)) { $sepPos = strpos($name, ':'); if ($sepPos !== false) { $module = substr($name, 0, $sepPos); $fileName = substr($name, $sepPos + 1); $dictDir = Module::getModuleDir($module) . '/dictionaries/'; } else { $dictDir = $this->configuration->getPathValue('dictionarydir', 'dictionaries/') ?: 'dictionaries/'; $fileName = $name; } $this->dictionaries[$name] = $this->readDictionaryFile($dictDir . $fileName); } return $this->dictionaries[$name]; } /** * This method retrieves a tag as an array with language => string mappings. * * @param string $tag The tag name. The tag name can also be on the form '{:}', to retrieve a tag * from the specific dictionary. * * @return array|null An associative array with language => string mappings, or null if the tag wasn't found. */ public function getTag($tag) { assert(is_string($tag)); // first check translations loaded by the includeInlineTranslation and includeLanguageFile methods if (array_key_exists($tag, $this->langtext)) { return $this->langtext[$tag]; } // check whether we should use the default dictionary or a dictionary specified in the tag if (substr($tag, 0, 1) === '{' && preg_match('/^{((?:\w+:)?\w+?):(.*)}$/D', $tag, $matches)) { $dictionary = $matches[1]; $tag = $matches[2]; } else { $dictionary = $this->defaultDictionary; if ($dictionary === null) { // we don't have any dictionary to load the tag from return null; } } $dictionary = $this->getDictionary($dictionary); if (!array_key_exists($tag, $dictionary)) { return null; } return $dictionary[$tag]; } /** * Retrieve the preferred translation of a given text. * * @param array $translations The translations, as an associative array with language => text mappings. * * @return string The preferred translation. * * @throws \Exception If there's no suitable translation. */ public function getPreferredTranslation($translations) { assert(is_array($translations)); // look up translation of tag in the selected language $selected_language = $this->language->getLanguage(); if (array_key_exists($selected_language, $translations)) { return $translations[$selected_language]; } // look up translation of tag in the default language $default_language = $this->language->getDefaultLanguage(); if (array_key_exists($default_language, $translations)) { return $translations[$default_language]; } // check for english translation if (array_key_exists('en', $translations)) { return $translations['en']; } // pick the first translation available if (count($translations) > 0) { $languages = array_keys($translations); return $translations[$languages[0]]; } // we don't have anything to return throw new \Exception('Nothing to return from translation.'); } /** * 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; } /** * Mark a string for translation without translating it. * * @param string $tag A tag name to mark for translation. * * @return string The tag, unchanged. */ public static function noop($tag) { return $tag; } /** * Translate a tag into the current language, with a fallback to english. * * This function is used to look up a translation tag in dictionaries, and return the translation into the current * language. If no translation into the current language can be found, english will be tried, and if that fails, * placeholder text will be returned. * * An array can be passed as the tag. In that case, the array will be assumed to be on the form (language => text), * and will be used as the source of translations. * * This function can also do replacements into the translated tag. It will search the translated tag for the keys * provided in $replacements, and replace any found occurrences with the value of the key. * * @param string|array $tag A tag name for the translation which should be looked up, or an array with * (language => text) mappings. The array version will go away in 2.0 * @param array $replacements An associative array of keys that should be replaced with values in the * translated string. * @param boolean $fallbackdefault Default translation to use as a fallback if no valid translation was found. * @param array $oldreplacements * @param bool $striptags * @deprecated Not used in twig, gettext * * @return string The translated tag, or a placeholder value if the tag wasn't found. */ public function t( $tag, $replacements = [], // TODO: remove this for 2.0. Assume true $fallbackdefault = true, // TODO: remove this for 2.0 $oldreplacements = [], // TODO: remove this for 2.0 $striptags = false ) { $backtrace = debug_backtrace(); $where = $backtrace[0]['file'] . ':' . $backtrace[0]['line']; if (!$fallbackdefault) { Logger::warning( 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at ' . $where . '. This parameter will go away, the fallback will become' . ' identical to the $tag in 2.0.' ); } if (is_array($tag)) { $tagData = $tag; Logger::warning( 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at ' . $where . '. The $tag-parameter can only be a string in 2.0.' ); } else { $tagData = $this->getTag($tag); if ($tagData === null) { // tag not found Logger::info('Translate: Looking up [' . $tag . ']: not translated at all.'); return $this->getStringNotTranslated($tag, $fallbackdefault); } } $translated = $this->getPreferredTranslation($tagData); foreach ($replacements as $k => $v) { // try to translate if no replacement is given if ($v == null) { $v = $this->t($k); } $translated = str_replace($k, $v, $translated); } return $translated; } /** * Return the string that should be used when no translation was found. * * @param string $tag A name tag of the string that should be returned. * @param boolean $fallbacktag If set to true and string was not found in any languages, return the tag itself. If * false return null. * * @return string The string that should be used, or the tag name if $fallbacktag is set to false. */ private function getStringNotTranslated(string $tag, bool $fallbacktag): string { if ($fallbacktag) { return 'not translated (' . $tag . ')'; } else { return $tag; } } /** * Include a translation inline instead of putting translations in dictionaries. This function is recommended to be * used ONLY for variable data, or when the translation is already provided by an external source, as a database * or in metadata. * * @param string $tag The tag that has a translation * @param array|string $translation The translation array * * @throws \Exception If $translation is neither a string nor an array. * @return void */ public function includeInlineTranslation($tag, $translation) { if (is_string($translation)) { $translation = ['en' => $translation]; } elseif (!is_array($translation)) { throw new \Exception( "Inline translation should be string or array. Is " . gettype($translation) . " now!" ); } Logger::debug('Translate: Adding inline language translation for tag [' . $tag . ']'); $this->langtext[$tag] = $translation; } /** * Include a language file from the dictionaries directory. * * @param string $file File name of dictionary to include * @param \SimpleSAML\Configuration|null $otherConfig Optionally provide a different configuration object than the * one provided in the constructor to be used to find the directory of the dictionary. This allows to combine * dictionaries inside the SimpleSAMLphp main code distribution together with external dictionaries. Defaults to * null. * @return void */ public function includeLanguageFile($file, $otherConfig = null) { if (!empty($otherConfig)) { $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/'); } else { $filebase = $this->configuration->getPathValue('dictionarydir', 'dictionaries/'); } $filebase = $filebase ?: 'dictionaries/'; $lang = $this->readDictionaryFile($filebase . $file); Logger::debug('Translate: Merging language array. Loading [' . $file . ']'); $this->langtext = array_merge($this->langtext, $lang); } /** * Read a dictionary file in JSON format. * * @param string $filename The absolute path to the dictionary file, minus the .definition.json ending. * * @return array An array holding all the translations in the file. */ private function readDictionaryJSON(string $filename): array { $definitionFile = $filename . '.definition.json'; assert(file_exists($definitionFile)); $fileContent = file_get_contents($definitionFile); $lang = json_decode($fileContent, true); if (empty($lang)) { Logger::error('Invalid dictionary definition file [' . $definitionFile . ']'); return []; } $translationFile = $filename . '.translation.json'; if (file_exists($translationFile)) { $fileContent = file_get_contents($translationFile); $moreTrans = json_decode($fileContent, true); if (!empty($moreTrans)) { $lang = array_merge_recursive($lang, $moreTrans); } } return $lang; } /** * Read a dictionary file in PHP format. * * @param string $filename The absolute path to the dictionary file. * * @return array An array holding all the translations in the file. */ private function readDictionaryPHP(string $filename): array { $phpFile = $filename . '.php'; assert(file_exists($phpFile)); $lang = null; include($phpFile); if (isset($lang)) { return $lang; } return []; } /** * Read a dictionary file. * * @param string $filename The absolute path to the dictionary file. * * @return array An array holding all the translations in the file. */ private function readDictionaryFile(string $filename): array { Logger::debug('Translate: Reading dictionary [' . $filename . ']'); $jsonFile = $filename . '.definition.json'; if (file_exists($jsonFile)) { return $this->readDictionaryJSON($filename); } $phpFile = $filename . '.php'; if (file_exists($phpFile)) { return $this->readDictionaryPHP($filename); } Logger::error( $_SERVER['PHP_SELF'] . ' - Translate: Could not find dictionary file at [' . $filename . ']' ); return []; } /** * Translate a singular text. * * @param string $original The string before translation. * * @return string The translated string. */ public static function translateSingularGettext($original) { $text = BaseTranslator::$current->gettext($original); if (func_num_args() === 1 || $original === null) { return $text; } $args = array_slice(func_get_args(), 1); return strtr($text, is_array($args[0]) ? $args[0] : $args); } /** * Translate a plural text. * * @param string $original The string before translation. * @param string $plural * @param string $value * * @return string The translated string. */ public static function translatePluralGettext($original, $plural, $value) { $text = BaseTranslator::$current->ngettext($original, $plural, $value); if (func_num_args() === 3) { return $text; } $args = array_slice(func_get_args(), 3); return strtr($text, is_array($args[0]) ? $args[0] : $args); } /** * Pick a translation from a given array of translations for the current language. * * @param array|null $context An array of options. The current language must be specified * as an ISO 639 code accessible with the key "currentLanguage" in the array. * @param array|null $translations An array of translations. Each translation has an * ISO 639 code as its key, identifying the language it corresponds to. * * @return null|string The translation appropriate for the current language, or null if none found. If the * $context or $translations arrays are null, or $context['currentLanguage'] is not defined, null is also returned. */ public static function translateFromArray($context, $translations) { if (!is_array($translations)) { return null; } if (!is_array($context) || !isset($context['currentLanguage'])) { return null; } if (isset($translations[$context['currentLanguage']])) { return $translations[$context['currentLanguage']]; } // we don't have a translation for the current language, load alternative priorities $sspcfg = Configuration::getInstance(); /** @psalm-var \SimpleSAML\Configuration $langcfg */ $langcfg = $sspcfg->getConfigItem('language'); $priorities = $langcfg->getArray('priorities', []); if (!empty($priorities[$context['currentLanguage']])) { foreach ($priorities[$context['currentLanguage']] as $lang) { if (isset($translations[$lang])) { return $translations[$lang]; } } } // nothing we can use, return null so that we can set a default return null; } /** * Prefix tag * * @param string $tag Translation tag * @param string $prefix Prefix to be added * * @return string Prefixed tag */ public static function addTagPrefix(string $tag, string $prefix): string { $tagPos = strrpos($tag, ':'); // if tag contains ':' target actual tag $tagPos = ($tagPos === false) ? 0 : $tagPos + 1; // add prefix at $tagPos return substr_replace($tag, $prefix, $tagPos, 0); } } simplesamlphp-1.19.1/lib/SimpleSAML/Locale/Language.php0000644000000000000000000003401114042503475021271 0ustar rootroot * @author Hanne Moa, UNINETT AS. * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML\Locale; use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Utils; class Language { /** * This is the default language map. It is used to map languages codes from the user agent to other language codes. */ private static $defaultLanguageMap = ['nb' => 'no']; /** * The configuration to use. * * @var \SimpleSAML\Configuration */ private $configuration; /** * An array holding a list of languages available. * * @var array */ private $availableLanguages; /** * The language currently in use. * * @var null|string */ private $language = null; /** * The language to use by default. * * @var string */ private $defaultLanguage; /** * An array holding a list of languages that are written from right to left. * * @var array */ private $rtlLanguages; /** * HTTP GET language parameter name. * * @var string */ private $languageParameterName; /** * A custom function to use in order to determine the language in use. * * @var callable|null */ private $customFunction; /** * A list of languages supported with their names localized. * Indexed by something that mostly resembles ISO 639-1 code, * with some charming SimpleSAML-specific variants... * that must remain before 2.0 due to backwards compatibility * * @var array */ public static $language_names = [ 'no' => 'Bokmål', // Norwegian Bokmål 'nn' => 'Nynorsk', // Norwegian Nynorsk 'se' => 'Sámegiella', // Northern Sami 'sma' => 'Åarjelh-saemien giele', // Southern Sami 'da' => 'Dansk', // Danish 'en' => 'English', 'de' => 'Deutsch', // German 'sv' => 'Svenska', // Swedish 'fi' => 'Suomeksi', // Finnish 'es' => 'Español', // Spanish 'ca' => 'Català', // Catalan 'fr' => 'Français', // French 'it' => 'Italiano', // Italian 'nl' => 'Nederlands', // Dutch 'lb' => 'Lëtzebuergesch', // Luxembourgish 'cs' => 'Čeština', // Czech 'sl' => 'Slovenščina', // Slovensk 'lt' => 'Lietuvių kalba', // Lithuanian 'hr' => 'Hrvatski', // Croatian 'hu' => 'Magyar', // Hungarian 'pl' => 'Język polski', // Polish 'pt' => 'Português', // Portuguese 'pt-br' => 'Português brasileiro', // Portuguese 'ru' => 'русский язык', // Russian 'et' => 'eesti keel', // Estonian 'tr' => 'Türkçe', // Turkish 'el' => 'ελληνικά', // Greek 'ja' => '日本語', // Japanese 'zh' => '简体中文', // Chinese (simplified) 'zh-tw' => '繁體中文', // Chinese (traditional) 'ar' => 'العربية', // Arabic 'fa' => 'پارسی', // Persian 'ur' => 'اردو', // Urdu 'he' => 'עִבְרִית', // Hebrew 'id' => 'Bahasa Indonesia', // Indonesian 'sr' => 'Srpski', // Serbian 'lv' => 'Latviešu', // Latvian 'ro' => 'Românește', // Romanian 'eu' => 'Euskara', // Basque 'af' => 'Afrikaans', // Afrikaans 'zu' => 'IsiZulu', // Zulu 'xh' => 'isiXhosa', // Xhosa 'st' => 'Sesotho', // Sesotho ]; /** * A mapping of SSP languages to locales * * @var array */ private $languagePosixMapping = [ 'no' => 'nb_NO', 'nn' => 'nn_NO', ]; /** * Constructor * * @param \SimpleSAML\Configuration $configuration Configuration object */ public function __construct(Configuration $configuration) { $this->configuration = $configuration; $this->availableLanguages = $this->getInstalledLanguages(); $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', []); if (isset($_GET[$this->languageParameterName])) { $this->setLanguage( $_GET[$this->languageParameterName], $this->configuration->getBoolean('language.parameter.setcookie', true) ); } } /** * Filter configured (available) languages against installed languages. * * @return array The set of languages both in 'language.available' and self::$language_names. */ private function getInstalledLanguages(): array { $configuredAvailableLanguages = $this->configuration->getArray('language.available', ['en']); $availableLanguages = []; foreach ($configuredAvailableLanguages as $code) { if (array_key_exists($code, self::$language_names) && isset(self::$language_names[$code])) { $availableLanguages[] = $code; } else { Logger::error("Language \"$code\" not installed. Check config."); } } return $availableLanguages; } /** * Rename to non-idiosyncratic language code. * * @param string $language Language code for the language to rename, if necessary. * * @return string The language code. */ public function getPosixLanguage($language) { if (isset($this->languagePosixMapping[$language])) { return $this->languagePosixMapping[$language]; } return $language; } /** * This method will set a cookie for the user's browser to remember what language was selected. * * @param string $language Language code for the language to set. * @param boolean $setLanguageCookie Whether to set the language cookie or not. Defaults to true. * @return void */ public function setLanguage($language, $setLanguageCookie = true) { $language = strtolower($language); if (in_array($language, $this->availableLanguages, true)) { $this->language = $language; if ($setLanguageCookie === true) { self::setLanguageCookie($language); } } } /** * This method will return the language selected by the user, or the default language. It looks first for a cached * language code, then checks for a language cookie, then it tries to calculate the preferred language from HTTP * headers. * * @return string The language selected by the user according to the processing rules specified, or the default * language in any other case. */ public function getLanguage() { // language is set in object if (isset($this->language)) { return $this->language; } // run custom getLanguage function if defined if (isset($this->customFunction) && is_callable($this->customFunction)) { $customLanguage = call_user_func($this->customFunction, $this); if ($customLanguage !== null && $customLanguage !== false) { return $customLanguage; } } // language is provided in a stored cookie $languageCookie = self::getLanguageCookie(); if ($languageCookie !== null) { $this->language = $languageCookie; return $languageCookie; } // check if we can find a good language from the Accept-Language HTTP header $httpLanguage = $this->getHTTPLanguage(); if ($httpLanguage !== null) { return $httpLanguage; } // language is not set, and we get the default language from the configuration return $this->getDefaultLanguage(); } /** * Get the localized name of a language, by ISO 639-2 code. * * @param string $code The ISO 639-2 code of the language. * * @return string|null The localized name of the language. */ public function getLanguageLocalizedName($code) { if (array_key_exists($code, self::$language_names) && isset(self::$language_names[$code])) { return self::$language_names[$code]; } Logger::error("Name for language \"$code\" not found. Check config."); return null; } /** * Get the language parameter name. * * @return string The language parameter name. */ public function getLanguageParameterName() { return $this->languageParameterName; } /** * This method returns the preferred language for the user based on the Accept-Language HTTP header. * * @return string|null The preferred language based on the Accept-Language HTTP header, * or null if none of the languages in the header is available. */ private function getHTTPLanguage(): ?string { $languageScore = Utils\HTTP::getAcceptLanguage(); // for now we only use the default language map. We may use a configurable language map in the future $languageMap = self::$defaultLanguageMap; // find the available language with the best score $bestLanguage = null; $bestScore = -1.0; foreach ($languageScore as $language => $score) { // apply the language map to the language code if (array_key_exists($language, $languageMap)) { $language = $languageMap[$language]; } if (!in_array($language, $this->availableLanguages, true)) { // skip this language - we don't have it continue; } /* Some user agents use very limited precision of the quality value, but order the elements in descending * order. Therefore we rely on the order of the output from getAcceptLanguage() matching the order of the * languages in the header when two languages have the same quality. */ if ($score > $bestScore) { $bestLanguage = $language; $bestScore = $score; } } return $bestLanguage; } /** * Return the default language according to configuration. * * @return string The default language that has been configured. Defaults to english if not configured. */ public function getDefaultLanguage() { return $this->defaultLanguage; } /** * Return an alias for a language code, if any. * * @param string $langcode * @return string|null The alias, or null if the alias was not found. */ public function getLanguageCodeAlias($langcode) { if (isset(self::$defaultLanguageMap[$langcode])) { return self::$defaultLanguageMap[$langcode]; } // No alias found, which is fine return null; } /** * Return an indexed list of all languages available. * * @return array An array holding all the languages available as the keys of the array. The value for each key is * true in case that the language specified by that key is currently active, or false otherwise. */ public function getLanguageList() { $current = $this->getLanguage(); $list = array_fill_keys($this->availableLanguages, false); $list[$current] = true; return $list; } /** * Check whether a language is written from the right to the left or not. * * @return boolean True if the language is right-to-left, false otherwise. */ public function isLanguageRTL() { return in_array($this->getLanguage(), $this->rtlLanguages, true); } /** * Retrieve the user-selected language from a cookie. * * @return string|null The selected language or null if unset. */ public static function getLanguageCookie() { $config = Configuration::getInstance(); $availableLanguages = $config->getArray('language.available', ['en']); $name = $config->getString('language.cookie.name', 'language'); if (isset($_COOKIE[$name])) { $language = strtolower((string) $_COOKIE[$name]); if (in_array($language, $availableLanguages, true)) { return $language; } } return null; } /** * This method will attempt to set the user-selected language in a cookie. It will do nothing if the language * specified is not in the list of available languages, or the headers have already been sent to the browser. * * @param string $language The language set by the user. * @return void */ public static function setLanguageCookie($language) { assert(is_string($language)); $language = strtolower($language); $config = Configuration::getInstance(); $availableLanguages = $config->getArray('language.available', ['en']); if (!in_array($language, $availableLanguages, true) || headers_sent()) { return; } $name = $config->getString('language.cookie.name', 'language'); $params = [ 'lifetime' => ($config->getInteger('language.cookie.lifetime', 60 * 60 * 24 * 900)), 'domain' => strval($config->getString('language.cookie.domain', null)), 'path' => ($config->getString('language.cookie.path', '/')), 'secure' => ($config->getBoolean('language.cookie.secure', false)), 'httponly' => ($config->getBoolean('language.cookie.httponly', false)), 'samesite' => ($config->getString('language.cookie.samesite', null)), ]; Utils\HTTP::setCookie($name, $language, $params, false); } } simplesamlphp-1.19.1/lib/SimpleSAML/SessionHandlerCookie.php0000644000000000000000000001116114042503475022423 0ustar rootroot * @package SimpleSAMLphp * @abstract */ declare(strict_types=1); namespace SimpleSAML; use SimpleSAML\Utils; abstract class SessionHandlerCookie extends SessionHandler { /** * This variable contains the current session id. * * @var string|null */ private $session_id = null; /** * This variable contains the session cookie name. * * @var string */ protected $cookie_name; /** * This constructor initializes the session id based on what we receive in a cookie. We create a new session id and * set a cookie with this id if we don't have a session id. */ protected function __construct() { // call the constructor in the base class in case it should become necessary in the future parent::__construct(); $config = Configuration::getInstance(); $this->cookie_name = $config->getString('session.cookie.name', 'SimpleSAMLSessionID'); } /** * Create a new session id. * * @return string The new session id. */ public function newSessionId() { $this->session_id = self::createSessionID(); Session::createSession($this->session_id); return $this->session_id; } /** * Retrieve the session ID saved in the session cookie, if there's one. * * @return string|null The session id saved in the cookie or null if no session cookie was set. */ public function getCookieSessionId() { if ($this->session_id === null) { if ($this->hasSessionCookie()) { // attempt to retrieve the session id from the cookie $this->session_id = $_COOKIE[$this->cookie_name]; } // check if we have a valid session id if (!is_null($this->session_id) && !self::isValidSessionID($this->session_id)) { // invalid, disregard this session return null; } } return $this->session_id; } /** * Retrieve the session cookie name. * * @return string The session cookie name. */ public function getSessionCookieName() { return $this->cookie_name; } /** * This static function creates a session id. A session id consists of 32 random hexadecimal characters. * * @return string A random session id. */ private static function createSessionID(): string { return bin2hex(openssl_random_pseudo_bytes(16)); } /** * This static function validates a session id. A session id is valid if it only consists of characters which are * allowed in a session id and it is the correct length. * * @param string $session_id The session ID we should validate. * * @return boolean True if this session ID is valid, false otherwise. */ private static function isValidSessionID(string $session_id): bool { if (strlen($session_id) != 32) { return false; } if (preg_match('/[^0-9a-f]/', $session_id)) { return false; } return true; } /** * Check whether the session cookie is set. * * This function will only return false if is is certain that the cookie isn't set. * * @return boolean True if it was set, false otherwise. */ public function hasSessionCookie() { return array_key_exists($this->cookie_name, $_COOKIE); } /** * Set a session cookie. * * @param string $sessionName The name of the session. * @param string|null $sessionID The session ID to use. Set to null to delete the cookie. * @param array|null $cookieParams Additional parameters to use for the session cookie. * @return void * * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie. */ public function setCookie($sessionName, $sessionID, array $cookieParams = null) { assert(is_string($sessionName)); assert(is_string($sessionID) || $sessionID === null); if ($cookieParams !== null) { $params = array_merge($this->getCookieParams(), $cookieParams); } else { $params = $this->getCookieParams(); } Utils\HTTP::setCookie($sessionName, $sessionID, $params, true); } } simplesamlphp-1.19.1/lib/SimpleSAML/SessionHandlerPHP.php0000644000000000000000000003302114042503475021640 0ustar rootroot * @package SimpleSAMLphp */ declare(strict_types=1); namespace SimpleSAML; use SimpleSAML\Error; use SimpleSAML\Utils; class SessionHandlerPHP extends SessionHandler { /** * This variable contains the session cookie name. * * @var string */ protected $cookie_name; /** * An associative array containing the details of a session existing previously to creating or loading one with this * session handler. The keys of the array will be: * * - id: the ID of the session, as returned by session_id(). * - name: the name of the session, as returned by session_name(). * - cookie_params: the parameters of the session cookie, as returned by session_get_cookie_params(). * * @var array */ private $previous_session = []; /** * Initialize the PHP session handling. This constructor is protected because it should only be called from * \SimpleSAML\SessionHandler::createSessionHandler(...). */ protected function __construct() { // call the parent constructor in case it should become necessary in the future parent::__construct(); $config = Configuration::getInstance(); $this->cookie_name = $config->getString('session.phpsession.cookiename', null); if (session_status() === PHP_SESSION_ACTIVE) { if (session_name() === $this->cookie_name || $this->cookie_name === null) { Logger::warning( 'There is already a PHP session with the same name as SimpleSAMLphp\'s session, or the ' . "'session.phpsession.cookiename' configuration option is not set. Make sure to set " . "SimpleSAMLphp's cookie name with a value not used by any other applications." ); } /* * We shouldn't have a session at this point, so it might be an application session. Save the details to * retrieve it later and commit. */ $this->previous_session['cookie_params'] = session_get_cookie_params(); $this->previous_session['id'] = session_id(); $this->previous_session['name'] = session_name(); session_write_close(); } if (empty($this->cookie_name)) { $this->cookie_name = session_name(); } elseif (!headers_sent() || version_compare(PHP_VERSION, '7.2', '<')) { session_name($this->cookie_name); } $params = $this->getCookieParams(); if (!headers_sent()) { if (version_compare(PHP_VERSION, '7.3.0', '>=')) { /** @psalm-suppress InvalidArgument */ session_set_cookie_params([ 'lifetime' => $params['lifetime'], 'path' => $params['path'], 'domain' => $params['domain'], 'secure' => $params['secure'], 'httponly' => $params['httponly'], 'samesite' => $params['samesite'], ]); } else { session_set_cookie_params( $params['lifetime'], $params['path'], $params['domain'] ?? '', $params['secure'], $params['httponly'] ); } } $savepath = $config->getString('session.phpsession.savepath', null); if (!empty($savepath)) { session_save_path($savepath); } } /** * Restore a previously-existing session. * * Use this method to restore a previous PHP session existing before SimpleSAMLphp initialized its own session. * * WARNING: do not use this method directly, unless you know what you are doing. Calling this method directly, * outside of \SimpleSAML\Session, could cause SimpleSAMLphp's session to be lost or mess the application's one. The * session must always be saved properly before calling this method. If you don't understand what this is about, * don't use this method. * * @return void */ public function restorePrevious() { if (empty($this->previous_session)) { return; // nothing to do here } // close our own session session_write_close(); session_name($this->previous_session['name']); if (version_compare(PHP_VERSION, '7.3.0', '>=')) { session_set_cookie_params($this->previous_session['cookie_params']); } else { session_set_cookie_params( $this->previous_session['cookie_params']['lifetime'], $this->previous_session['cookie_params']['path'], $this->previous_session['cookie_params']['domain'], $this->previous_session['cookie_params']['secure'], $this->previous_session['cookie_params']['httponly'] ); } session_id($this->previous_session['id']); $this->previous_session = []; @session_start(); /* * At this point, we have restored a previously-existing session, so we can't continue to use our session here. * Therefore, we need to load our session again in case we need it. We remove this handler from the parent * class so that the handler is initialized again if we ever need to do something with the session. */ parent::$sessionHandler = null; } /** * Create a new session id. * * @return string The new session id. */ public function newSessionId() { $sessionId = false; // generate new (secure) session id if (function_exists('session_create_id')) { $sid_length = (int) ini_get('session.sid_length'); $sid_bits_per_char = (int) ini_get('session.sid_bits_per_character'); if (($sid_length * $sid_bits_per_char) < 128) { Logger::warning("Unsafe defaults used for sessionId generation!"); } $sessionId = session_create_id(); } if (!$sessionId) { Logger::warning("Secure session ID generation failed, falling back to custom ID generation."); $sessionId = bin2hex(openssl_random_pseudo_bytes(16)); } Session::createSession($sessionId); return $sessionId; } /** * Retrieve the session ID saved in the session cookie, if there's one. * * @return string|null The session id saved in the cookie or null if no session cookie was set. * * @throws \SimpleSAML\Error\Exception If the cookie is marked as secure but we are not using HTTPS. */ public function getCookieSessionId() { if (!$this->hasSessionCookie()) { return null; // there's no session cookie, can't return ID } if (version_compare(PHP_VERSION, '7.2', 'ge') && headers_sent()) { // latest versions of PHP don't allow loading a session when output sent, get the ID from the cookie return $_COOKIE[$this->cookie_name]; } // do not rely on session_id() as it can return the ID of a previous session. Get it from the cookie instead. session_id($_COOKIE[$this->cookie_name]); $session_cookie_params = session_get_cookie_params(); if ($session_cookie_params['secure'] && !Utils\HTTP::isHTTPS()) { throw new Error\Exception('Session start with secure cookie not allowed on http.'); } @session_start(); return session_id(); } /** * Retrieve the session cookie name. * * @return string The session cookie name. */ public function getSessionCookieName() { return $this->cookie_name; } /** * Save the current session to the PHP session array. * * @param \SimpleSAML\Session $session The session object we should save. * @return void */ public function saveSession(\SimpleSAML\Session $session) { $_SESSION['SimpleSAMLphp_SESSION'] = serialize($session); } /** * Load the session from the PHP session array. * * @param string|null $sessionId The ID of the session we should load, or null to use the default. * * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist. * * @throws \SimpleSAML\Error\Exception If it wasn't possible to disable session cookies or we are trying to load a * PHP session with a specific identifier and it doesn't match with the current session identifier. */ public function loadSession($sessionId = null) { assert(is_string($sessionId) || $sessionId === null); if ($sessionId !== null) { if (session_id() === '' && !(version_compare(PHP_VERSION, '7.2', 'ge') && headers_sent())) { // session not initiated with getCookieSessionId(), start session without setting cookie $ret = ini_set('session.use_cookies', '0'); if ($ret === false) { throw new Error\Exception('Disabling PHP option session.use_cookies failed.'); } session_id($sessionId); @session_start(); } elseif ($sessionId !== session_id()) { throw new Error\Exception('Cannot load PHP session with a specific ID.'); } } elseif (session_id() === '') { $this->getCookieSessionId(); } if (!isset($_SESSION['SimpleSAMLphp_SESSION'])) { return null; } $session = $_SESSION['SimpleSAMLphp_SESSION']; assert(is_string($session)); $session = unserialize($session); return ($session !== false) ? $session : null; } /** * Check whether the session cookie is set. * * This function will only return false if is is certain that the cookie isn't set. * * @return boolean True if it was set, false otherwise. */ public function hasSessionCookie() { return array_key_exists($this->cookie_name, $_COOKIE); } /** * Get the cookie parameters that should be used for session cookies. * * This function contains some adjustments from the default to provide backwards-compatibility. * * @return array The cookie parameters for our sessions. * @link http://www.php.net/manual/en/function.session-get-cookie-params.php * * @throws \SimpleSAML\Error\Exception If both 'session.phpsession.limitedpath' and 'session.cookie.path' options * are set at the same time in the configuration. */ public function getCookieParams() { $config = Configuration::getInstance(); $ret = parent::getCookieParams(); if ($config->hasValue('session.phpsession.limitedpath') && $config->hasValue('session.cookie.path')) { throw new Error\Exception( 'You cannot set both the session.phpsession.limitedpath and session.cookie.path options.' ); } elseif ($config->hasValue('session.phpsession.limitedpath')) { $ret['path'] = $config->getBoolean( 'session.phpsession.limitedpath', false ) ? $config->getBasePath() : '/'; } $ret['httponly'] = $config->getBoolean('session.phpsession.httponly', true); if (version_compare(PHP_VERSION, '7.3.0', '<')) { // in older versions of PHP we need a nasty hack to set RFC6265bis SameSite attribute if ($ret['samesite'] !== null and !preg_match('/;\s+samesite/i', $ret['path'])) { $ret['path'] .= '; SameSite=' . $ret['samesite']; } } return $ret; } /** * Set a session cookie. * * @param string $sessionName The name of the session. * @param string|null $sessionID The session ID to use. Set to null to delete the cookie. * @param array|null $cookieParams Additional parameters to use for the session cookie. * @return void * * @throws \SimpleSAML\Error\CannotSetCookie If we can't set the cookie. */ public function setCookie($sessionName, $sessionID, array $cookieParams = null) { if ($cookieParams === null) { $cookieParams = session_get_cookie_params(); } if ($cookieParams['secure'] && !Utils\HTTP::isHTTPS()) { throw new Error\CannotSetCookie( 'Setting secure cookie on plain HTTP is not allowed.', Error\CannotSetCookie::SECURE_COOKIE ); } if (headers_sent()) { throw new Error\CannotSetCookie( 'Headers already sent.', Error\CannotSetCookie::HEADERS_SENT ); } if (session_id() !== '') { // session already started, close it session_write_close(); } if (version_compare(PHP_VERSION, '7.3.0', '>=')) { /** @psalm-suppress InvalidArgument */ session_set_cookie_params($cookieParams); } else { session_set_cookie_params( $cookieParams['lifetime'], $cookieParams['path'], $cookieParams['domain'] ?? '', $cookieParams['secure'], $cookieParams['httponly'] ); } session_id(strval($sessionID)); @session_start(); } } simplesamlphp-1.19.1/lib/SimpleSAML/Store/0000755000000000000000000000000014042503475016733 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Store/Redis.php0000644000000000000000000000672314042503475020522 0ustar rootrootgetString('store.redis.host', 'localhost'); $port = $config->getInteger('store.redis.port', 6379); $prefix = $config->getString('store.redis.prefix', 'SimpleSAMLphp'); $password = $config->getString('store.redis.password', ''); $database = $config->getInteger('store.redis.database', 0); $redis = new Client( [ 'scheme' => 'tcp', 'host' => $host, 'port' => $port, 'database' => $database, ] + (!empty($password) ? ['password' => $password] : []), [ 'prefix' => $prefix, ] ); } $this->redis = $redis; } /** * Deconstruct the Redis data store. */ public function __destruct() { if (method_exists($this->redis, 'disconnect')) { $this->redis->disconnect(); } } /** * Retrieve a value from the data store. * * @param string $type The type of the data. * @param string $key The key to retrieve. * * @return mixed|null The value associated with that key, or null if there's no such key. */ public function get($type, $key) { assert(is_string($type)); assert(is_string($key)); $result = $this->redis->get("{$type}.{$key}"); if ($result === false || $result === null) { return null; } return unserialize($result); } /** * Save a value in the data store. * * @param string $type The type of the data. * @param string $key The key to insert. * @param mixed $value The value itself. * @param int|null $expire The expiration time (unix timestamp), or null if it never expires. * @return void */ public function set($type, $key, $value, $expire = null) { assert(is_string($type)); assert(is_string($key)); assert($expire === null || (is_int($expire) && $expire > 2592000)); $serialized = serialize($value); if ($expire === null) { $this->redis->set("{$type}.{$key}", $serialized); } else { // setex expire time is in seconds (not unix timestamp) $this->redis->setex("{$type}.{$key}", $expire - time(), $serialized); } } /** * Delete an entry from the data store. * * @param string $type The type of the data * @param string $key The key to delete. * @return void */ public function delete($type, $key) { assert(is_string($type)); assert(is_string($key)); $this->redis->del("{$type}.{$key}"); } } simplesamlphp-1.19.1/lib/SimpleSAML/Store/Memcache.php0000644000000000000000000000401714042503475021150 0ustar rootrootprefix = $config->getString('memcache_store.prefix', 'simpleSAMLphp'); } /** * Retrieve a value from the data store. * * @param string $type The data type. * @param string $key The key. * @return mixed|null The value. */ public function get($type, $key) { assert(is_string($type)); assert(is_string($key)); return \SimpleSAML\Memcache::get($this->prefix . '.' . $type . '.' . $key); } /** * Save a value to the data store. * * @param string $type The data type. * @param string $key The key. * @param mixed $value The value. * @param int|null $expire The expiration time (unix timestamp), or NULL if it never expires. * @return void */ public function set($type, $key, $value, $expire = null) { assert(is_string($type)); assert(is_string($key)); assert($expire === null || (is_int($expire) && $expire > 2592000)); if ($expire === null) { $expire = 0; } \SimpleSAML\Memcache::set($this->prefix . '.' . $type . '.' . $key, $value, $expire); } /** * Delete a value from the data store. * * @param string $type The data type. * @param string $key The key. * @return void */ public function delete($type, $key) { assert(is_string($type)); assert(is_string($key)); \SimpleSAML\Memcache::delete($this->prefix . '.' . $type . '.' . $key); } } simplesamlphp-1.19.1/lib/SimpleSAML/Store/SQL.php0000644000000000000000000003075514042503475020115 0ustar rootrootgetString('store.sql.dsn'); $username = $config->getString('store.sql.username', null); $password = $config->getString('store.sql.password', null); $options = $config->getArray('store.sql.options', null); $this->prefix = $config->getString('store.sql.prefix', 'simpleSAMLphp'); try { $this->pdo = new PDO($dsn, $username, $password, $options); } catch (PDOException $e) { throw new \Exception("Database error: " . $e->getMessage()); } $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->driver = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); if ($this->driver === 'mysql') { $this->pdo->exec('SET time_zone = "+00:00"'); } $this->initTableVersionTable(); $this->initKVTable(); } /** * Initialize the table-version table. * @return void */ private function initTableVersionTable(): void { $this->tableVersions = []; try { $fetchTableVersion = $this->pdo->query('SELECT _name, _version FROM ' . $this->prefix . '_tableVersion'); } catch (PDOException $e) { $this->pdo->exec( 'CREATE TABLE ' . $this->prefix . '_tableVersion (_name VARCHAR(30) NOT NULL UNIQUE, _version INTEGER NOT NULL)' ); return; } while (($row = $fetchTableVersion->fetch(PDO::FETCH_ASSOC)) !== false) { $this->tableVersions[$row['_name']] = (int) $row['_version']; } } /** * Initialize key-value table. * @return void */ private function initKVTable(): void { $current_version = $this->getTableVersion('kvstore'); $text_t = 'TEXT'; $time_field = 'TIMESTAMP'; if ($this->driver === 'mysql') { // TEXT data type has size constraints that can be hit at some point, so we use LONGTEXT instead $text_t = 'LONGTEXT'; } if ($this->driver === 'sqlsrv') { // TIMESTAMP will not work for MSSQL. TIMESTAMP is automatically generated and cannot be inserted // so we use DATETIME instead $time_field = 'DATETIME'; } /** * Queries for updates, grouped by version. * New updates can be added as a new array in this array */ $table_updates = [ [ 'CREATE TABLE ' . $this->prefix . '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value ' . $text_t . ' NOT NULL, _expire ' . $time_field . ', PRIMARY KEY (_key, _type))', $this->driver === 'sqlite' || $this->driver === 'sqlsrv' || $this->driver === 'pgsql' ? 'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)' : 'ALTER TABLE ' . $this->prefix . '_kvstore ADD INDEX ' . $this->prefix . '_kvstore_expire (_expire)' ], /** * This upgrade removes the default NOT NULL constraint on the _expire field in MySQL. * Because SQLite does not support field alterations, the approach is to: * Create a new table without the NOT NULL constraint * Copy the current data to the new table * Drop the old table * Rename the new table correctly * Read the index */ [ 'CREATE TABLE ' . $this->prefix . '_kvstore_new (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value ' . $text_t . ' NOT NULL, _expire ' . $time_field . ' NULL, PRIMARY KEY (_key, _type))', 'INSERT INTO ' . $this->prefix . '_kvstore_new SELECT * FROM ' . $this->prefix . '_kvstore', 'DROP TABLE ' . $this->prefix . '_kvstore', // FOR MSSQL use EXEC sp_rename to rename a table (RENAME won't work) $this->driver === 'sqlsrv' ? 'EXEC sp_rename ' . $this->prefix . '_kvstore_new, ' . $this->prefix . '_kvstore' : 'ALTER TABLE ' . $this->prefix . '_kvstore_new RENAME TO ' . $this->prefix . '_kvstore', $this->driver === 'sqlite' || $this->driver === 'sqlsrv' || $this->driver === 'pgsql' ? 'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)' : 'ALTER TABLE ' . $this->prefix . '_kvstore ADD INDEX ' . $this->prefix . '_kvstore_expire (_expire)' ] ]; $latest_version = count($table_updates); if ($current_version == $latest_version) { return; } // Only run queries for after the current version $updates_to_run = array_slice($table_updates, $current_version); foreach ($updates_to_run as $version_updates) { foreach ($version_updates as $query) { $this->pdo->exec($query); } } $this->setTableVersion('kvstore', $latest_version); } /** * Get table version. * * @param string $name Table name. * * @return int The table version, or 0 if the table doesn't exist. */ public function getTableVersion($name) { assert(is_string($name)); if (!isset($this->tableVersions[$name])) { return 0; } return $this->tableVersions[$name]; } /** * Set table version. * * @param string $name Table name. * @param int $version Table version. * @return void */ public function setTableVersion($name, $version) { assert(is_string($name)); assert(is_int($version)); $this->insertOrUpdate( $this->prefix . '_tableVersion', ['_name'], ['_name' => $name, '_version' => $version] ); $this->tableVersions[$name] = $version; } /** * Insert or update a key-value in the store. * * Since various databases implement different methods for doing this, we abstract it away here. * * @param string $table The table we should update. * @param array $keys The key columns. * @param array $data Associative array with columns. * @return void */ public function insertOrUpdate($table, array $keys, array $data) { assert(is_string($table)); $colNames = '(' . implode(', ', array_keys($data)) . ')'; $values = 'VALUES(:' . implode(', :', array_keys($data)) . ')'; switch ($this->driver) { case 'mysql': $query = 'REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values; $query = $this->pdo->prepare($query); $query->execute($data); break; case 'sqlite': $query = 'INSERT OR REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values; $query = $this->pdo->prepare($query); $query->execute($data); break; default: $updateCols = []; $condCols = []; $condData = []; foreach ($data as $col => $value) { $tmp = $col . ' = :' . $col; if (in_array($col, $keys, true)) { $condCols[] = $tmp; $condData[$col] = $value; } else { $updateCols[] = $tmp; } } $selectQuery = 'SELECT * FROM ' . $table . ' WHERE ' . implode(' AND ', $condCols); $selectQuery = $this->pdo->prepare($selectQuery); $selectQuery->execute($condData); if (count($selectQuery->fetchAll()) > 0) { // Update $insertOrUpdateQuery = 'UPDATE ' . $table . ' SET ' . implode(',', $updateCols); $insertOrUpdateQuery .= ' WHERE ' . implode(' AND ', $condCols); $insertOrUpdateQuery = $this->pdo->prepare($insertOrUpdateQuery); } else { // Insert $insertOrUpdateQuery = 'INSERT INTO ' . $table . ' ' . $colNames . ' ' . $values; $insertOrUpdateQuery = $this->pdo->prepare($insertOrUpdateQuery); } $insertOrUpdateQuery->execute($data); break; } } /** * Clean the key-value table of expired entries. * @return void */ private function cleanKVStore(): void { Logger::debug('store.sql: Cleaning key-value store.'); $query = 'DELETE FROM ' . $this->prefix . '_kvstore WHERE _expire < :now'; $params = ['now' => gmdate('Y-m-d H:i:s')]; $query = $this->pdo->prepare($query); $query->execute($params); } /** * Retrieve a value from the data store. * * @param string $type The type of the data. * @param string $key The key to retrieve. * * @return mixed|null The value associated with that key, or null if there's no such key. */ public function get($type, $key) { assert(is_string($type)); assert(is_string($key)); if (strlen($key) > 50) { $key = sha1($key); } $query = 'SELECT _value FROM ' . $this->prefix . '_kvstore WHERE _type = :type AND _key = :key AND (_expire IS NULL OR _expire > :now)'; $params = ['type' => $type, 'key' => $key, 'now' => gmdate('Y-m-d H:i:s')]; $query = $this->pdo->prepare($query); $query->execute($params); $row = $query->fetch(PDO::FETCH_ASSOC); if ($row === false) { return null; } $value = $row['_value']; if (is_resource($value)) { $value = stream_get_contents($value); } $value = urldecode($value); $value = unserialize($value); if ($value === false) { return null; } return $value; } /** * Save a value in the data store. * * @param string $type The type of the data. * @param string $key The key to insert. * @param mixed $value The value itself. * @param int|null $expire The expiration time (unix timestamp), or null if it never expires. * @return void */ public function set($type, $key, $value, $expire = null) { assert(is_string($type)); assert(is_string($key)); assert($expire === null || (is_int($expire) && $expire > 2592000)); if (rand(0, 1000) < 10) { $this->cleanKVStore(); } if (strlen($key) > 50) { $key = sha1($key); } if ($expire !== null) { $expire = gmdate('Y-m-d H:i:s', $expire); } $value = serialize($value); $value = rawurlencode($value); $data = [ '_type' => $type, '_key' => $key, '_value' => $value, '_expire' => $expire, ]; $this->insertOrUpdate($this->prefix . '_kvstore', ['_type', '_key'], $data); } /** * Delete an entry from the data store. * * @param string $type The type of the data * @param string $key The key to delete. * @return void */ public function delete($type, $key) { assert(is_string($type)); assert(is_string($key)); if (strlen($key) > 50) { $key = sha1($key); } $data = [ '_type' => $type, '_key' => $key, ]; $query = 'DELETE FROM ' . $this->prefix . '_kvstore WHERE _type=:_type AND _key=:_key'; $query = $this->pdo->prepare($query); $query->execute($data); } } simplesamlphp-1.19.1/lib/SimpleSAML/Logger.php0000644000000000000000000003532314042503475017575 0ustar rootroot * @author Jaime Pérez Crespo, UNINETT AS * @package SimpleSAMLphp */ class Logger { /** * @var \SimpleSAML\Logger\LoggingHandlerInterface */ private static $loggingHandler; /** * @var bool */ private static $initializing = false; /** * @var integer|null */ private static $logLevel = null; /** * @var boolean */ private static $captureLog = false; /** * @var array */ private static $capturedLog = []; /** * Array with messages logged before the logging handler was initialized. * * @var array */ private static $earlyLog = []; /** * List of log levels. * * This list is used to restore the log levels after some log levels have been disabled. * * @var array */ private static $logLevelStack = []; /** * The current mask of log levels disabled. * * Note: this mask is not directly related to the PHP error reporting level. * * @var int */ private static $logMask = 0; /** * This constant defines the string we set the track ID to while we are fetching the track ID from the session * class. This is used to prevent infinite recursion. * * @var string */ public const NO_TRACKID = '_NOTRACKIDYET_'; /** * This variable holds the track ID we have retrieved from the session class. It can also be NULL, in which case * we haven't fetched the track ID yet, or self::NO_TRACKID, which means that we are fetching the track ID now. * * @var string */ private static $trackid = self::NO_TRACKID; /** * This variable holds the format used to log any message. Its use varies depending on the log handler used (for * instance, you cannot control here how dates are displayed when using syslog or errorlog handlers), but in * general the options are: * * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation * of the strftime() function for more information on the format. If the brackets are omitted, the standard * format is applied. This can be useful if you just want to control the placement of the date, but don't care * about the format. * * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' * option. The SyslogLoggingHandler will just remove this. * * - %level: the log level (name or number depending on the handler used). Please note different logging handlers * will print the log level differently. * * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind * the trailing space). * * - %trackid: the track ID, an identifier that allows you to track a single session. * * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. * * - %msg: the message to be logged. * * @var string The format of the log line. */ private static $format = '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg'; /** * This variable tells if we have a shutdown function registered or not. * * @var bool */ private static $shutdownRegistered = false; /** * This variable tells if we are shutting down. * * @var bool */ private static $shuttingDown = false; /** @var int */ public const EMERG = 0; /** @var int */ public const ALERT = 1; /** @var int */ public const CRIT = 2; /** @var int */ public const ERR = 3; /** @var int */ public const WARNING = 4; /** @var int */ public const NOTICE = 5; /** @var int */ public const INFO = 6; /** @var int */ public const DEBUG = 7; /** * Log an emergency message. * * @param string $string The message to log. * @return void */ public static function emergency($string) { self::log(self::EMERG, $string); } /** * Log a critical message. * * @param string $string The message to log. * @return void */ public static function critical($string) { self::log(self::CRIT, $string); } /** * Log an alert. * * @param string $string The message to log. * @return void */ public static function alert($string) { self::log(self::ALERT, $string); } /** * Log an error. * * @param string $string The message to log. * @return void */ public static function error($string) { self::log(self::ERR, $string); } /** * Log a warning. * * @param string $string The message to log. * @return void */ public static function warning($string) { self::log(self::WARNING, $string); } /** * We reserve the notice level for statistics, so do not use this level for other kind of log messages. * * @param string $string The message to log. * @return void */ public static function notice($string) { self::log(self::NOTICE, $string); } /** * Info messages are a bit less verbose than debug messages. This is useful to trace a session. * * @param string $string The message to log. * @return void */ public static function info($string) { self::log(self::INFO, $string); } /** * Debug messages are very verbose, and will contain more information than what is necessary for a production * system. * * @param string $string The message to log. * @return void */ public static function debug($string) { self::log(self::DEBUG, $string); } /** * Statistics. * * @param string $string The message to log. * @return void */ public static function stats($string) { self::log(self::NOTICE, $string, true); } /** * Set the logger to capture logs. * * @param boolean $val Whether to capture logs or not. Defaults to TRUE. * @return void */ public static function setCaptureLog($val = true) { self::$captureLog = $val; } /** * Get the captured log. * @return array */ public static function getCapturedLog() { return self::$capturedLog; } /** * Set the track identifier to use in all logs. * * @param string $trackId The track identifier to use during this session. * @return void */ public static function setTrackId($trackId) { self::$trackid = $trackId; self::flush(); } /** * Flush any pending log messages to the logging handler. * * @return void */ public static function flush() { foreach (self::$earlyLog as $msg) { self::log($msg['level'], $msg['string'], $msg['statsLog']); } self::$earlyLog = []; } /** * Flush any pending deferred logs during shutdown. * * This method is intended to be registered as a shutdown handler, so that any pending messages that weren't sent * to the logging handler at that point, can still make it. It is therefore not intended to be called manually. * * @return void */ public static function shutdown() { if (self::$trackid === self::NO_TRACKID) { try { $s = Session::getSessionFromRequest(); } catch (\Exception $e) { // loading session failed. We don't care why, at this point we have a transient session, so we use that $s = Session::getSessionFromRequest(); } self::$trackid = $s->getTrackID(); } self::$shuttingDown = true; self::flush(); } /** * Evaluate whether errors of a certain error level are masked or not. * * @param int $errno The level of the error to check. * * @return bool True if the error is masked, false otherwise. */ public static function isErrorMasked($errno) { return ($errno & self::$logMask) || !($errno & error_reporting()); } /** * Disable error reporting for the given log levels. * * Every call to this function must be followed by a call to popErrorMask(). * * @param int $mask The log levels that should be masked. * @return void */ public static function maskErrors($mask) { assert(is_int($mask)); $currentEnabled = error_reporting(); self::$logLevelStack[] = [$currentEnabled, self::$logMask]; $currentEnabled &= ~$mask; error_reporting($currentEnabled); self::$logMask |= $mask; } /** * Pop an error mask. * * This function restores the previous error mask. * * @return void */ public static function popErrorMask() { $lastMask = array_pop(self::$logLevelStack); error_reporting($lastMask[0]); self::$logMask = $lastMask[1]; } /** * Defer a message for later logging. * * @param int $level The log level corresponding to this message. * @param string $message The message itself to log. * @param boolean $stats Whether this is a stats message or a regular one. * @return void */ private static function defer(int $level, string $message, bool $stats): void { // save the message for later self::$earlyLog[] = ['level' => $level, 'string' => $message, 'statsLog' => $stats]; // register a shutdown handler if needed if (!self::$shutdownRegistered) { register_shutdown_function([self::class, 'shutdown']); self::$shutdownRegistered = true; } } /** * @param string|null $handler * @return void * @throws \Exception */ private static function createLoggingHandler(string $handler = null): void { self::$initializing = true; // a set of known logging handlers $known_handlers = [ 'syslog' => 'SimpleSAML\Logger\SyslogLoggingHandler', 'file' => 'SimpleSAML\Logger\FileLoggingHandler', 'errorlog' => 'SimpleSAML\Logger\ErrorLogLoggingHandler', 'stderr' => 'SimpleSAML\Logger\StandardErrorLoggingHandler', ]; // get the configuration $config = Configuration::getInstance(); assert($config instanceof Configuration); // setting minimum log_level self::$logLevel = $config->getInteger('logging.level', self::INFO); // get the metadata handler option from the configuration if (is_null($handler)) { $handler = $config->getString('logging.handler', 'syslog'); } if (!array_key_exists($handler, $known_handlers) && class_exists($handler)) { if (!in_array('SimpleSAML\Logger\LoggingHandlerInterface', class_implements($handler), true)) { throw new \Exception("The logging handler '$handler' is invalid."); } } else { $handler = strtolower($handler); if (!array_key_exists($handler, $known_handlers)) { throw new \Exception( "Invalid value for the 'logging.handler' configuration option. Unknown handler '" . $handler . "'." ); } $handler = $known_handlers[$handler]; } self::$format = $config->getString('logging.format', self::$format); try { /** @var \SimpleSAML\Logger\LoggingHandlerInterface */ self::$loggingHandler = new $handler($config); self::$loggingHandler->setLogFormat(self::$format); self::$initializing = false; } catch (\Exception $e) { self::$loggingHandler = new ErrorLogLoggingHandler($config); self::$initializing = false; self::log(self::CRIT, $e->getMessage(), false); } } /** * @param int $level * @param string $string * @param bool $statsLog * @return void */ private static function log(int $level, string $string, bool $statsLog = false): void { if (self::$initializing) { // some error occurred while initializing logging self::defer($level, $string, $statsLog); return; } elseif (php_sapi_name() === 'cli' || defined('STDIN')) { // we are being executed from the CLI, nowhere to log if (!isset(self::$loggingHandler)) { self::createLoggingHandler(\SimpleSAML\Logger\StandardErrorLoggingHandler::class); } $_SERVER['REMOTE_ADDR'] = "CLI"; if (self::$trackid === self::NO_TRACKID) { self::$trackid = 'CL' . bin2hex(openssl_random_pseudo_bytes(4)); } } elseif (!isset(self::$loggingHandler)) { // Initialize logging self::createLoggingHandler(); } if (self::$captureLog) { $sample = microtime(false); list($msecs, $mtime) = explode(' ', $sample); $time = intval($mtime); $usec = substr($msecs, 2, 3); $ts = gmdate('H:i:s', $time) . '.' . $usec . 'Z'; self::$capturedLog[] = $ts . ' ' . $string; } if (self::$logLevel >= $level || $statsLog) { $formats = ['%trackid', '%msg', '%srcip', '%stat']; $replacements = [self::$trackid, $string, $_SERVER['REMOTE_ADDR']]; $stat = ''; if ($statsLog) { $stat = 'STAT '; } array_push($replacements, $stat); if (self::$trackid === self::NO_TRACKID && !self::$shuttingDown) { // we have a log without track ID and we are not still shutting down, so defer logging self::defer($level, $string, $statsLog); return; } elseif (self::$trackid === self::NO_TRACKID) { // shutting down without a track ID, prettify it array_shift($replacements); array_unshift($replacements, 'N/A'); } // we either have a track ID or we are shutting down, so just log the message $string = str_replace($formats, $replacements, self::$format); self::$loggingHandler->log($level, $string); } } } simplesamlphp-1.19.1/lib/SimpleSAML/SessionHandlerStore.php0000644000000000000000000000401014042503475022301 0ustar rootrootstore = $store; } /** * Load a session from the data store. * * @param string|null $sessionId The ID of the session we should load, or null to use the default. * * @return \SimpleSAML\Session|null The session object, or null if it doesn't exist. */ public function loadSession($sessionId = null) { assert(is_string($sessionId) || $sessionId === null); if ($sessionId === null) { $sessionId = $this->getCookieSessionId(); if ($sessionId === null) { // no session cookie, nothing to load return null; } } $session = $this->store->get('session', $sessionId); if ($session !== null) { assert($session instanceof Session); return $session; } return null; } /** * Save a session to the data store. * * @param \SimpleSAML\Session $session The session object we should save. * @return void */ public function saveSession(Session $session) { if ($session->isTransient()) { // transient session, nothing to save return; } /** @var string $sessionId */ $sessionId = $session->getSessionId(); $config = Configuration::getInstance(); $sessionDuration = $config->getInteger('session.duration', 8 * 60 * 60); $expire = time() + $sessionDuration; $this->store->set('session', $sessionId, $session, $expire); } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/0000755000000000000000000000000014042503475016730 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Error/MetadataNotFound.php0000644000000000000000000000113114042503475022632 0ustar rootrootincludeTemplate = 'core:no_metadata.tpl.php'; parent::__construct([ 'METADATANOTFOUND', '%ENTITYID%' => htmlspecialchars(var_export($entityId, true)) ]); } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/ConfigurationError.php0000644000000000000000000000366214042503475023271 0ustar rootroot * @package SimpleSAMLphp */ class ConfigurationError extends Error { /** * The reason for this exception. * * @var null|string */ protected $reason; /** * The configuration file that caused this exception. * * @var null|string */ protected $config_file; /** * ConfigurationError constructor. * * @param string|null $reason The reason for this exception. * @param string|null $file The configuration file that originated this error. * @param array|null $config The configuration array that led to this problem. */ public function __construct($reason = null, $file = null, array $config = null) { $file_str = ''; $reason_str = '.'; $params = ['CONFIG']; if ($file !== null) { $params['%FILE%'] = $file; $basepath = dirname(dirname(dirname(dirname(__FILE__)))) . '/'; $file_str = '(' . str_replace($basepath, '', $file) . ') '; } if ($reason !== null) { $params['%REASON%'] = $reason; $reason_str = ': ' . $reason; } $this->reason = $reason; $this->config_file = $file; parent::__construct($params); $this->message = 'The configuration ' . $file_str . 'is invalid' . $reason_str; } /** * Get the reason for this exception. * * @return null|string The reason for this exception. */ public function getReason() { return $this->reason; } /** * Get the configuration file that caused this exception. * * @return null|string The configuration file that caused this exception. */ public function getConfFile() { return $this->config_file; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/UnserializableException.php0000644000000000000000000000257514042503475024302 0ustar rootrootclass = get_class($original); $msg = $original->getMessage(); $code = $original->getCode(); if (!is_int($code)) { // PDOException and possibly others use a string for the code. Filter it out here. $code = -1; } parent::__construct($msg, $code); $this->initBacktrace($original); } /** * Retrieve the class of this exception. * * @return string The classname. */ public function getClass() { return $this->class; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/User.php0000644000000000000000000000035114042503475020356 0ustar rootroot * @package SimpleSAMLphp_base * */ class User extends Exception { } simplesamlphp-1.19.1/lib/SimpleSAML/Error/NoPassive.php0000644000000000000000000000051514042503475021351 0ustar rootroot * @package SimpleSAMLphp */ class CannotSetCookie extends Exception { /** * The exception was thrown for unknown reasons. * * @var int */ public const UNKNOWN = 0; /** * The exception was due to the HTTP headers being already sent, and therefore we cannot send additional headers to * set the cookie. * * @var int */ public const HEADERS_SENT = 1; /** * The exception was due to trying to set a secure cookie over an insecure channel. * * @var int */ public const SECURE_COOKIE = 2; } simplesamlphp-1.19.1/lib/SimpleSAML/Error/ProxyCountExceeded.php0000644000000000000000000000056114042503475023224 0ustar rootrootincludeTemplate = 'core:no_state.tpl.php'; parent::__construct('NOSTATE'); } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/ErrorCodes.php0000644000000000000000000002155714042503475021522 0ustar rootroot * @package SimpleSAMLphp */ class ErrorCodes { /** * Fetch all default translation strings for error code titles. * * @return array A map from error code to error code title */ final public static function defaultGetAllErrorCodeTitles() { return [ 'ACSPARAMS' => Translate::noop('{errors:title_ACSPARAMS}'), 'ARSPARAMS' => Translate::noop('No SAML message provided'), 'AUTHSOURCEERROR' => Translate::noop('{errors:title_AUTHSOURCEERROR}'), 'BADREQUEST' => Translate::noop('{errors:title_BADREQUEST}'), 'CASERROR' => Translate::noop('{errors:title_CASERROR}'), 'CONFIG' => Translate::noop('{errors:title_CONFIG}'), 'CREATEREQUEST' => Translate::noop('{errors:title_CREATEREQUEST}'), 'DISCOPARAMS' => Translate::noop('{errors:title_DISCOPARAMS}'), 'GENERATEAUTHNRESPONSE' => Translate::noop('{errors:title_GENERATEAUTHNRESPONSE}'), 'INVALIDCERT' => Translate::noop('{errors:title_INVALIDCERT}'), 'LDAPERROR' => Translate::noop('{errors:title_LDAPERROR}'), 'LOGOUTINFOLOST' => Translate::noop('{errors:title_LOGOUTINFOLOST}'), 'LOGOUTREQUEST' => Translate::noop('{errors:title_LOGOUTREQUEST}'), 'MEMCACHEDOWN' => Translate::noop('Cannot retrieve session data'), 'METADATA' => Translate::noop('{errors:title_METADATA}'), 'METADATANOTFOUND' => Translate::noop('{errors:title_METADATANOTFOUND}'), 'NOACCESS' => Translate::noop('{errors:title_NOACCESS}'), 'NOCERT' => Translate::noop('{errors:title_NOCERT}'), 'NORELAYSTATE' => Translate::noop('{errors:title_NORELAYSTATE}'), 'NOSTATE' => Translate::noop('{errors:title_NOSTATE}'), 'NOTFOUND' => Translate::noop('{errors:title_NOTFOUND}'), 'NOTFOUNDREASON' => Translate::noop('{errors:title_NOTFOUNDREASON}'), 'NOTSET' => Translate::noop('{errors:title_NOTSET}'), 'NOTVALIDCERT' => Translate::noop('{errors:title_NOTVALIDCERT}'), 'PROCESSASSERTION' => Translate::noop('{errors:title_PROCESSASSERTION}'), 'PROCESSAUTHNREQUEST' => Translate::noop('{errors:title_PROCESSAUTHNREQUEST}'), 'RESPONSESTATUSNOSUCCESS' => Translate::noop('{errors:title_RESPONSESTATUSNOSUCCESS}'), 'SLOSERVICEPARAMS' => Translate::noop('{errors:title_SLOSERVICEPARAMS}'), 'SSOPARAMS' => Translate::noop('No SAML request provided'), 'UNHANDLEDEXCEPTION' => Translate::noop('{errors:title_UNHANDLEDEXCEPTION}'), 'UNKNOWNCERT' => Translate::noop('{errors:title_UNKNOWNCERT}'), 'USERABORTED' => Translate::noop('{errors:title_USERABORTED}'), 'WRONGUSERPASS' => Translate::noop('{errors:title_WRONGUSERPASS}'), ]; } /** * Fetch all translation strings for error code titles. * * Extend this to add error codes. * * @return array A map from error code to error code title */ public static function getAllErrorCodeTitles() { return self::defaultGetAllErrorCodeTitles(); } /** * Fetch all default translation strings for error code descriptions. * * @return array A map from error code to error code description */ final public static function defaultGetAllErrorCodeDescriptions() { return [ 'ACSPARAMS' => Translate::noop('{errors:descr_ACSPARAMS}'), 'ARSPARAMS' => Translate::noop("" . "You accessed the Artifact Resolution Service interface, but did not " . "provide a SAML ArtifactResolve message. Please note that this endpoint is" . " not intended to be accessed directly."), 'AUTHSOURCEERROR' => Translate::noop('{errors:descr_AUTHSOURCEERROR}'), 'BADREQUEST' => Translate::noop('{errors:descr_BADREQUEST}'), 'CASERROR' => Translate::noop('{errors:descr_CASERROR}'), 'CONFIG' => Translate::noop('{errors:descr_CONFIG}'), 'CREATEREQUEST' => Translate::noop('{errors:descr_CREATEREQUEST}'), 'DISCOPARAMS' => Translate::noop('{errors:descr_DISCOPARAMS}'), 'GENERATEAUTHNRESPONSE' => Translate::noop('{errors:descr_GENERATEAUTHNRESPONSE}'), 'INVALIDCERT' => Translate::noop('{errors:descr_INVALIDCERT}'), 'LDAPERROR' => Translate::noop('{errors:descr_LDAPERROR}'), 'LOGOUTINFOLOST' => Translate::noop('{errors:descr_LOGOUTINFOLOST}'), 'LOGOUTREQUEST' => Translate::noop('{errors:descr_LOGOUTREQUEST}'), 'MEMCACHEDOWN' => Translate::noop('{errors:descr_MEMCACHEDOWN}'), 'METADATA' => Translate::noop('{errors:descr_METADATA}'), 'METADATANOTFOUND' => Translate::noop('{errors:descr_METADATANOTFOUND}'), 'NOACCESS' => Translate::noop('{errors:descr_NOACCESS}'), 'NOCERT' => Translate::noop('{errors:descr_NOCERT}'), 'NORELAYSTATE' => Translate::noop('{errors:descr_NORELAYSTATE}'), 'NOSTATE' => Translate::noop('{errors:descr_NOSTATE}'), 'NOTFOUND' => Translate::noop('{errors:descr_NOTFOUND}'), 'NOTFOUNDREASON' => Translate::noop('{errors:descr_NOTFOUNDREASON}'), 'NOTSET' => Translate::noop('{errors:descr_NOTSET}'), 'NOTVALIDCERT' => Translate::noop('{errors:descr_NOTVALIDCERT}'), 'PROCESSASSERTION' => Translate::noop('{errors:descr_PROCESSASSERTION}'), 'PROCESSAUTHNREQUEST' => Translate::noop('{errors:descr_PROCESSAUTHNREQUEST}'), 'RESPONSESTATUSNOSUCCESS' => Translate::noop('{errors:descr_RESPONSESTATUSNOSUCCESS}'), 'SLOSERVICEPARAMS' => Translate::noop('{errors:descr_SLOSERVICEPARAMS}'), 'SSOPARAMS' => Translate::noop("" . "You accessed the Single Sign On Service interface, but did not provide a " . "SAML Authentication Request. Please note that this endpoint is not " . "intended to be accessed directly."), 'UNHANDLEDEXCEPTION' => Translate::noop('{errors:descr_UNHANDLEDEXCEPTION}'), 'UNKNOWNCERT' => Translate::noop('{errors:descr_UNKNOWNCERT}'), 'USERABORTED' => Translate::noop('{errors:descr_USERABORTED}'), 'WRONGUSERPASS' => Translate::noop('{errors:descr_WRONGUSERPASS}'), ]; } /** * Fetch all translation strings for error code descriptions. * * Extend this to add error codes. * * @return array A map from error code to error code description */ public static function getAllErrorCodeDescriptions() { return self::defaultGetAllErrorCodeDescriptions(); } /** * Get a map of both errorcode titles and descriptions * * Convenience-method for template-callers * * @return array An array containing both errorcode maps. */ public static function getAllErrorCodeMessages() { return [ 'title' => self::getAllErrorCodeTitles(), 'descr' => self::getAllErrorCodeDescriptions(), ]; } /** * Fetch a translation string for a title for a given error code. * * @param string $errorCode The error code to look up * * @return string A string to translate */ public static function getErrorCodeTitle($errorCode) { if (array_key_exists($errorCode, self::getAllErrorCodeTitles())) { $errorCodeTitles = self::getAllErrorCodeTitles(); return $errorCodeTitles[$errorCode]; } else { return Translate::addTagPrefix($errorCode, 'title_'); } } /** * Fetch a translation string for a description for a given error code. * * @param string $errorCode The error code to look up * * @return string A string to translate */ public static function getErrorCodeDescription($errorCode) { if (array_key_exists($errorCode, self::getAllErrorCodeTitles())) { $errorCodeDescriptions = self::getAllErrorCodeDescriptions(); return $errorCodeDescriptions[$errorCode]; } else { return Translate::addTagPrefix($errorCode, 'descr_'); } } /** * Get both title and description for a specific error code * * Convenience-method for template-callers * * @param string $errorCode The error code to look up * * @return array An array containing both errorcode strings. */ public static function getErrorCodeMessage($errorCode) { return [ 'title' => self::getErrorCodeTitle($errorCode), 'descr' => self::getErrorCodeDescription($errorCode), ]; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/Exception.php0000644000000000000000000002037714042503475021410 0ustar rootroot * @package SimpleSAMLphp */ class Exception extends \Exception { /** * The backtrace for this exception. * * We need to save the backtrace, since we cannot rely on * serializing the Exception::trace-variable. * * @var array */ private $backtrace = []; /** * The cause of this exception. * * @var \SimpleSAML\Error\Exception|null */ private $cause = null; /** * Constructor for this error. * * Note that the cause will be converted to a SimpleSAML\Error\UnserializableException unless it is a subclass of * SimpleSAML\Error\Exception. * * @param string $message Exception message * @param int $code Error code * @param \Throwable|null $cause The cause of this exception. */ public function __construct(string $message, int $code = 0, Throwable $cause = null) { assert(is_string($message)); assert(is_int($code)); parent::__construct($message, $code); $this->initBacktrace($this); if ($cause !== null) { $this->cause = Exception::fromException($cause); } } /** * Convert any exception into a \SimpleSAML\Error\Exception. * * @param \Throwable $e The exception. * * @return \SimpleSAML\Error\Exception The new exception. */ public static function fromException(Throwable $e): Exception { if ($e instanceof Exception) { return $e; } return new UnserializableException($e); } /** * Load the backtrace from the given exception. * * @param \Throwable $exception The exception we should fetch the backtrace from. * @return void */ protected function initBacktrace(Throwable $exception): void { $this->backtrace = []; // position in the top function on the stack $pos = $exception->getFile() . ':' . $exception->getLine(); foreach ($exception->getTrace() as $t) { $function = $t['function']; if (array_key_exists('class', $t)) { $function = $t['class'] . '::' . $function; } $this->backtrace[] = $pos . ' (' . $function . ')'; if (array_key_exists('file', $t)) { $pos = $t['file'] . ':' . $t['line']; } else { $pos = '[builtin]'; } } $this->backtrace[] = $pos . ' (N/A)'; } /** * Retrieve the backtrace. * * @return array An array where each function call is a single item. */ public function getBacktrace() { return $this->backtrace; } /** * Retrieve the cause of this exception. * * @return \Throwable|null The cause of this exception. */ public function getCause(): ?Throwable { return $this->cause; } /** * Retrieve the class of this exception. * * @return string The name of the class. */ public function getClass() { return get_class($this); } /** * Format this exception for logging. * * Create an array of lines for logging. * * @param boolean $anonymize Whether the resulting messages should be anonymized or not. * * @return array Log lines that should be written out. */ public function format($anonymize = false) { $ret = [ $this->getClass() . ': ' . $this->getMessage(), ]; return array_merge($ret, $this->formatBacktrace($anonymize)); } /** * Format the backtrace for logging. * * Create an array of lines for logging from the backtrace. * * @param boolean $anonymize Whether the resulting messages should be anonymized or not. * * @return array All lines of the backtrace, properly formatted. */ public function formatBacktrace($anonymize = false) { $ret = []; $basedir = Configuration::getInstance()->getBaseDir(); $e = $this; do { if ($e !== $this) { $ret[] = 'Caused by: ' . $e->getClass() . ': ' . $e->getMessage(); } $ret[] = 'Backtrace:'; $depth = count($e->backtrace); foreach ($e->backtrace as $i => $trace) { if ($anonymize) { $trace = str_replace($basedir, '', $trace); } $ret[] = ($depth - $i - 1) . ' ' . $trace; } $e = $e->cause; } while ($e !== null); return $ret; } /** * Print the backtrace to the log if the 'debug' option is enabled in the configuration. * @param int $level * @return void */ protected function logBacktrace($level = Logger::DEBUG) { // Do nothing if backtraces have been disabled in config. $debug = Configuration::getInstance()->getArrayize('debug', ['backtraces' => true]); if (array_key_exists('backtraces', $debug) && $debug['backtraces'] === false) { return; } $backtrace = $this->formatBacktrace(); $callback = [Logger::class]; $functions = [ Logger::ERR => 'error', Logger::WARNING => 'warning', Logger::INFO => 'info', Logger::DEBUG => 'debug', ]; $callback[] = $functions[$level]; foreach ($backtrace as $line) { call_user_func($callback, $line); } } /** * Print the exception to the log, by default with log level error. * * Override to allow errors extending this class to specify the log level themselves. * * @param int $default_level The log level to use if this method was not overridden. * @return void */ public function log($default_level) { $fn = [ Logger::ERR => 'logError', Logger::WARNING => 'logWarning', Logger::INFO => 'logInfo', Logger::DEBUG => 'logDebug', ]; call_user_func([$this, $fn[$default_level]], $default_level); } /** * Print the exception to the log with log level error. * * This function will write this exception to the log, including a full backtrace. * @return void */ public function logError() { Logger::error($this->getClass() . ': ' . $this->getMessage()); $this->logBacktrace(Logger::ERR); } /** * Print the exception to the log with log level warning. * * This function will write this exception to the log, including a full backtrace. * @return void */ public function logWarning() { Logger::warning($this->getClass() . ': ' . $this->getMessage()); $this->logBacktrace(Logger::WARNING); } /** * Print the exception to the log with log level info. * * This function will write this exception to the log, including a full backtrace. * @return void */ public function logInfo() { Logger::info($this->getClass() . ': ' . $this->getMessage()); $this->logBacktrace(Logger::INFO); } /** * Print the exception to the log with log level debug. * * This function will write this exception to the log, including a full backtrace. * @return void */ public function logDebug() { Logger::debug($this->getClass() . ': ' . $this->getMessage()); $this->logBacktrace(Logger::DEBUG); } /** * Function for serialization. * * This function builds a list of all variables which should be serialized. It will serialize all variables except * the Exception::trace variable. * * @return array Array with the variables that should be serialized. */ public function __sleep() { $ret = array_keys((array) $this); foreach ($ret as $i => $e) { if ($e === "\0Exception\0trace") { unset($ret[$i]); } } return $ret; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/BadRequest.php0000644000000000000000000000203214042503475021475 0ustar rootrootreason = $reason; parent::__construct(['BADREQUEST', '%REASON%' => $this->reason]); $this->httpCode = 400; } /** * Retrieve the reason why the request was invalid. * * @return string The reason why the request was invalid. */ public function getReason() { return $this->reason; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/CriticalConfigurationError.php0000644000000000000000000000552114042503475024740 0ustar rootroot * @package SimpleSAMLphp */ class CriticalConfigurationError extends ConfigurationError { /** * This is the bare minimum configuration that we can use. * * @var array */ private static $minimum_config = [ 'logging.handler' => 'errorlog', 'logging.level' => Logger::DEBUG, 'errorreporting' => false, 'debug' => true, ]; /** * CriticalConfigurationError constructor. * * @param string|null $reason The reason for this critical error. * @param string|null $file The configuration file that originated this error. * @param array|null $config The configuration array that led to this problem. */ public function __construct($reason = null, $file = null, $config = null) { if ($config === null) { $config = self::$minimum_config; $config['baseurlpath'] = Utils\HTTP::guessBasePath(); } Configuration::loadFromArray( $config, '', 'simplesaml' ); parent::__construct($reason, $file); } /** * @param \Throwable $exception * * @return \SimpleSAML\Error\Exception */ public static function fromException(Throwable $exception): Exception { $reason = null; $file = null; if ($exception instanceof ConfigurationError) { $reason = $exception->getReason(); $file = $exception->getConfFile(); } else { $reason = $exception->getMessage(); } return new CriticalConfigurationError($reason, $file); } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/NotFound.php0000644000000000000000000000357314042503475021205 0ustar rootroot $url]); $this->message = "The requested page '$url' could not be found."; } else { parent::__construct(['NOTFOUNDREASON', '%URL%' => $url, '%REASON%' => $reason]); $this->message = "The requested page '$url' could not be found. " . $reason; } $this->reason = $reason; $this->httpCode = 404; } /** * Retrieve the reason why the given page could not be found. * * @return string|null The reason why the page could not be found. */ public function getReason() { return $this->reason; } /** * NotFound exceptions don't need to display a backtrace, as they are very simple and the trace is usually trivial, * so just log the message without any backtrace at all. * * @param bool $anonymize Whether to anonymize the trace or not. * * @return array */ public function format($anonymize = false) { return [ $this->getClass() . ': ' . $this->getMessage(), ]; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/Error.php0000644000000000000000000001700014042503475020530 0ustar rootrootparameters = $errorCode; unset($this->parameters[0]); $this->errorCode = $errorCode[0]; } else { $this->parameters = []; $this->errorCode = $errorCode; } if (isset($httpCode)) { $this->httpCode = $httpCode; } $this->dictTitle = ErrorCodes::getErrorCodeTitle($this->errorCode); $this->dictDescr = ErrorCodes::getErrorCodeDescription($this->errorCode); if (!empty($this->parameters)) { $msg = $this->errorCode . '('; foreach ($this->parameters as $k => $v) { if ($k === 0) { continue; } $msg .= var_export($k, true) . ' => ' . var_export($v, true) . ', '; } $msg = substr($msg, 0, -2) . ')'; } else { $msg = $this->errorCode; } parent::__construct($msg, -1, $cause); } /** * Retrieve the error code given when throwing this error. * * @return string The error code. */ public function getErrorCode() { return $this->errorCode; } /** * Retrieve the error parameters given when throwing this error. * * @return array The parameters. */ public function getParameters() { return $this->parameters; } /** * Retrieve the error title tag in dictionary. * * @return string The error title tag. */ public function getDictTitle() { return $this->dictTitle; } /** * Retrieve the error description tag in dictionary. * * @return string The error description tag. */ public function getDictDescr() { return $this->dictDescr; } /** * Set the HTTP return code for this error. * * This should be overridden by subclasses who want a different return code than 500 Internal Server Error. * @return void */ protected function setHTTPCode() { http_response_code($this->httpCode); } /** * Save an error report. * * @return array The array with the error report data. */ protected function saveError() { $data = $this->format(true); $emsg = array_shift($data); $etrace = implode("\n", $data); $reportId = bin2hex(openssl_random_pseudo_bytes(4)); Logger::error('Error report with id ' . $reportId . ' generated.'); $config = Configuration::getInstance(); $session = Session::getSessionFromRequest(); if (isset($_SERVER['HTTP_REFERER'])) { $referer = $_SERVER['HTTP_REFERER']; // remove anything after the first '?' or ';', just in case it contains any sensitive data $referer = explode('?', $referer, 2); $referer = $referer[0]; $referer = explode(';', $referer, 2); $referer = $referer[0]; } else { $referer = 'unknown'; } $errorData = [ 'exceptionMsg' => $emsg, 'exceptionTrace' => $etrace, 'reportId' => $reportId, 'trackId' => $session->getTrackID(), 'url' => Utils\HTTP::getSelfURLNoQuery(), 'version' => $config->getVersion(), 'referer' => $referer, ]; $session->setData('core:errorreport', $reportId, $errorData); return $errorData; } /** * Display this error. * * This method displays a standard SimpleSAMLphp error page and exits. * @return void */ public function show() { // log the error message $this->logError(); $errorData = $this->saveError(); $config = Configuration::getInstance(); $data = []; $data['showerrors'] = $config->getBoolean('showerrors', true); $data['error'] = $errorData; $data['errorCode'] = $this->errorCode; $data['parameters'] = $this->parameters; $data['module'] = $this->module; $data['dictTitle'] = $this->dictTitle; $data['dictDescr'] = $this->dictDescr; $data['includeTemplate'] = $this->includeTemplate; $data['clipboard.js'] = true; // check if there is a valid technical contact email address if ( $config->getBoolean('errorreporting', true) && $config->getString('technicalcontact_email', 'na@example.org') !== 'na@example.org' ) { // enable error reporting $baseurl = Utils\HTTP::getBaseURL(); $data['errorReportAddress'] = $baseurl . 'errorreport.php'; } $data['email'] = ''; $session = Session::getSessionFromRequest(); $authorities = $session->getAuthorities(); foreach ($authorities as $authority) { $attributes = $session->getAuthData($authority, 'Attributes'); if ($attributes !== null && array_key_exists('mail', $attributes) && count($attributes['mail']) > 0) { $data['email'] = $attributes['mail'][0]; break; // enough, don't need to get all available mails, if more than one } } $show_function = $config->getArray('errors.show_function', null); if (isset($show_function)) { assert(is_callable($show_function)); $this->setHTTPCode(); call_user_func($show_function, $config, $data); assert(false); } else { $t = new Template($config, 'error.php', 'errors'); $t->setStatusCode($this->httpCode); $t->data = array_merge($t->data, $data); $t->show(); } exit; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/UserAborted.php0000644000000000000000000000071614042503475021664 0ustar rootrootassertion = $assertion; } /** * Retrieve the assertion which failed. * * @return string|null The assertion which failed, or null if the assert-function was called with an expression. */ public function getAssertion() { return $this->assertion; } /** * Install this assertion handler. * * This function will register this assertion handler. If will not enable assertions if they are * disabled. * @return void */ public static function installHandler() { assert_options(ASSERT_WARNING, 0); assert_options(ASSERT_QUIET_EVAL, 0); assert_options(ASSERT_CALLBACK, [Assertion::class, 'onAssertion']); } /** * Handle assertion. * * This function handles an assertion. * * @param string $file The file assert was called from. * @param int $line The line assert was called from. * @param mixed $message The expression which was passed to the assert-function. * @return void */ public static function onAssertion($file, $line, $message) { if (!empty($message)) { $exception = new self($message); } else { $exception = new self(); } $exception->logError(); } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/AuthSource.php0000644000000000000000000000327114042503475021526 0ustar rootrootauthsource = $authsource; $this->reason = $reason; parent::__construct( [ 'AUTHSOURCEERROR', '%AUTHSOURCE%' => htmlspecialchars(var_export($this->authsource, true)), '%REASON%' => htmlspecialchars(var_export($this->reason, true)) ], $cause ); $this->message = "Error with authentication source '$authsource': $reason"; } /** * Retrieve the authsource module name from where this error was thrown. * * @return string Authsource module name. */ public function getAuthSource() { return $this->authsource; } /** * Retrieve the reason why the request was invalid. * * @return string The reason why the request was invalid. */ public function getReason() { return $this->reason; } } simplesamlphp-1.19.1/lib/SimpleSAML/Error/InvalidCredential.php0000644000000000000000000000037514042503475023027 0ustar rootroot * @package SimpleSAMLphp_base * */ class InvalidCredential extends User { } simplesamlphp-1.19.1/lib/SimpleSAML/Error/UserNotFound.php0000644000000000000000000000037014042503475022034 0ustar rootroot * @package SimpleSAMLphp_base * */ class UserNotFound extends User { } simplesamlphp-1.19.1/lib/SimpleSAML/Error/BadUserInput.php0000644000000000000000000000036414042503475022011 0ustar rootroot * @package SimpleSAMLphp_base * */ class BadUserInput extends User { } simplesamlphp-1.19.1/lib/SimpleSAML/HTTP/0000755000000000000000000000000014042503475016416 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/HTTP/RunnableResponse.php0000644000000000000000000000321414042503475022414 0ustar rootrootarguments = $args; $this->callable = $callable; $this->charset = 'UTF-8'; parent::__construct(); } /** * Get the callable for this response. * * @return callable */ public function getCallable() { return $this->callable; } /** * Get the arguments to the callable. * * @return array */ public function getArguments() { return $this->arguments; } /** * "Send" this response by actually running the callable. * * @return $this * * Note: No return-type possible due to upstream limitations */ public function sendContent() { return call_user_func_array($this->callable, $this->arguments); } } simplesamlphp-1.19.1/lib/SimpleSAML/IdP/0000755000000000000000000000000014042503475016313 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/IdP/TraditionalLogoutHandler.php0000644000000000000000000000676314042503475024002 0ustar rootrootidp = $idp; } /** * Picks the next SP and issues a logout request. * * This function never returns. * * @param array &$state The logout state. * @return void */ private function logoutNextSP(array &$state): void { $association = array_pop($state['core:LogoutTraditional:Remaining']); if ($association === null) { $this->idp->finishLogout($state); } $relayState = Auth\State::saveState($state, 'core:LogoutTraditional', true); $id = $association['id']; Logger::info('Logging out of ' . var_export($id, true) . '.'); try { $idp = IdP::getByState($association); $url = call_user_func([$association['Handler'], 'getLogoutURL'], $idp, $association, $relayState); Utils\HTTP::redirectTrustedURL($url); } catch (\Exception $e) { Logger::warning('Unable to initialize logout to ' . var_export($id, true) . '.'); $this->idp->terminateAssociation($id); $state['core:Failed'] = true; // Try the next SP $this->logoutNextSP($state); assert(false); } } /** * Start the logout operation. * * This function never returns. * * @param array &$state The logout state. * @param string $assocId The association that started the logout. * @return void */ public function startLogout(array &$state, $assocId) { $state['core:LogoutTraditional:Remaining'] = $this->idp->getAssociations(); $this->logoutNextSP($state); } /** * Continue the logout operation. * * This function will never return. * * @param string $assocId The association that is terminated. * @param string|null $relayState The RelayState from the start of the logout. * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any). * @return void * * @throws \SimpleSAML\Error\Exception If the RelayState was lost during logout. */ public function onResponse($assocId, $relayState, Error\Exception $error = null) { assert(is_string($assocId)); assert(is_string($relayState) || $relayState === null); if ($relayState === null) { throw new Error\Exception('RelayState lost during logout.'); } /** @psalm-var array $state */ $state = Auth\State::loadState($relayState, 'core:LogoutTraditional'); if ($error === null) { Logger::info('Logged out of ' . var_export($assocId, true) . '.'); $this->idp->terminateAssociation($assocId); } else { Logger::warning('Error received from ' . var_export($assocId, true) . ' during logout:'); $error->logWarning(); $state['core:Failed'] = true; } $this->logoutNextSP($state); } } simplesamlphp-1.19.1/lib/SimpleSAML/IdP/LogoutHandlerInterface.php0000644000000000000000000000225414042503475023417 0ustar rootrootidp = $idp; } /** * Start the logout operation. * * @param array &$state The logout state. * @param string|null $assocId The SP we are logging out from. * @return void */ public function startLogout(array &$state, $assocId) { assert(is_string($assocId) || $assocId === null); $associations = $this->idp->getAssociations(); if (count($associations) === 0) { $this->idp->finishLogout($state); } foreach ($associations as $id => &$association) { $idp = IdP::getByState($association); $association['core:Logout-IFrame:Name'] = $idp->getSPName($id); $association['core:Logout-IFrame:State'] = 'onhold'; } $state['core:Logout-IFrame:Associations'] = $associations; if (!is_null($assocId)) { $spName = $this->idp->getSPName($assocId); if ($spName === null) { $spName = ['en' => $assocId]; } $state['core:Logout-IFrame:From'] = $spName; } else { $state['core:Logout-IFrame:From'] = null; } $params = [ 'id' => Auth\State::saveState($state, 'core:Logout-IFrame'), ]; if (isset($state['core:Logout-IFrame:InitType'])) { $params['type'] = $state['core:Logout-IFrame:InitType']; } $url = Module::getModuleURL('core/idp/logout-iframe.php', $params); Utils\HTTP::redirectTrustedURL($url); } /** * Continue the logout operation. * * This function will never return. * * @param string $assocId The association that is terminated. * @param string|null $relayState The RelayState from the start of the logout. * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any). * @return void */ public function onResponse($assocId, $relayState, Error\Exception $error = null) { assert(is_string($assocId)); $this->idp->terminateAssociation($assocId); $config = Configuration::getInstance(); $t = new Template($config, 'IFrameLogoutHandler.tpl.php'); $t->data['assocId'] = var_export($assocId, true); $t->data['spId'] = sha1($assocId); if (!is_null($error)) { $t->data['errorMsg'] = $error->getMessage(); } $t->show(); } } simplesamlphp-1.19.1/lib/SimpleSAML/Store.php0000644000000000000000000000616514042503475017454 0ustar rootrootgetString('store.type', 'phpsession'); switch ($storeType) { case 'phpsession': // we cannot support advanced features with the PHP session store self::$instance = false; break; case 'memcache': self::$instance = new Store\Memcache(); break; case 'sql': self::$instance = new Store\SQL(); break; case 'redis': self::$instance = new Store\Redis(); break; default: // datastore from module try { $className = Module::resolveClass($storeType, 'Store', '\SimpleSAML\Store'); } catch (Exception $e) { $c = $config->toArray(); $c['store.type'] = 'phpsession'; throw new Error\CriticalConfigurationError( "Invalid 'store.type' configuration option. Cannot find store '$storeType'.", null, $c ); } /** @var \SimpleSAML\Store|false */ self::$instance = new $className(); } return self::$instance; } /** * Retrieve a value from the data store. * * @param string $type The data type. * @param string $key The key. * * @return mixed|null The value. */ abstract public function get($type, $key); /** * Save a value to the data store. * * @param string $type The data type. * @param string $key The key. * @param mixed $value The value. * @param int|null $expire The expiration time (unix timestamp), or null if it never expires. */ abstract public function set($type, $key, $value, $expire = null); /** * Delete a value from the data store. * * @param string $type The data type. * @param string $key The key. */ abstract public function delete($type, $key); /** * Clear any SSP specific state, such as SSP environmental variables or cached internals. * @return void */ public static function clearInternalState() { self::$instance = null; } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/0000755000000000000000000000000014042503475016540 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Auth/DefaultAuth.php0000644000000000000000000001065114042503475021462 0ustar rootrootinitLogin($return, $errorURL, $params); } /** * @deprecated This method will be removed in SSP 2.0. Please use * State::getPersistentAuthData() instead. * @param array &$state * @return array */ public static function extractPersistentAuthState(array &$state) { return State::getPersistentAuthData($state); } /** * @deprecated This method will be removed in SSP 2.0. Please use Source::loginCompleted() instead. * @param array $state * @return void */ public static function loginCompleted($state) { Source::loginCompleted($state); } /** * @deprecated This method will be removed in SSP 2.0. * @param string $returnURL * @param string $authority * @return void */ public static function initLogoutReturn($returnURL, $authority) { assert(is_string($returnURL)); assert(is_string($authority)); $session = Session::getSessionFromRequest(); $state = $session->getAuthData($authority, 'LogoutState'); $session->doLogout($authority); $state['\SimpleSAML\Auth\DefaultAuth.ReturnURL'] = $returnURL; $state['LogoutCompletedHandler'] = [get_class(), 'logoutCompleted']; $as = Source::getById($authority); if ($as === null) { // The authority wasn't an authentication source... self::logoutCompleted($state); } $as->logout($state); } /** * @deprecated This method will be removed in SSP 2.0. * @param string $returnURL * @param string $authority * @return void */ public static function initLogout($returnURL, $authority) { assert(is_string($returnURL)); assert(is_string($authority)); self::initLogoutReturn($returnURL, $authority); Utils\HTTP::redirectTrustedURL($returnURL); } /** * @deprecated This method will be removed in SSP 2.0. * @param array $state * @return void */ public static function logoutCompleted($state) { assert(is_array($state)); assert(array_key_exists('\SimpleSAML\Auth\DefaultAuth.ReturnURL', $state)); Utils\HTTP::redirectTrustedURL($state['\SimpleSAML\Auth\DefaultAuth.ReturnURL']); } /** * @deprecated This method will be removed in SSP 2.0. Please use Source::logoutCallback() instead. * @param array $state * @return void */ public static function logoutCallback($state) { Source::logoutCallback($state); } /** * @deprecated This method will be removed in SSP 2.0. Please use * \SimpleSAML\Module\saml\Auth\Source\SP::handleUnsolicitedAuth() instead. * @param string $authId * @param array $state * @param string $redirectTo * @return void */ public static function handleUnsolicitedAuth($authId, array $state, $redirectTo) { SP::handleUnsolicitedAuth($authId, $state, $redirectTo); } /** * Return an authentication source by ID. * * @param string $id The id of the authentication source. * @return Source The authentication source. * @throws \Exception If the $id does not correspond with an authentication source. */ private static function getAuthSource($id): Source { $as = Source::getById($id); if ($as === null) { throw new Exception('Invalid authentication source: ' . $id); } return $as; } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/State.php0000644000000000000000000003273514042503475020343 0ustar rootroot." or ":". * * There is also support for passing exceptions through the state. * By defining an exception handler when creating the state array, users of the state * array can call throwException with the state and the exception. This exception will * be passed to the handler defined by the EXCEPTION_HANDLER_URL or EXCEPTION_HANDLER_FUNC * elements of the state array. Note that internally this uses the request parameter name * defined in EXCEPTION_PARAM, which, for technical reasons, cannot contain a ".". * * @author Olav Morken, UNINETT AS. * @package SimpleSAMLphp */ class State { /** * The index in the state array which contains the identifier. */ public const ID = '\SimpleSAML\Auth\State.id'; /** * The index in the cloned state array which contains the identifier of the * original state. */ public const CLONE_ORIGINAL_ID = '\SimpleSAML\Auth\State.cloneOriginalId'; /** * The index in the state array which contains the current stage. */ public const STAGE = '\SimpleSAML\Auth\State.stage'; /** * The index in the state array which contains the restart URL. */ public const RESTART = '\SimpleSAML\Auth\State.restartURL'; /** * The index in the state array which contains the exception handler URL. */ public const EXCEPTION_HANDLER_URL = '\SimpleSAML\Auth\State.exceptionURL'; /** * The index in the state array which contains the exception handler function. */ public const EXCEPTION_HANDLER_FUNC = '\SimpleSAML\Auth\State.exceptionFunc'; /** * The index in the state array which contains the exception data. */ public const EXCEPTION_DATA = '\SimpleSAML\Auth\State.exceptionData'; /** * The stage of a state with an exception. */ public const EXCEPTION_STAGE = '\SimpleSAML\Auth\State.exceptionStage'; /** * The URL parameter which contains the exception state id. * Note that this does not contain a "." since it's used in the * _REQUEST superglobal that does not allow dots. */ public const EXCEPTION_PARAM = '\SimpleSAML\Auth\State_exceptionId'; /** * State timeout. */ private static $stateTimeout = null; /** * Get the persistent authentication state from the state array. * * @param array $state The state array to analyze. * * @return array The persistent authentication state. */ public static function getPersistentAuthData(array $state) { // save persistent authentication data $persistent = []; if (array_key_exists('PersistentAuthData', $state)) { foreach ($state['PersistentAuthData'] as $key) { if (isset($state[$key])) { $persistent[$key] = $state[$key]; } } } // add those that should always be included $mandatory = [ 'Attributes', 'Expire', 'LogoutState', 'AuthInstant', 'RememberMe', 'saml:sp:NameID' ]; foreach ($mandatory as $key) { if (isset($state[$key])) { $persistent[$key] = $state[$key]; } } return $persistent; } /** * Retrieve the ID of a state array. * * Note that this function will not save the state. * * @param array &$state The state array. * @param bool $rawId Return a raw ID, without a restart URL. Defaults to FALSE. * * @return string Identifier which can be used to retrieve the state later. */ public static function getStateId(&$state, $rawId = false) { assert(is_array($state)); assert(is_bool($rawId)); if (!array_key_exists(self::ID, $state)) { $state[self::ID] = Utils\Random::generateID(); } $id = $state[self::ID]; if ($rawId || !array_key_exists(self::RESTART, $state)) { // Either raw ID or no restart URL. In any case, return the raw ID. return $id; } // We have a restart URL. Return the ID with that URL. return $id . ':' . $state[self::RESTART]; } /** * Retrieve state timeout. * * @return integer State timeout. */ private static function getStateTimeout(): int { if (self::$stateTimeout === null) { $globalConfig = Configuration::getInstance(); self::$stateTimeout = $globalConfig->getInteger('session.state.timeout', 60 * 60); } return self::$stateTimeout; } /** * Save the state. * * This function saves the state, and returns an id which can be used to * retrieve it later. It will also update the $state array with the identifier. * * @param array &$state The login request state. * @param string $stage The current stage in the login process. * @param bool $rawId Return a raw ID, without a restart URL. * * @return string Identifier which can be used to retrieve the state later. */ public static function saveState(&$state, $stage, $rawId = false) { assert(is_array($state)); assert(is_string($stage)); assert(is_bool($rawId)); $return = self::getStateId($state, $rawId); $id = $state[self::ID]; // Save stage $state[self::STAGE] = $stage; // Save state $serializedState = serialize($state); $session = Session::getSessionFromRequest(); $session->setData('\SimpleSAML\Auth\State', $id, $serializedState, self::getStateTimeout()); Logger::debug('Saved state: ' . var_export($return, true)); return $return; } /** * Clone the state. * * This function clones and returns the new cloned state. * * @param array $state The original request state. * * @return array Cloned state data. */ public static function cloneState(array $state) { $clonedState = $state; if (array_key_exists(self::ID, $state)) { $clonedState[self::CLONE_ORIGINAL_ID] = $state[self::ID]; unset($clonedState[self::ID]); Logger::debug('Cloned state: ' . var_export($state[self::ID], true)); } else { Logger::debug('Cloned state with undefined id.'); } return $clonedState; } /** * Retrieve saved state. * * This function retrieves saved state information. If the state information has been lost, * it will attempt to restart the request by calling the restart URL which is embedded in the * state information. If there is no restart information available, an exception will be thrown. * * @param string $id State identifier (with embedded restart information). * @param string $stage The stage the state should have been saved in. * @param bool $allowMissing Whether to allow the state to be missing. * * @throws \SimpleSAML\Error\NoState If we couldn't find the state and there's no URL defined to redirect to. * @throws \Exception If the stage of the state is invalid and there's no URL defined to redirect to. * * @return array|null State information, or NULL if the state is missing and $allowMissing is true. */ public static function loadState($id, $stage, $allowMissing = false) { assert(is_string($id)); assert(is_string($stage)); assert(is_bool($allowMissing)); Logger::debug('Loading state: ' . var_export($id, true)); $sid = self::parseStateID($id); $session = Session::getSessionFromRequest(); $state = $session->getData('\SimpleSAML\Auth\State', $sid['id']); if ($state === null) { // Could not find saved data if ($allowMissing) { return null; } if ($sid['url'] === null) { throw new Error\NoState(); } Utils\HTTP::redirectUntrustedURL($sid['url']); } $state = unserialize($state); assert(is_array($state)); assert(array_key_exists(self::ID, $state)); assert(array_key_exists(self::STAGE, $state)); // Verify stage if ($state[self::STAGE] !== $stage) { /* This could be a user trying to bypass security, but most likely it is just * someone using the back-button in the browser. We try to restart the * request if that is possible. If not, show an error. */ $msg = 'Wrong stage in state. Was \'' . $state[self::STAGE] . '\', should be \'' . $stage . '\'.'; Logger::warning($msg); if ($sid['url'] === null) { throw new \Exception($msg); } Utils\HTTP::redirectUntrustedURL($sid['url']); } return $state; } /** * Delete state. * * This function deletes the given state to prevent the user from reusing it later. * * @param array &$state The state which should be deleted. * @return void */ public static function deleteState(&$state) { assert(is_array($state)); if (!array_key_exists(self::ID, $state)) { // This state hasn't been saved return; } Logger::debug('Deleting state: ' . var_export($state[self::ID], true)); $session = Session::getSessionFromRequest(); $session->deleteData('\SimpleSAML\Auth\State', $state[self::ID]); } /** * Throw exception to the state exception handler. * * @param array $state The state array. * @param \SimpleSAML\Error\Exception $exception The exception. * * @throws \SimpleSAML\Error\Exception If there is no exception handler defined, it will just throw the $exception. * @return void */ public static function throwException($state, Error\Exception $exception) { assert(is_array($state)); if (array_key_exists(self::EXCEPTION_HANDLER_URL, $state)) { // Save the exception $state[self::EXCEPTION_DATA] = $exception; $id = self::saveState($state, self::EXCEPTION_STAGE); // Redirect to the exception handler Utils\HTTP::redirectTrustedURL( $state[self::EXCEPTION_HANDLER_URL], [self::EXCEPTION_PARAM => $id] ); } elseif (array_key_exists(self::EXCEPTION_HANDLER_FUNC, $state)) { // Call the exception handler $func = $state[self::EXCEPTION_HANDLER_FUNC]; assert(is_callable($func)); call_user_func($func, $exception, $state); assert(false); } else { /* * No exception handler is defined for the current state. */ throw $exception; } throw new \Exception(); // This should never happen } /** * Retrieve an exception state. * * @param string|null $id The exception id. Can be NULL, in which case it will be retrieved from the request. * * @return array|null The state array with the exception, or NULL if no exception was thrown. */ public static function loadExceptionState($id = null) { assert(is_string($id) || $id === null); if ($id === null) { if (!array_key_exists(self::EXCEPTION_PARAM, $_REQUEST)) { // No exception return null; } $id = $_REQUEST[self::EXCEPTION_PARAM]; } /** @var array $state */ $state = self::loadState($id, self::EXCEPTION_STAGE); assert(array_key_exists(self::EXCEPTION_DATA, $state)); return $state; } /** * Get the ID and (optionally) a URL embedded in a StateID, in the form 'id:url'. * * @param string $stateId The state ID to use. * * @return array A hashed array with the ID and the URL (if any), in the 'id' and 'url' keys, respectively. If * there's no URL in the input parameter, NULL will be returned as the value for the 'url' key. * * @author Andreas Solberg, UNINETT AS * @author Jaime Perez, UNINETT AS */ public static function parseStateID($stateId) { $tmp = explode(':', $stateId, 2); $id = $tmp[0]; $url = null; if (count($tmp) === 2) { $url = $tmp[1]; } return ['id' => $id, 'url' => $url]; } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/Simple.php0000644000000000000000000003117014042503475020504 0ustar rootrootauthSource = $authSource; $this->app_config = $config->getConfigItem('application'); if ($session === null) { $session = Session::getSessionFromRequest(); } $this->session = $session; } /** * Retrieve the implementing authentication source. * * @return Source The authentication source. * * @throws \SimpleSAML\Error\AuthSource If the requested auth source is unknown. */ public function getAuthSource() { $as = Source::getById($this->authSource); if ($as === null) { throw new Error\AuthSource($this->authSource, 'Unknown authentication source.'); } return $as; } /** * Check if the user is authenticated. * * This function checks if the user is authenticated with the default authentication source selected by the * 'default-authsource' option in 'config.php'. * * @return bool True if the user is authenticated, false if not. */ public function isAuthenticated() { return $this->session->isValid($this->authSource); } /** * Require the user to be authenticated. * * If the user is authenticated, this function returns immediately. * * If the user isn't authenticated, this function will authenticate the user with the authentication source, and * then return the user to the current page. * * This function accepts an array $params, which controls some parts of the authentication. See the login() * method for a description. * * @param array $params Various options to the authentication request. See the documentation. * @return void */ public function requireAuth(array $params = []) { if ($this->session->isValid($this->authSource)) { // Already authenticated return; } $this->login($params); } /** * Start an authentication process. * * This function accepts an array $params, which controls some parts of the authentication. The accepted parameters * depends on the authentication source being used. Some parameters are generic: * - 'ErrorURL': A URL that should receive errors from the authentication. * - 'KeepPost': If the current request is a POST request, keep the POST data until after the authentication. * - 'ReturnTo': The URL the user should be returned to after authentication. * - 'ReturnCallback': The function we should call after the user has finished authentication. * * Please note: this function never returns. * * @param array $params Various options to the authentication request. * @return void */ public function login(array $params = []) { if (array_key_exists('KeepPost', $params)) { $keepPost = (bool) $params['KeepPost']; } else { $keepPost = true; } if (array_key_exists('ReturnTo', $params)) { $returnTo = (string) $params['ReturnTo']; } else { if (array_key_exists('ReturnCallback', $params)) { $returnTo = (array) $params['ReturnCallback']; } else { $returnTo = Utils\HTTP::getSelfURL(); } } if (is_string($returnTo) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') { $returnTo = Utils\HTTP::getPOSTRedirectURL($returnTo, $_POST); } if (array_key_exists('ErrorURL', $params)) { $errorURL = (string) $params['ErrorURL']; } else { $errorURL = null; } if (!isset($params[State::RESTART]) && is_string($returnTo)) { /* * A URL to restart the authentication, in case the user bookmarks * something, e.g. the discovery service page. */ $restartURL = $this->getLoginURL($returnTo); $params[State::RESTART] = $restartURL; } $as = $this->getAuthSource(); $as->initLogin($returnTo, $errorURL, $params); assert(false); } /** * Log the user out. * * This function logs the user out. It will never return. By default, it will cause a redirect to the current page * after logging the user out, but a different URL can be given with the $params parameter. * * Generic parameters are: * - 'ReturnTo': The URL the user should be returned to after logout. * - 'ReturnCallback': The function that should be called after logout. * - 'ReturnStateParam': The parameter we should return the state in when redirecting. * - 'ReturnStateStage': The stage the state array should be saved with. * * @param string|array|null $params Either the URL the user should be redirected to after logging out, or an array * with parameters for the logout. If this parameter is null, we will return to the current page. * @return void */ public function logout($params = null) { assert(is_array($params) || is_string($params) || $params === null); if ($params === null) { $params = Utils\HTTP::getSelfURL(); } if (is_string($params)) { $params = [ 'ReturnTo' => $params, ]; } assert(is_array($params)); assert(isset($params['ReturnTo']) || isset($params['ReturnCallback'])); if (isset($params['ReturnStateParam']) || isset($params['ReturnStateStage'])) { assert(isset($params['ReturnStateParam'], $params['ReturnStateStage'])); } if ($this->session->isValid($this->authSource)) { $state = $this->session->getAuthData($this->authSource, 'LogoutState'); if ($state !== null) { $params = array_merge($state, $params); } $this->session->doLogout($this->authSource); $params['LogoutCompletedHandler'] = [get_class(), 'logoutCompleted']; $as = Source::getById($this->authSource); if ($as !== null) { $as->logout($params); } } self::logoutCompleted($params); } /** * Called when logout operation completes. * * This function never returns. * * @param array $state The state after the logout. * @return void */ public static function logoutCompleted($state) { assert(is_array($state)); assert(isset($state['ReturnTo']) || isset($state['ReturnCallback'])); if (isset($state['ReturnCallback'])) { call_user_func($state['ReturnCallback'], $state); assert(false); } else { $params = []; if (isset($state['ReturnStateParam']) || isset($state['ReturnStateStage'])) { assert(isset($state['ReturnStateParam'], $state['ReturnStateStage'])); $stateID = State::saveState($state, $state['ReturnStateStage']); $params[$state['ReturnStateParam']] = $stateID; } Utils\HTTP::redirectTrustedURL($state['ReturnTo'], $params); } } /** * Retrieve attributes of the current user. * * This function will retrieve the attributes of the current user if the user is authenticated. If the user isn't * authenticated, it will return an empty array. * * @return array The users attributes. */ public function getAttributes() { if (!$this->isAuthenticated()) { // Not authenticated return []; } // Authenticated return $this->session->getAuthData($this->authSource, 'Attributes'); } /** * Retrieve authentication data. * * @param string $name The name of the parameter, e.g. 'Attributes', 'Expire' or 'saml:sp:IdP'. * * @return mixed|null The value of the parameter, or null if it isn't found or we are unauthenticated. */ public function getAuthData($name) { assert(is_string($name)); if (!$this->isAuthenticated()) { return null; } return $this->session->getAuthData($this->authSource, $name); } /** * Retrieve all authentication data. * * @return array|null All persistent authentication data, or null if we aren't authenticated. */ public function getAuthDataArray() { if (!$this->isAuthenticated()) { return null; } return $this->session->getAuthState($this->authSource); } /** * Retrieve a URL that can be used to log the user in. * * @param string|null $returnTo The page the user should be returned to afterwards. If this parameter is null, the * user will be returned to the current page. * * @return string A URL which is suitable for use in link-elements. */ public function getLoginURL($returnTo = null) { assert($returnTo === null || is_string($returnTo)); if ($returnTo === null) { $returnTo = Utils\HTTP::getSelfURL(); } $login = Module::getModuleURL('core/as_login.php', [ 'AuthId' => $this->authSource, 'ReturnTo' => $returnTo, ]); return $login; } /** * Retrieve a URL that can be used to log the user out. * * @param string|null $returnTo The page the user should be returned to afterwards. If this parameter is null, the * user will be returned to the current page. * * @return string A URL which is suitable for use in link-elements. */ public function getLogoutURL($returnTo = null) { assert($returnTo === null || is_string($returnTo)); if ($returnTo === null) { $returnTo = Utils\HTTP::getSelfURL(); } $logout = Module::getModuleURL('core/as_logout.php', [ 'AuthId' => $this->authSource, 'ReturnTo' => $returnTo, ]); return $logout; } /** * Process a URL and modify it according to the application/baseURL configuration option, if present. * * @param string|null $url The URL to process, or null if we want to use the current URL. Both partial and full * URLs can be used as a parameter. The maximum precedence is given to the application/baseURL configuration option, * then the URL specified (if it specifies scheme, host and port) and finally the environment observed in the * server. * * @return string The URL modified according to the precedence rules. */ protected function getProcessedURL($url = null) { if ($url === null) { $url = Utils\HTTP::getSelfURL(); } $scheme = parse_url($url, PHP_URL_SCHEME); $host = parse_url($url, PHP_URL_HOST) ? : Utils\HTTP::getSelfHost(); $port = parse_url($url, PHP_URL_PORT) ? : ( $scheme ? '' : ltrim(Utils\HTTP::getServerPort(), ':') ); $scheme = $scheme ? : (Utils\HTTP::getServerHTTPS() ? 'https' : 'http'); $path = parse_url($url, PHP_URL_PATH) ? : '/'; $query = parse_url($url, PHP_URL_QUERY) ? : ''; $fragment = parse_url($url, PHP_URL_FRAGMENT) ? : ''; $port = !empty($port) ? ':' . $port : ''; if (($scheme === 'http' && $port === ':80') || ($scheme === 'https' && $port === ':443')) { $port = ''; } /** @psalm-var \SimpleSAML\Configuration $this->app_config */ $base = trim($this->app_config->getString( 'baseURL', $scheme . '://' . $host . $port ), '/'); return $base . $path . ($query ? '?' . $query : '') . ($fragment ? '#' . $fragment : ''); } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/ProcessingFilter.php0000644000000000000000000000417414042503475022541 0ustar rootrootpriority = $config['%priority']; if (!is_int($this->priority)) { throw new \Exception('Invalid priority: ' . var_export($this->priority, true)); } unset($config['%priority']); } } /** * Process a request. * * When a filter returns from this function, it is assumed to have completed its task. * * @param array &$request The request we are currently processing. */ abstract public function process(&$request); } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/SourceFactory.php0000644000000000000000000000035514042503475022044 0ustar rootrootauthId = $info['AuthId']; } /** * Get sources of a specific type. * * @param string $type The type of the authentication source. * * @return Source[] Array of \SimpleSAML\Auth\Source objects of the specified type. * @throws \Exception If the authentication source is invalid. */ public static function getSourcesOfType($type) { assert(is_string($type)); $config = Configuration::getConfig('authsources.php'); $ret = []; $sources = $config->getOptions(); foreach ($sources as $id) { $source = $config->getArray($id); self::validateSource($source, $id); if ($source[0] !== $type) { continue; } $ret[] = self::parseAuthSource($id, $source); } return $ret; } /** * Retrieve the ID of this authentication source. * * @return string The ID of this authentication source. */ public function getAuthId() { return $this->authId; } /** * Process a request. * * If an authentication source returns from this function, it is assumed to have * authenticated the user, and should have set elements in $state with the attributes * of the user. * * If the authentication process requires additional steps which make it impossible to * complete before returning from this function, the authentication source should * save the state, and at a later stage, load the state, update it with the authentication * information about the user, and call completeAuth with the state array. * * @param array &$state Information about the current authentication. * @return void */ abstract public function authenticate(&$state); /** * Reauthenticate an user. * * This function is called by the IdP to give the authentication source a chance to * interact with the user even in the case when the user is already authenticated. * * @param array &$state Information about the current authentication. * @return void */ public function reauthenticate(array &$state) { assert(isset($state['ReturnCallback'])); // the default implementation just copies over the previous authentication data $session = Session::getSessionFromRequest(); $data = $session->getAuthState($this->authId); if ($data === null) { throw new Error\NoState(); } foreach ($data as $k => $v) { $state[$k] = $v; } } /** * Complete authentication. * * This function should be called if authentication has completed. It will never return, * except in the case of exceptions. Exceptions thrown from this page should not be caught, * but should instead be passed to the top-level exception handler. * * @param array &$state Information about the current authentication. * @return void */ public static function completeAuth(&$state) { assert(is_array($state)); assert(array_key_exists('LoginCompletedHandler', $state)); State::deleteState($state); $func = $state['LoginCompletedHandler']; assert(is_callable($func)); call_user_func($func, $state); assert(false); } /** * Start authentication. * * This method never returns. * * @param string|array $return The URL or function we should direct the user to after authentication. If using a * URL obtained from user input, please make sure to check it by calling \SimpleSAML\Utils\HTTP::checkURLAllowed(). * @param string|null $errorURL The URL we should direct the user to after failed authentication. Can be null, in * which case a standard error page will be shown. If using a URL obtained from user input, please make sure to * check it by calling \SimpleSAML\Utils\HTTP::checkURLAllowed(). * @param array $params Extra information about the login. Different authentication requestors may provide different * information. Optional, will default to an empty array. * @return void */ public function initLogin($return, $errorURL = null, array $params = []) { assert(is_string($return) || is_array($return)); assert(is_string($errorURL) || $errorURL === null); $state = array_merge($params, [ '\SimpleSAML\Auth\DefaultAuth.id' => $this->authId, // TODO: remove in 2.0 '\SimpleSAML\Auth\Source.id' => $this->authId, '\SimpleSAML\Auth\DefaultAuth.Return' => $return, // TODO: remove in 2.0 '\SimpleSAML\Auth\Source.Return' => $return, '\SimpleSAML\Auth\DefaultAuth.ErrorURL' => $errorURL, // TODO: remove in 2.0 '\SimpleSAML\Auth\Source.ErrorURL' => $errorURL, 'LoginCompletedHandler' => [get_class(), 'loginCompleted'], 'LogoutCallback' => [get_class(), 'logoutCallback'], 'LogoutCallbackState' => [ '\SimpleSAML\Auth\DefaultAuth.logoutSource' => $this->authId, // TODO: remove in 2.0 '\SimpleSAML\Auth\Source.logoutSource' => $this->authId, ], ]); if (is_string($return)) { $state['\SimpleSAML\Auth\DefaultAuth.ReturnURL'] = $return; // TODO: remove in 2.0 $state['\SimpleSAML\Auth\Source.ReturnURL'] = $return; } if ($errorURL !== null) { $state[State::EXCEPTION_HANDLER_URL] = $errorURL; } try { $this->authenticate($state); } catch (Error\Exception $e) { State::throwException($state, $e); } catch (\Exception $e) { $e = new Error\UnserializableException($e); State::throwException($state, $e); } self::loginCompleted($state); } /** * Called when a login operation has finished. * * This method never returns. * * @param array $state The state after the login has completed. * @return void */ public static function loginCompleted($state) { assert(is_array($state)); assert(array_key_exists('\SimpleSAML\Auth\Source.Return', $state)); assert(array_key_exists('\SimpleSAML\Auth\Source.id', $state)); assert(array_key_exists('Attributes', $state)); assert(!array_key_exists('LogoutState', $state) || is_array($state['LogoutState'])); $return = $state['\SimpleSAML\Auth\Source.Return']; // save session state $session = Session::getSessionFromRequest(); $authId = $state['\SimpleSAML\Auth\Source.id']; $session->doLogin($authId, State::getPersistentAuthData($state)); if (is_string($return)) { // redirect... Utils\HTTP::redirectTrustedURL($return); } else { call_user_func($return, $state); } assert(false); } /** * Log out from this authentication source. * * This function should be overridden if the authentication source requires special * steps to complete a logout operation. * * If the logout process requires a redirect, the state should be saved. Once the * logout operation is completed, the state should be restored, and completeLogout * should be called with the state. If this operation can be completed without * showing the user a page, or redirecting, this function should return. * * @param array &$state Information about the current logout operation. * @return void */ public function logout(&$state) { assert(is_array($state)); // default logout handler which doesn't do anything } /** * Complete logout. * * This function should be called after logout has completed. It will never return, * except in the case of exceptions. Exceptions thrown from this page should not be caught, * but should instead be passed to the top-level exception handler. * * @param array &$state Information about the current authentication. * @return void */ public static function completeLogout(&$state) { assert(is_array($state)); assert(array_key_exists('LogoutCompletedHandler', $state)); State::deleteState($state); $func = $state['LogoutCompletedHandler']; assert(is_callable($func)); call_user_func($func, $state); assert(false); } /** * Create authentication source object from configuration array. * * This function takes an array with the configuration for an authentication source object, * and returns the object. * * @param string $authId The authentication source identifier. * @param array $config The configuration. * * @return \SimpleSAML\Auth\Source The parsed authentication source. * @throws \Exception If the authentication source is invalid. */ private static function parseAuthSource(string $authId, array $config): Source { self::validateSource($config, $authId); $id = $config[0]; $info = ['AuthId' => $authId]; $authSource = null; unset($config[0]); try { // Check whether or not there's a factory responsible for instantiating our Auth Source instance $factoryClass = Module::resolveClass( $id, 'Auth\Source\Factory', '\SimpleSAML\Auth\SourceFactory' ); /** @var SourceFactory $factory */ $factory = new $factoryClass(); $authSource = $factory->create($info, $config); } catch (\Exception $e) { // If not, instantiate the Auth Source here $className = Module::resolveClass($id, 'Auth\Source', '\SimpleSAML\Auth\Source'); $authSource = new $className($info, $config); } /** @var \SimpleSAML\Auth\Source */ return $authSource; } /** * Retrieve authentication source. * * This function takes an id of an authentication source, and returns the * AuthSource object. If no authentication source with the given id can be found, * NULL will be returned. * * If the $type parameter is specified, this function will return an * authentication source of the given type. If no authentication source or if an * authentication source of a different type is found, an exception will be thrown. * * @param string $authId The authentication source identifier. * @param string|null $type The type of authentication source. If NULL, any type will be accepted. * * @return \SimpleSAML\Auth\Source|null The AuthSource object, or NULL if no authentication * source with the given identifier is found. * @throws \SimpleSAML\Error\Exception If no such authentication source is found or it is invalid. */ public static function getById($authId, $type = null) { assert(is_string($authId)); assert($type === null || is_string($type)); // for now - load and parse config file $config = Configuration::getConfig('authsources.php'); $authConfig = $config->getArray($authId, null); if ($authConfig === null) { if ($type !== null) { throw new Error\Exception( 'No authentication source with id ' . var_export($authId, true) . ' found.' ); } return null; } $ret = self::parseAuthSource($authId, $authConfig); if ($type === null || $ret instanceof $type) { return $ret; } // the authentication source doesn't have the correct type throw new Error\Exception( 'Invalid type of authentication source ' . var_export($authId, true) . '. Was ' . var_export(get_class($ret), true) . ', should be ' . var_export($type, true) . '.' ); } /** * Called when the authentication source receives an external logout request. * * @param array $state State array for the logout operation. * @return void */ public static function logoutCallback($state) { assert(is_array($state)); assert(array_key_exists('\SimpleSAML\Auth\Source.logoutSource', $state)); $source = $state['\SimpleSAML\Auth\Source.logoutSource']; $session = Session::getSessionFromRequest(); if (!$session->isValid($source)) { Logger::warning( 'Received logout from an invalid authentication source ' . var_export($source, true) ); return; } $session->doLogout($source); } /** * Add a logout callback association. * * This function adds a logout callback association, which allows us to initiate * a logout later based on the $assoc-value. * * Note that logout-associations exists per authentication source. A logout association * from one authentication source cannot be called from a different authentication source. * * @param string $assoc The identifier for this logout association. * @param array $state The state array passed to the authenticate-function. * @return void */ protected function addLogoutCallback($assoc, $state) { assert(is_string($assoc)); assert(is_array($state)); if (!array_key_exists('LogoutCallback', $state)) { // the authentication requester doesn't have a logout callback return; } $callback = $state['LogoutCallback']; if (array_key_exists('LogoutCallbackState', $state)) { $callbackState = $state['LogoutCallbackState']; } else { $callbackState = []; } $id = strlen($this->authId) . ':' . $this->authId . $assoc; $data = [ 'callback' => $callback, 'state' => $callbackState, ]; $session = Session::getSessionFromRequest(); $session->setData( '\SimpleSAML\Auth\Source.LogoutCallbacks', $id, $data, Session::DATA_TIMEOUT_SESSION_END ); } /** * Call a logout callback based on association. * * This function calls a logout callback based on an association saved with * addLogoutCallback(...). * * This function always returns. * * @param string $assoc The logout association which should be called. * @return void */ protected function callLogoutCallback($assoc) { assert(is_string($assoc)); $id = strlen($this->authId) . ':' . $this->authId . $assoc; $session = Session::getSessionFromRequest(); $data = $session->getData('\SimpleSAML\Auth\Source.LogoutCallbacks', $id); if ($data === null) { // FIXME: fix for IdP-first flow (issue 397) -> reevaluate logout callback infrastructure $session->doLogout($this->authId); return; } assert(is_array($data)); assert(array_key_exists('callback', $data)); assert(array_key_exists('state', $data)); $callback = $data['callback']; $callbackState = $data['state']; $session->deleteData('\SimpleSAML\Auth\Source.LogoutCallbacks', $id); call_user_func($callback, $callbackState); } /** * Retrieve list of authentication sources. * * @return array The id of all authentication sources. */ public static function getSources() { $config = Configuration::getOptionalConfig('authsources.php'); return $config->getOptions(); } /** * Make sure that the first element of an auth source is its identifier. * * @param array $source An array with the auth source configuration. * @param string $id The auth source identifier. * * @throws \Exception If the first element of $source is not an identifier for the auth source. * @return void */ protected static function validateSource($source, $id) { if (!array_key_exists(0, $source) || !is_string($source[0])) { throw new \Exception( 'Invalid authentication source \'' . $id . '\': First element must be a string which identifies the authentication source.' ); } } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/ProcessingChain.php0000644000000000000000000003106314042503475022333 0ustar rootrootfilters = []; $config = Configuration::getInstance(); $configauthproc = $config->getArray('authproc.' . $mode, null); if (!empty($configauthproc)) { $configfilters = self::parseFilterList($configauthproc); self::addFilters($this->filters, $configfilters); } if (array_key_exists('authproc', $idpMetadata)) { $idpFilters = self::parseFilterList($idpMetadata['authproc']); self::addFilters($this->filters, $idpFilters); } if (array_key_exists('authproc', $spMetadata)) { $spFilters = self::parseFilterList($spMetadata['authproc']); self::addFilters($this->filters, $spFilters); } Logger::debug('Filter config for ' . $idpMetadata['entityid'] . '->' . $spMetadata['entityid'] . ': ' . str_replace("\n", '', var_export($this->filters, true))); } /** * Sort & merge filter configuration * * Inserts unsorted filters into sorted filter list. This sort operation is stable. * * @param array &$target Target filter list. This list must be sorted. * @param array $src Source filters. May be unsorted. * @return void */ private static function addFilters(array &$target, array $src): void { foreach ($src as $filter) { $fp = $filter->priority; // Find insertion position for filter for ($i = count($target) - 1; $i >= 0; $i--) { if ($target[$i]->priority <= $fp) { // The new filter should be inserted after this one break; } } /* $i now points to the filter which should preceede the current filter. */ array_splice($target, $i + 1, 0, [$filter]); } } /** * Parse an array of authentication processing filters. * * @param array $filterSrc Array with filter configuration. * @return array Array of ProcessingFilter objects. */ private static function parseFilterList(array $filterSrc): array { $parsedFilters = []; foreach ($filterSrc as $priority => $filter) { if (is_string($filter)) { $filter = ['class' => $filter]; } if (!is_array($filter)) { throw new \Exception('Invalid authentication processing filter configuration: ' . 'One of the filters wasn\'t a string or an array.'); } $parsedFilters[] = self::parseFilter($filter, $priority); } return $parsedFilters; } /** * Parse an authentication processing filter. * * @param array $config Array with the authentication processing filter configuration. * @param int $priority The priority of the current filter, (not included in the filter * definition.) * @return \SimpleSAML\Auth\ProcessingFilter The parsed filter. */ private static function parseFilter(array $config, int $priority): ProcessingFilter { if (!array_key_exists('class', $config)) { throw new \Exception('Authentication processing filter without name given.'); } $className = Module::resolveClass( $config['class'], 'Auth\Process', '\SimpleSAML\Auth\ProcessingFilter' ); $config['%priority'] = $priority; unset($config['class']); /** @var \SimpleSAML\Auth\ProcessingFilter */ return new $className($config, null); } /** * Process the given state. * * This function will only return if processing completes. If processing requires showing * a page to the user, we will not be able to return from this function. There are two ways * this can be handled: * - Redirect to a URL: We will redirect to the URL set in $state['ReturnURL']. * - Call a function: We will call the function set in $state['ReturnCall']. * * If an exception is thrown during processing, it should be handled by the caller of * this function. If the user has redirected to a different page, the exception will be * returned through the exception handler defined on the state array. See * State for more information. * * @see State * @see State::EXCEPTION_HANDLER_URL * @see State::EXCEPTION_HANDLER_FUNC * * @param array &$state The state we are processing. * @throws \SimpleSAML\Error\Exception * @throws \SimpleSAML\Error\UnserializableException * @return void */ public function processState(&$state) { assert(is_array($state)); assert(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state)); assert(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state)); $state[self::FILTERS_INDEX] = $this->filters; try { // TODO: remove this in SSP 2.0 if (!array_key_exists('UserID', $state)) { // No unique user ID present. Attempt to add one. self::addUserID($state); } while (count($state[self::FILTERS_INDEX]) > 0) { $filter = array_shift($state[self::FILTERS_INDEX]); $filter->process($state); } } catch (Error\Exception $e) { // No need to convert the exception throw $e; } catch (\Exception $e) { /* * To be consistent with the exception we return after an redirect, * we convert this exception before returning it. */ throw new Error\UnserializableException($e); } // Completed } /** * Continues processing of the state. * * This function is used to resume processing by filters which for example needed to show * a page to the user. * * This function will never return. Exceptions thrown during processing will be passed * to whatever exception handler is defined in the state array. * * @param array $state The state we are processing. * @return void */ public static function resumeProcessing($state) { assert(is_array($state)); while (count($state[self::FILTERS_INDEX]) > 0) { $filter = array_shift($state[self::FILTERS_INDEX]); try { $filter->process($state); } catch (Error\Exception $e) { State::throwException($state, $e); } catch (\Exception $e) { $e = new Error\UnserializableException($e); State::throwException($state, $e); } } // Completed assert(array_key_exists('ReturnURL', $state) || array_key_exists('ReturnCall', $state)); assert(!array_key_exists('ReturnURL', $state) || !array_key_exists('ReturnCall', $state)); if (array_key_exists('ReturnURL', $state)) { /* * Save state information, and redirect to the URL specified * in $state['ReturnURL']. */ $id = State::saveState($state, self::COMPLETED_STAGE); Utils\HTTP::redirectTrustedURL($state['ReturnURL'], [self::AUTHPARAM => $id]); } else { /* Pass the state to the function defined in $state['ReturnCall']. */ // We are done with the state array in the session. Delete it. State::deleteState($state); $func = $state['ReturnCall']; assert(is_callable($func)); call_user_func($func, $state); assert(false); } } /** * Process the given state passivly. * * Modules with user interaction are expected to throw an \SimpleSAML\Module\saml\Error\NoPassive exception * which are silently ignored. Exceptions of other types are passed further up the call stack. * * This function will only return if processing completes. * * @param array &$state The state we are processing. * @return void */ public function processStatePassive(&$state) { assert(is_array($state)); // Should not be set when calling this method assert(!array_key_exists('ReturnURL', $state)); // Notify filters about passive request $state['isPassive'] = true; $state[self::FILTERS_INDEX] = $this->filters; // TODO: remove this in SSP 2.0 if (!array_key_exists('UserID', $state)) { // No unique user ID present. Attempt to add one. self::addUserID($state); } while (count($state[self::FILTERS_INDEX]) > 0) { $filter = array_shift($state[self::FILTERS_INDEX]); try { $filter->process($state); } catch (Error\NoPassive $e) { // @deprecated will be removed in 2.0 // Ignore \SimpleSAML\Error\NoPassive exceptions } catch (Module\saml\Error\NoPassive $e) { // Ignore \SimpleSAML\Module\saml\Error\NoPassive exceptions } } } /** * Retrieve a state which has finished processing. * * @param string $id The state identifier. * @see State::parseStateID() * @return array|null The state referenced by the $id parameter. */ public static function fetchProcessedState($id) { assert(is_string($id)); return State::loadState($id, self::COMPLETED_STAGE); } /** * @deprecated This method will be removed in SSP 2.0. * @param array &$state * @return void */ private static function addUserID(array &$state): void { assert(array_key_exists('Attributes', $state)); if (isset($state['Destination']['userid.attribute'])) { $attributeName = $state['Destination']['userid.attribute']; Logger::debug("The 'userid.attribute' option has been deprecated."); } elseif (isset($state['Source']['userid.attribute'])) { $attributeName = $state['Source']['userid.attribute']; Logger::debug("The 'userid.attribute' option has been deprecated."); } else { // Default attribute $attributeName = 'eduPersonPrincipalName'; } if (!array_key_exists($attributeName, $state['Attributes'])) { return; } $uid = $state['Attributes'][$attributeName]; if (count($uid) === 0) { Logger::warning('Empty user id attribute [' . $attributeName . '].'); return; } if (count($uid) > 1) { Logger::warning('Multiple attribute values for user id attribute [' . $attributeName . '].'); return; } // TODO: the attribute value should be trimmed $uid = $uid[0]; if (empty($uid)) { Logger::warning('Empty value in attribute ' . $attributeName . ". on user. Cannot set UserID."); return; } $state['UserID'] = $uid; } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/LDAP.php0000644000000000000000000000074514042503475017777 0ustar rootrootsecretSalt = $secretSalt; $this->lifetime = $lifetime; $this->skew = $skew; $this->algo = $algo; } /** * Add some given data to the current token. This data will be needed later too for token validation. * * This mechanism can be used to provide context for a token, such as a user identifier of the only subject * authorised to use it. Note also that multiple data can be added to the token. This means that upon validation, * not only the same data must be added, but also in the same order. * * @param string $data The data to incorporate into the current token. * @return void */ public function addVerificationData($data) { $this->secretSalt .= '|' . $data; } /** * Calculates a token value for a given offset. * * @param int $offset The offset to use. * @param int|null $time The time stamp to which the offset is relative to. Defaults to the current time. * * @return string The token for the given time and offset. */ private function calculateTokenValue(int $offset, int $time = null): string { if ($time === null) { $time = time(); } // a secret salt that should be randomly generated for each installation return hash( $this->algo, $offset . ':' . floor(($time - $offset) / ($this->lifetime + $this->skew)) . ':' . $this->secretSalt ); } /** * Generates a token that contains an offset and a token value, using the current offset. * * @return string A time-limited token with the offset respect to the beginning of its time slot prepended. */ public function generate() { $time = time(); $current_offset = ($time - $this->skew) % ($this->lifetime + $this->skew); return dechex($current_offset) . '-' . $this->calculateTokenValue($current_offset, $time); } /** * @see generate * @deprecated This method will be removed in SSP 2.0. Use generate() instead. * @return string */ public function generate_token() { return $this->generate(); } /** * Validates a token by calculating the token value for the provided offset and comparing it. * * @param string $token The token to validate. * * @return bool True if the given token is currently valid, false otherwise. */ public function validate($token) { $splittoken = explode('-', $token); if (count($splittoken) !== 2) { return false; } $offset = intval(hexdec($splittoken[0])); $value = $splittoken[1]; return ($this->calculateTokenValue($offset) === $value); } /** * @see validate * @deprecated This method will be removed in SSP 2.0. Use validate() instead. * @param string $token * @return bool */ public function validate_token($token) { return $this->validate($token); } } simplesamlphp-1.19.1/lib/SimpleSAML/Auth/AuthenticationFactory.php0000644000000000000000000000164714042503475023570 0ustar rootrootconfig = $config; $this->session = $session; } /** * Create a new instance of \SimpleSAML\Auth\Simple for the given authentication source. * * @param string $as The identifier of the authentication source, as indexed in the authsources.php configuration * file. * * @return \SimpleSAML\Auth\Simple */ public function create($as) { return new Simple($as, $this->config, $this->session); } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/0000755000000000000000000000000014042503475017357 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Metadata/Sources/0000755000000000000000000000000014042503475021002 5ustar rootrootsimplesamlphp-1.19.1/lib/SimpleSAML/Metadata/Sources/MDQ.php0000644000000000000000000003062514042503475022142 0ustar rootrootserver = $config['server']; } if (array_key_exists('validateFingerprint', $config)) { $this->validateFingerprint = $config['validateFingerprint']; } else { $this->validateFingerprint = null; } if (isset($config['validateFingerprintAlgorithm'])) { $this->validateFingerprintAlgorithm = $config['validateFingerprintAlgorithm']; } else { $this->validateFingerprintAlgorithm = XMLSecurityDSig::SHA1; } if (array_key_exists('cachedir', $config)) { $globalConfig = Configuration::getInstance(); $this->cacheDir = $globalConfig->resolvePath($config['cachedir']); } else { $this->cacheDir = null; } if (array_key_exists('cachelength', $config)) { $this->cacheLength = $config['cachelength']; } else { $this->cacheLength = 86400; } } /** * This function is not implemented. * * @param string $set The set we want to list metadata for. * * @return array An empty array. */ public function getMetadataSet($set) { // we don't have this metadata set return []; } /** * Find the cache file name for an entity, * * @param string $set The metadata set this entity belongs to. * @param string $entityId The entity id of this entity. * * @return string The full path to the cache file. */ private function getCacheFilename(string $set, string $entityId): string { if ($this->cacheDir === null) { throw new Error\ConfigurationError("Missing cache directory configuration."); } $cachekey = sha1($entityId); return $this->cacheDir . '/' . $set . '-' . $cachekey . '.cached.xml'; } /** * Load a entity from the cache. * * @param string $set The metadata set this entity belongs to. * @param string $entityId The entity id of this entity. * * @return array|NULL The associative array with the metadata for this entity, or NULL * if the entity could not be found. * @throws \Exception If an error occurs while loading metadata from cache. */ private function getFromCache(string $set, string $entityId): ?array { if (empty($this->cacheDir)) { return null; } $cachefilename = $this->getCacheFilename($set, $entityId); if (!file_exists($cachefilename)) { return null; } if (!is_readable($cachefilename)) { throw new Exception(__CLASS__ . ': could not read cache file for entity [' . $cachefilename . ']'); } Logger::debug(__CLASS__ . ': reading cache [' . $entityId . '] => [' . $cachefilename . ']'); /* Ensure that this metadata isn't older that the cachelength option allows. This * must be verified based on the file, since this option may be changed after the * file is written. */ $stat = stat($cachefilename); if ($stat['mtime'] + $this->cacheLength <= time()) { Logger::debug(__CLASS__ . ': cache file older that the cachelength option allows.'); return null; } $rawData = file_get_contents($cachefilename); if (empty($rawData)) { /** @var array $error */ $error = error_get_last(); throw new Exception( __CLASS__ . ': error reading metadata from cache file "' . $cachefilename . '": ' . $error['message'] ); } $data = unserialize($rawData); if ($data === false) { throw new Exception(__CLASS__ . ': error unserializing cached data from file "' . $cachefilename . '".'); } if (!is_array($data)) { throw new Exception(__CLASS__ . ': Cached metadata from "' . $cachefilename . '" wasn\'t an array.'); } return $data; } /** * Save a entity to the cache. * * @param string $set The metadata set this entity belongs to. * @param string $entityId The entity id of this entity. * @param array $data The associative array with the metadata for this entity. * * @throws \Exception If metadata cannot be written to cache. * @return void */ private function writeToCache(string $set, string $entityId, array $data): void { if (empty($this->cacheDir)) { return; } $cachefilename = $this->getCacheFilename($set, $entityId); if (!is_writable(dirname($cachefilename))) { throw new \Exception(__CLASS__ . ': could not write cache file for entity [' . $cachefilename . ']'); } Logger::debug(__CLASS__ . ': Writing cache [' . $entityId . '] => [' . $cachefilename . ']'); file_put_contents($cachefilename, serialize($data)); } /** * Retrieve metadata for the correct set from a SAML2Parser. * * @param \SimpleSAML\Metadata\SAMLParser $entity A SAML2Parser representing an entity. * @param string $set The metadata set we are looking for. * * @return array|NULL The associative array with the metadata, or NULL if no metadata for * the given set was found. */ private static function getParsedSet(SAMLParser $entity, string $set): ?array { switch ($set) { case 'saml20-idp-remote': return $entity->getMetadata20IdP(); case 'saml20-sp-remote': return $entity->getMetadata20SP(); case 'shib13-idp-remote': return $entity->getMetadata1xIdP(); case 'shib13-sp-remote': return $entity->getMetadata1xSP(); case 'attributeauthority-remote': return $entity->getAttributeAuthorities(); default: Logger::warning(__CLASS__ . ': unknown metadata set: \'' . $set . '\'.'); } return null; } /** * Overriding this function from the superclass \SimpleSAML\Metadata\MetaDataStorageSource. * * This function retrieves metadata for the given entity id in the given set of metadata. * It will return NULL if it is unable to locate the metadata. * * This class implements this function using the getMetadataSet-function. A subclass should * override this function if it doesn't implement the getMetadataSet function, or if the * implementation of getMetadataSet is slow. * * @param string $index The entityId or metaindex we are looking up. * @param string $set The set we are looking for metadata in. * * @return array|null An associative array with metadata for the given entity, or NULL if we are unable to * locate the entity. * @throws \Exception If an error occurs while validating the signature or the metadata is in an * incorrect set. */ public function getMetaData($index, $set) { assert(is_string($index)); assert(is_string($set)); Logger::info(__CLASS__ . ': loading metadata entity [' . $index . '] from [' . $set . ']'); // read from cache if possible try { $data = $this->getFromCache($set, $index); } catch (\Exception $e) { Logger::error($e->getMessage()); // proceed with fetching metadata even if the cache is broken $data = null; } if ($data !== null && array_key_exists('expires', $data) && $data['expires'] < time()) { // metadata has expired $data = null; } if (isset($data)) { // metadata found in cache and not expired Logger::debug(__CLASS__ . ': using cached metadata for: ' . $index . '.'); return $data; } // look at Metadata Query Protocol: https://github.com/iay/md-query/blob/master/draft-young-md-query.txt $mdq_url = $this->server . '/entities/' . urlencode($index); Logger::debug(__CLASS__ . ': downloading metadata for "' . $index . '" from [' . $mdq_url . ']'); try { $xmldata = Utils\HTTP::fetch($mdq_url); } catch (\Exception $e) { // Avoid propagating the exception, make sure we can handle the error later $xmldata = false; } if (empty($xmldata)) { $error = error_get_last(); Logger::info('Unable to fetch metadata for "' . $index . '" from ' . $mdq_url . ': ' . (is_array($error) ? $error['message'] : 'no error available')); return null; } /** @var string $xmldata */ $entity = SAMLParser::parseString($xmldata); Logger::debug(__CLASS__ . ': completed parsing of [' . $mdq_url . ']'); if ($this->validateFingerprint !== null) { if ( !$entity->validateFingerprint( $this->validateFingerprint, $this->validateFingerprintAlgorithm ) ) { throw new \Exception(__CLASS__ . ': error, could not verify signature for entity: ' . $index . '".'); } } $data = self::getParsedSet($entity, $set); if ($data === null) { throw new \Exception(__CLASS__ . ': no metadata for set "' . $set . '" available from "' . $index . '".'); } try { $this->writeToCache($set, $index, $data); } catch (\Exception $e) { // Proceed without writing to cache Logger::error('Error writing MDQ result to cache: ' . $e->getMessage()); } return $data; } /** * This function loads the metadata for entity IDs in $entityIds. It is returned as an associative array * where the key is the entity id. An empty array may be returned if no matching entities were found * @param array $entityIds The entity ids to load * @param string $set The set we want to get metadata from. * @return array An associative array with the metadata for the requested entities, if found. */ public function getMetaDataForEntities(array $entityIds, $set) { return $this->getMetaDataForEntitiesIndividually($entityIds, $set); } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/SAMLBuilder.php0000644000000000000000000007045214042503475022143 0ustar rootrootmaxCache = $maxCache; $this->maxDuration = $maxDuration; $this->entityDescriptor = new EntityDescriptor(); $this->entityDescriptor->setEntityID($entityId); } /** * @param array $metadata * @return void */ private function setExpiration(array $metadata): void { if (array_key_exists('expire', $metadata)) { if ($metadata['expire'] - time() < $this->maxDuration) { $this->maxDuration = $metadata['expire'] - time(); } } if ($this->maxCache !== null) { $this->entityDescriptor->setCacheDuration('PT' . $this->maxCache . 'S'); } if ($this->maxDuration !== null) { $this->entityDescriptor->setValidUntil(time() + $this->maxDuration); } } /** * Retrieve the EntityDescriptor element which is generated for this entity. * * @return \DOMElement The EntityDescriptor element of this entity. */ public function getEntityDescriptor() { $xml = $this->entityDescriptor->toXML(); $xml->ownerDocument->appendChild($xml); return $xml; } /** * Retrieve the EntityDescriptor as text. * * This function serializes this EntityDescriptor, and returns it as text. * * @param bool $formatted Whether the returned EntityDescriptor should be formatted first. * * @return string The serialized EntityDescriptor. */ public function getEntityDescriptorText($formatted = true) { assert(is_bool($formatted)); $xml = $this->getEntityDescriptor(); if ($formatted) { Utils\XML::formatDOMElement($xml); } return $xml->ownerDocument->saveXML(); } /** * Add a SecurityTokenServiceType for ADFS metadata. * * @param array $metadata The metadata with the information about the SecurityTokenServiceType. * @return void */ public function addSecurityTokenServiceType($metadata) { assert(is_array($metadata)); assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $defaultEndpoint = $metadata->getDefaultEndpoint('SingleSignOnService'); /** * @psalm-var \SAML2\XML\md\RoleDescriptor $e * @psalm-suppress UndefinedClass */ $e = new SecurityTokenServiceType(); $e->setLocation($defaultEndpoint['Location']); $this->addCertificate($e, $metadata); $this->entityDescriptor->addRoleDescriptor($e); } /** * Add extensions to the metadata. * * @param \SimpleSAML\Configuration $metadata The metadata to get extensions from. * @param \SAML2\XML\md\RoleDescriptor $e Reference to the element where the Extensions element should be included. * @return void */ private function addExtensions(Configuration $metadata, RoleDescriptor $e): void { if ($metadata->hasValue('tags')) { $a = new Attribute(); $a->setName('tags'); foreach ($metadata->getArray('tags') as $tag) { $a->addAttributeValue(new AttributeValue($tag)); } $e->setExtensions(array_merge($e->getExtensions(), [$a])); } if ($metadata->hasValue('hint.cidr')) { $a = new Attribute(); $a->setName('hint.cidr'); foreach ($metadata->getArray('hint.cidr') as $hint) { $a->addAttributeValue(new AttributeValue($hint)); } $e->setExtensions(array_merge($e->getExtensions(), [$a])); } if ($metadata->hasValue('scope')) { foreach ($metadata->getArray('scope') as $scopetext) { $s = new Scope(); $s->setScope($scopetext); // Check whether $ ^ ( ) * | \ are in a scope -> assume regex. if (1 === preg_match('/[\$\^\)\(\*\|\\\\]/', $scopetext)) { $s->setIsRegexpScope(true); } else { $s->setIsRegexpScope(false); } $e->setExtensions(array_merge($e->getExtensions(), [$s])); } } if ($metadata->hasValue('EntityAttributes')) { $ea = new EntityAttributes(); foreach ($metadata->getArray('EntityAttributes') as $attributeName => $attributeValues) { $a = new Attribute(); $a->setName($attributeName); $a->setNameFormat('urn:oasis:names:tc:SAML:2.0:attrname-format:uri'); // Attribute names that is not URI is prefixed as this: '{nameformat}name' if (preg_match('/^\{(.*?)\}(.*)$/', $attributeName, $matches)) { $a->setName($matches[2]); $nameFormat = $matches[1]; if ($nameFormat !== Constants::NAMEFORMAT_UNSPECIFIED) { $a->setNameFormat($nameFormat); } } foreach ($attributeValues as $attributeValue) { $a->addAttributeValue(new AttributeValue($attributeValue)); } $ea->addChildren($a); } $this->entityDescriptor->setExtensions( array_merge($this->entityDescriptor->getExtensions(), [$ea]) ); } if ($metadata->hasValue('RegistrationInfo')) { $ri = new RegistrationInfo(); foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) { switch ($riName) { case 'authority': $ri->setRegistrationAuthority($riValues); break; case 'instant': $ri->setRegistrationInstant(\SAML2\Utils::xsDateTimeToTimestamp($riValues)); break; case 'policies': $ri->setRegistrationPolicy($riValues); break; } } $this->entityDescriptor->setExtensions( array_merge($this->entityDescriptor->getExtensions(), [$ri]) ); } if ($metadata->hasValue('UIInfo')) { $ui = new UIInfo(); foreach ($metadata->getArray('UIInfo') as $uiName => $uiValues) { switch ($uiName) { case 'DisplayName': $ui->setDisplayName($uiValues); break; case 'Description': $ui->setDescription($uiValues); break; case 'InformationURL': $ui->setInformationURL($uiValues); break; case 'PrivacyStatementURL': $ui->setPrivacyStatementURL($uiValues); break; case 'Keywords': foreach ($uiValues as $lang => $keywords) { $uiItem = new Keywords(); $uiItem->setLanguage($lang); $uiItem->setKeywords($keywords); $ui->addKeyword($uiItem); } break; case 'Logo': foreach ($uiValues as $logo) { $uiItem = new Logo(); $uiItem->setUrl($logo['url']); $uiItem->setWidth($logo['width']); $uiItem->setHeight($logo['height']); if (isset($logo['lang'])) { $uiItem->setLanguage($logo['lang']); } $ui->addLogo($uiItem); } break; } } $e->setExtensions(array_merge($e->getExtensions(), [$ui])); } if ($metadata->hasValue('DiscoHints')) { $dh = new DiscoHints(); foreach ($metadata->getArray('DiscoHints') as $dhName => $dhValues) { switch ($dhName) { case 'IPHint': $dh->setIPHint($dhValues); break; case 'DomainHint': $dh->setDomainHint($dhValues); break; case 'GeolocationHint': $dh->setGeolocationHint($dhValues); break; } } $e->setExtensions(array_merge($e->getExtensions(), [$dh])); } } /** * Add an Organization element based on data passed as parameters * * @param array $orgName An array with the localized OrganizationName. * @param array $orgDisplayName An array with the localized OrganizationDisplayName. * @param array $orgURL An array with the localized OrganizationURL. * @return void */ public function addOrganization(array $orgName, array $orgDisplayName, array $orgURL) { $org = new Organization(); $org->setOrganizationName($orgName); $org->setOrganizationDisplayName($orgDisplayName); $org->setOrganizationURL($orgURL); $this->entityDescriptor->setOrganization($org); } /** * Add an Organization element based on metadata array. * * @param array $metadata The metadata we should extract the organization information from. * @return void */ public function addOrganizationInfo(array $metadata) { if ( empty($metadata['OrganizationName']) || empty($metadata['OrganizationDisplayName']) || empty($metadata['OrganizationURL']) ) { // empty or incomplete organization information return; } $orgName = Utils\Arrays::arrayize($metadata['OrganizationName'], 'en'); $orgDisplayName = Utils\Arrays::arrayize($metadata['OrganizationDisplayName'], 'en'); $orgURL = Utils\Arrays::arrayize($metadata['OrganizationURL'], 'en'); $this->addOrganization($orgName, $orgDisplayName, $orgURL); } /** * Add a list of endpoints to metadata. * * @param array $endpoints The endpoints. * @param bool $indexed Whether the endpoints should be indexed. * * @return array An array of endpoint objects, * either \SAML2\XML\md\EndpointType or \SAML2\XML\md\IndexedEndpointType. */ private static function createEndpoints(array $endpoints, bool $indexed): array { $ret = []; foreach ($endpoints as &$ep) { if ($indexed) { $t = new IndexedEndpointType(); if (!isset($ep['index'])) { // Find the maximum index $maxIndex = -1; foreach ($endpoints as $ep) { if (!isset($ep['index'])) { continue; } if ($ep['index'] > $maxIndex) { $maxIndex = $ep['index']; } } $ep['index'] = $maxIndex + 1; } $t->setIndex($ep['index']); } else { $t = new EndpointType(); } $t->setBinding($ep['Binding']); $t->setLocation($ep['Location']); if (isset($ep['ResponseLocation'])) { $t->setResponseLocation($ep['ResponseLocation']); } if (isset($ep['hoksso:ProtocolBinding'])) { $t->setAttributeNS( Constants::NS_HOK, 'hoksso:ProtocolBinding', Constants::BINDING_HTTP_REDIRECT ); } $ret[] = $t; } return $ret; } /** * Add an AttributeConsumingService element to the metadata. * * @param \SAML2\XML\md\SPSSODescriptor $spDesc The SPSSODescriptor element. * @param \SimpleSAML\Configuration $metadata The metadata. * @return void */ private function addAttributeConsumingService( SPSSODescriptor $spDesc, Configuration $metadata ): void { $attributes = $metadata->getArray('attributes', []); $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', []); /* * Add an AttributeConsumingService element with information as name and description and list * of requested attributes */ $attributeconsumer = new AttributeConsumingService(); $attributeconsumer->setIndex($metadata->getInteger('attributes.index', 0)); if ($metadata->hasValue('attributes.isDefault')) { $attributeconsumer->setIsDefault($metadata->getBoolean('attributes.isDefault', false)); } $attributeconsumer->setServiceName($name); $attributeconsumer->setServiceDescription($metadata->getLocalizedString('description', [])); $nameFormat = $metadata->getString('attributes.NameFormat', Constants::NAMEFORMAT_UNSPECIFIED); foreach ($attributes as $friendlyName => $attribute) { $t = new RequestedAttribute(); $t->setName($attribute); if (!is_int($friendlyName)) { $t->setFriendlyName($friendlyName); } if ($nameFormat !== Constants::NAMEFORMAT_UNSPECIFIED) { $t->setNameFormat($nameFormat); } if (in_array($attribute, $attributesrequired, true)) { $t->setIsRequired(true); } $attributeconsumer->addRequestedAttribute($t); } $spDesc->addAttributeConsumingService($attributeconsumer); } /** * Add a specific type of metadata to an entity. * * @param string $set The metadata set this metadata comes from. * @param array $metadata The metadata. * @return void */ public function addMetadata($set, $metadata) { assert(is_string($set)); assert(is_array($metadata)); $this->setExpiration($metadata); switch ($set) { case 'saml20-sp-remote': $this->addMetadataSP20($metadata); break; case 'saml20-idp-remote': $this->addMetadataIdP20($metadata); break; case 'shib13-sp-remote': $this->addMetadataSP11($metadata); break; case 'shib13-idp-remote': $this->addMetadataIdP11($metadata); break; case 'attributeauthority-remote': $this->addAttributeAuthority($metadata); break; default: Logger::warning('Unable to generate metadata for unknown type \'' . $set . '\'.'); } } /** * Add SAML 2.0 SP metadata. * * @param array $metadata The metadata. * @param array $protocols The protocols supported. Defaults to \SAML2\Constants::NS_SAMLP. * @return void */ public function addMetadataSP20($metadata, $protocols = [Constants::NS_SAMLP]) { assert(is_array($metadata)); assert(is_array($protocols)); assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $e = new SPSSODescriptor(); $e->setProtocolSupportEnumeration($protocols); if ($metadata->hasValue('saml20.sign.assertion')) { $e->setWantAssertionsSigned($metadata->getBoolean('saml20.sign.assertion')); } if ($metadata->hasValue('redirect.validate')) { $e->setAuthnRequestsSigned($metadata->getBoolean('redirect.validate')); } elseif ($metadata->hasValue('validate.authnrequest')) { $e->setAuthnRequestsSigned($metadata->getBoolean('validate.authnrequest')); } $this->addExtensions($metadata, $e); $this->addCertificate($e, $metadata); $e->setSingleLogoutService(self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false)); $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', [])); $endpoints = $metadata->getEndpoints('AssertionConsumerService'); foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', []) as $acs) { $endpoints[] = [ 'Binding' => Constants::BINDING_HTTP_ARTIFACT, 'Location' => $acs, ]; } $e->setAssertionConsumerService(self::createEndpoints($endpoints, true)); $this->addAttributeConsumingService($e, $metadata); $this->entityDescriptor->addRoleDescriptor($e); foreach ($metadata->getArray('contacts', []) as $contact) { if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) { $this->addContact($contact['contactType'], Utils\Config\Metadata::getContact($contact)); } } } /** * Add metadata of a SAML 2.0 identity provider. * * @param array $metadata The metadata. * @return void */ public function addMetadataIdP20($metadata) { assert(is_array($metadata)); assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $e = new IDPSSODescriptor(); $e->setProtocolSupportEnumeration(array_merge($e->getProtocolSupportEnumeration(), [Constants::NS_SAMLP])); if ($metadata->hasValue('sign.authnrequest')) { $e->setWantAuthnRequestsSigned($metadata->getBoolean('sign.authnrequest')); } elseif ($metadata->hasValue('redirect.sign')) { $e->setWantAuthnRequestsSigned($metadata->getBoolean('redirect.sign')); } $this->addExtensions($metadata, $e); $this->addCertificate($e, $metadata); if ($metadata->hasValue('ArtifactResolutionService')) { $e->setArtifactResolutionService(self::createEndpoints( $metadata->getEndpoints('ArtifactResolutionService'), true )); } $e->setSingleLogoutService(self::createEndpoints($metadata->getEndpoints('SingleLogoutService'), false)); $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', [])); $e->setSingleSignOnService(self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), false)); $this->entityDescriptor->addRoleDescriptor($e); foreach ($metadata->getArray('contacts', []) as $contact) { if (array_key_exists('contactType', $contact) && array_key_exists('emailAddress', $contact)) { $this->addContact($contact['contactType'], Utils\Config\Metadata::getContact($contact)); } } } /** * Add metadata of a SAML 1.1 service provider. * * @param array $metadata The metadata. * @return void */ public function addMetadataSP11($metadata) { assert(is_array($metadata)); assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $e = new SPSSODescriptor(); $e->setProtocolSupportEnumeration( array_merge( $e->getProtocolSupportEnumeration(), ['urn:oasis:names:tc:SAML:1.1:protocol'] ) ); $this->addCertificate($e, $metadata); $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', [])); $endpoints = $metadata->getEndpoints('AssertionConsumerService'); foreach ($metadata->getArrayizeString('AssertionConsumerService.artifact', []) as $acs) { $endpoints[] = [ 'Binding' => 'urn:oasis:names:tc:SAML:1.0:profiles:artifact-01', 'Location' => $acs, ]; } $e->setAssertionConsumerService(self::createEndpoints($endpoints, true)); $this->addAttributeConsumingService($e, $metadata); $this->entityDescriptor->addRoleDescriptor($e); } /** * Add metadata of a SAML 1.1 identity provider. * * @param array $metadata The metadata. * @return void */ public function addMetadataIdP11($metadata) { assert(is_array($metadata)); assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $e = new IDPSSODescriptor(); $e->setProtocolSupportEnumeration( array_merge($e->getProtocolSupportEnumeration(), [ 'urn:oasis:names:tc:SAML:1.1:protocol', 'urn:mace:shibboleth:1.0' ]) ); $this->addCertificate($e, $metadata); $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', [])); $e->setSingleSignOnService(self::createEndpoints($metadata->getEndpoints('SingleSignOnService'), false)); $this->entityDescriptor->addRoleDescriptor($e); } /** * Add metadata of a SAML attribute authority. * * @param array $metadata The AttributeAuthorityDescriptor, in the format returned by * \SimpleSAML\Metadata\SAMLParser. * @return void */ public function addAttributeAuthority(array $metadata) { assert(isset($metadata['entityid'])); assert(isset($metadata['metadata-set'])); $metadata = Configuration::loadFromArray($metadata, $metadata['entityid']); $e = new AttributeAuthorityDescriptor(); $e->setProtocolSupportEnumeration($metadata->getArray('protocols', [Constants::NS_SAMLP])); $this->addExtensions($metadata, $e); $this->addCertificate($e, $metadata); $e->setAttributeService(self::createEndpoints($metadata->getEndpoints('AttributeService'), false)); $e->setAssertionIDRequestService(self::createEndpoints( $metadata->getEndpoints('AssertionIDRequestService'), false )); $e->setNameIDFormat($metadata->getArrayizeString('NameIDFormat', [])); $this->entityDescriptor->addRoleDescriptor($e); } /** * Add contact information. * * Accepts a contact type, and a contact array that must be previously sanitized. * * WARNING: This function will change its signature and no longer parse a 'name' element. * * @param string $type The type of contact. Deprecated. * @param array $details The details about the contact. * * @return void * @todo Change the signature to remove $type. * @todo Remove the capability to pass a name and parse it inside the method. */ public function addContact($type, $details) { assert(is_string($type)); assert(is_array($details)); assert(in_array($type, ['technical', 'support', 'administrative', 'billing', 'other'], true)); // TODO: remove this check as soon as getContact() is called always before calling this function $details = Utils\Config\Metadata::getContact($details); $e = new \SAML2\XML\md\ContactPerson(); $e->setContactType($type); if (!empty($details['attributes'])) { $e->setContactPersonAttributes($details['attributes']); } if (isset($details['company'])) { $e->setCompany($details['company']); } if (isset($details['givenName'])) { $e->setGivenName($details['givenName']); } if (isset($details['surName'])) { $e->setSurName($details['surName']); } if (isset($details['emailAddress'])) { $eas = $details['emailAddress']; if (!is_array($eas)) { $eas = [$eas]; } foreach ($eas as $ea) { $e->addEmailAddress($ea); } } if (isset($details['telephoneNumber'])) { $tlfNrs = $details['telephoneNumber']; if (!is_array($tlfNrs)) { $tlfNrs = [$tlfNrs]; } foreach ($tlfNrs as $tlfNr) { $e->addTelephoneNumber($tlfNr); } } $this->entityDescriptor->addContactPerson($e); } /** * Add a KeyDescriptor with an X509 certificate. * * @param \SAML2\XML\md\RoleDescriptor $rd The RoleDescriptor the certificate should be added to. * @param string $use The value of the 'use' attribute. * @param string $x509data The certificate data. * @return void */ private function addX509KeyDescriptor(RoleDescriptor $rd, string $use, string $x509data): void { assert(in_array($use, ['encryption', 'signing'], true)); $keyDescriptor = \SAML2\Utils::createKeyDescriptor($x509data); $keyDescriptor->setUse($use); $rd->addKeyDescriptor($keyDescriptor); } /** * 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. * @return void */ private function addCertificate(RoleDescriptor $rd, Configuration $metadata): void { $keys = $metadata->getPublicKeys(); 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')); } } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageHandlerXML.php0000644000000000000000000000715714042503475024766 0ustar rootrootresolvePath($config['file']); } elseif (array_key_exists('url', $config)) { $src = $config['url']; } elseif (array_key_exists('xml', $config)) { $srcXml = $config['xml']; } else { throw new \Exception("Missing one of 'file', 'url' and 'xml' in XML metadata source configuration."); } $SP1x = []; $IdP1x = []; $SP20 = []; $IdP20 = []; $AAD = []; if (isset($src)) { $entities = SAMLParser::parseDescriptorsFile($src); } elseif (isset($srcXml)) { $entities = SAMLParser::parseDescriptorsString($srcXml); } else { throw new \Exception("Neither source file path/URI nor string data provided"); } foreach ($entities as $entityId => $entity) { $md = $entity->getMetadata1xSP(); if ($md !== null) { $SP1x[$entityId] = $md; } $md = $entity->getMetadata1xIdP(); if ($md !== null) { $IdP1x[$entityId] = $md; } $md = $entity->getMetadata20SP(); if ($md !== null) { $SP20[$entityId] = $md; } $md = $entity->getMetadata20IdP(); if ($md !== null) { $IdP20[$entityId] = $md; } $md = $entity->getAttributeAuthorities(); if (count($md) > 0) { $AAD[$entityId] = $md[0]; } } $this->metadata = [ 'shib13-sp-remote' => $SP1x, 'shib13-idp-remote' => $IdP1x, 'saml20-sp-remote' => $SP20, 'saml20-idp-remote' => $IdP20, 'attributeauthority-remote' => $AAD, ]; } /** * This function returns an associative array with metadata for all entities in the given set. The * key of the array is the entity id. * * @param string $set The set we want to list metadata for. * * @return array An associative array with all entities in the given set. */ public function getMetadataSet($set) { if (array_key_exists($set, $this->metadata)) { return $this->metadata[$set]; } // we don't have this metadata set return []; } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php0000644000000000000000000003477114042503475024407 0ustar rootroot * @package SimpleSAMLphp */ class MetaDataStorageHandler implements \SimpleSAML\Utils\ClearableState { /** * This static variable contains a reference to the current * instance of the metadata handler. This variable will be null if * we haven't instantiated a metadata handler yet. * * @var MetaDataStorageHandler|null */ private static $metadataHandler = null; /** * This is a list of all the metadata sources we have in our metadata * chain. When we need metadata, we will look through this chain from start to end. * * @var MetaDataStorageSource[] */ private $sources; /** * This function retrieves the current instance of the metadata handler. * The metadata handler will be instantiated if this is the first call * to this function. * * @return MetaDataStorageHandler The current metadata handler instance. */ public static function getMetadataHandler() { if (self::$metadataHandler === null) { self::$metadataHandler = new MetaDataStorageHandler(); } return self::$metadataHandler; } /** * This constructor initializes this metadata storage handler. It will load and * parse the configuration, and initialize the metadata source list. */ protected function __construct() { $config = Configuration::getInstance(); $sourcesConfig = $config->getArray('metadata.sources', null); // for backwards compatibility, and to provide a default configuration if ($sourcesConfig === null) { $type = $config->getString('metadata.handler', 'flatfile'); $sourcesConfig = [['type' => $type]]; } try { $this->sources = MetaDataStorageSource::parseSources($sourcesConfig); } catch (\Exception $e) { throw new \Exception( "Invalid configuration of the 'metadata.sources' configuration option: " . $e->getMessage() ); } } /** * This function is used to generate some metadata elements automatically. * * @param string $property The metadata property which should be auto-generated. * @param string $set The set we the property comes from. * * @return string The auto-generated metadata property. * @throws \Exception If the metadata cannot be generated automatically. */ public function getGenerated($property, $set) { // first we check if the user has overridden this property in the metadata try { $metadataSet = $this->getMetaDataCurrent($set); if (array_key_exists($property, $metadataSet)) { return $metadataSet[$property]; } } catch (\Exception $e) { // probably metadata wasn't found. In any case we continue by generating the metadata } // get the configuration $config = Configuration::getInstance(); assert($config instanceof Configuration); $baseurl = Utils\HTTP::getSelfURLHost() . $config->getBasePath(); if ($set == 'saml20-sp-hosted') { if ($property === 'SingleLogoutServiceBinding') { return Constants::BINDING_HTTP_REDIRECT; } } elseif ($set == 'saml20-idp-hosted') { switch ($property) { case 'SingleSignOnService': return $baseurl . 'saml2/idp/SSOService.php'; case 'SingleSignOnServiceBinding': return Constants::BINDING_HTTP_REDIRECT; case 'SingleLogoutService': return $baseurl . 'saml2/idp/SingleLogoutService.php'; case 'SingleLogoutServiceBinding': return Constants::BINDING_HTTP_REDIRECT; } } elseif ($set == 'shib13-idp-hosted') { if ($property === 'SingleSignOnService') { return $baseurl . 'shib13/idp/SSOService.php'; } } throw new \Exception('Could not generate metadata property ' . $property . ' for set ' . $set . '.'); } /** * This function lists all known metadata in the given set. It is returned as an associative array * where the key is the entity id. * * @param string $set The set we want to list metadata from. * @param bool $showExpired A boolean specifying whether expired entities should be returned * * @return array An associative array with the metadata from from the given set. */ public function getList($set = 'saml20-idp-remote', $showExpired = false) { assert(is_string($set)); $result = []; foreach ($this->sources as $source) { $srcList = $source->getMetadataSet($set); if ($showExpired === false) { foreach ($srcList as $key => $le) { if (array_key_exists('expire', $le) && ($le['expire'] < time())) { unset($srcList[$key]); Logger::warning( "Dropping metadata entity " . var_export($key, true) . ", expired " . Utils\Time::generateTimestamp($le['expire']) . "." ); } } } /* $result is the last argument to array_merge because we want the content already * in $result to have precedence. */ $result = array_merge($srcList, $result); } return $result; } /** * This function retrieves metadata for the current entity based on the hostname/path the request * was directed to. It will throw an exception if it is unable to locate the metadata. * * @param string $set The set we want metadata from. * * @return array An associative array with the metadata. */ public function getMetaDataCurrent($set) { return $this->getMetaData(null, $set); } /** * This function locates the current entity id based on the hostname/path combination the user accessed. * It will throw an exception if it is unable to locate the entity id. * * @param string $set The set we look for the entity id in. * @param string $type Do you want to return the metaindex or the entityID. [entityid|metaindex] * * @return string The entity id which is associated with the current hostname/path combination. * @throws \Exception If no default metadata can be found in the set for the current host. */ public function getMetaDataCurrentEntityID($set, $type = 'entityid') { assert(is_string($set)); // first we look for the hostname/path combination $currenthostwithpath = Utils\HTTP::getSelfHostWithPath(); // sp.example.org/university foreach ($this->sources as $source) { $index = $source->getEntityIdFromHostPath($currenthostwithpath, $set, $type); if ($index !== null) { return $index; } } // then we look for the hostname $currenthost = Utils\HTTP::getSelfHost(); // sp.example.org foreach ($this->sources as $source) { $index = $source->getEntityIdFromHostPath($currenthost, $set, $type); if ($index !== null) { return $index; } } // then we look for the DEFAULT entry foreach ($this->sources as $source) { $entityId = $source->getEntityIdFromHostPath('__DEFAULT__', $set, $type); if ($entityId !== null) { return $entityId; } } // we were unable to find the hostname/path in any metadata source throw new \Exception( 'Could not find any default metadata entities in set [' . $set . '] for host [' . $currenthost . ' : ' . $currenthostwithpath . ']' ); } /** * This method will call getPreferredEntityIdFromCIDRhint() on all of the * sources. * * @param string $set Which set of metadata we are looking it up in. * @param string $ip IP address * * @return string|null The entity id of a entity which have a CIDR hint where the provided * IP address match. */ public function getPreferredEntityIdFromCIDRhint($set, $ip) { foreach ($this->sources as $source) { $entityId = $source->getPreferredEntityIdFromCIDRhint($set, $ip); if ($entityId !== null) { return $entityId; } } return null; } /** * This function loads the metadata for entity IDs in $entityIds. It is returned as an associative array * where the key is the entity id. An empty array may be returned if no matching entities were found * @param array $entityIds The entity ids to load * @param string $set The set we want to get metadata from. * @return array An associative array with the metadata for the requested entities, if found. */ public function getMetaDataForEntities(array $entityIds, $set) { $result = []; foreach ($this->sources as $source) { $srcList = $source->getMetaDataForEntities($entityIds, $set); foreach ($srcList as $key => $le) { if (array_key_exists('expire', $le)) { if ($le['expire'] < time()) { unset($srcList[$key]); \SimpleSAML\Logger::warning( "Dropping metadata entity " . var_export($key, true) . ", expired " . \SimpleSAML\Utils\Time::generateTimestamp($le['expire']) . "." ); continue; } } // We found the entity id so remove it from the list that needs resolving /** @psalm-suppress PossiblyInvalidArrayOffset */ unset($entityIds[array_search($key, $entityIds)]); } $result = array_merge($srcList, $result); } return $result; } /** * This function looks up the metadata for the given entity id in the given set. It will throw an * exception if it is unable to locate the metadata. * * @param string|null $index The entity id we are looking up. This parameter may be NULL, in which case we look up * the current entity id based on the current hostname/path. * @param string $set The set of metadata we are looking up the entity id in. * * @return array The metadata array describing the specified entity. * @throws \Exception If metadata for the specified entity is expired. * @throws \SimpleSAML\Error\MetadataNotFound If no metadata for the entity specified can be found. */ public function getMetaData($index, $set) { assert(is_string($set)); if ($index === null) { $index = $this->getMetaDataCurrentEntityID($set, 'metaindex'); } assert(is_string($index)); foreach ($this->sources as $source) { $metadata = $source->getMetaData($index, $set); if ($metadata !== null) { if (array_key_exists('expire', $metadata)) { if ($metadata['expire'] < time()) { throw new \Exception( 'Metadata for the entity [' . $index . '] expired ' . (time() - $metadata['expire']) . ' seconds ago.' ); } } $metadata['metadata-index'] = $index; $metadata['metadata-set'] = $set; assert(array_key_exists('entityid', $metadata)); return $metadata; } } throw new Error\MetadataNotFound($index); } /** * Retrieve the metadata as a configuration object. * * This function will throw an exception if it is unable to locate the metadata. * * @param string $entityId The entity ID we are looking up. * @param string $set The metadata set we are searching. * * @return \SimpleSAML\Configuration The configuration object representing the metadata. * @throws \SimpleSAML\Error\MetadataNotFound If no metadata for the entity specified can be found. */ public function getMetaDataConfig($entityId, $set) { assert(is_string($entityId)); assert(is_string($set)); $metadata = $this->getMetaData($entityId, $set); return Configuration::loadFromArray($metadata, $set . '/' . var_export($entityId, true)); } /** * Search for an entity's metadata, given the SHA1 digest of its entity ID. * * @param string $sha1 The SHA1 digest of the entity ID. * @param string $set The metadata set we are searching. * * @return null|\SimpleSAML\Configuration The metadata corresponding to the entity, or null if the entity cannot be * found. */ public function getMetaDataConfigForSha1($sha1, $set) { assert(is_string($sha1)); assert(is_string($set)); $result = []; foreach ($this->sources as $source) { $srcList = $source->getMetadataSet($set); /* $result is the last argument to array_merge because we want the content already * in $result to have precedence. */ $result = array_merge($srcList, $result); } foreach ($result as $remote_provider) { if (sha1($remote_provider['entityid']) == $sha1) { $remote_provider['metadata-set'] = $set; return Configuration::loadFromArray( $remote_provider, $set . '/' . var_export($remote_provider['entityid'], true) ); } } return null; } /** * Clear any metadata cached. * Allows for metadata configuration to be changed and reloaded during a given request. Most useful * when running phpunit tests and needing to alter config.php and metadata sources between test cases * @return void */ public static function clearInternalState() { self::$metadataHandler = null; } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/SAMLParser.php0000644000000000000000000015672114042503475022015 0ustar rootrootspDescriptors = []; $this->idpDescriptors = []; $e = $entityElement->toXML(); $e = $e->ownerDocument->saveXML($e); $this->entityDescriptor = base64_encode($e); $this->entityId = $entityElement->getEntityID(); $expireTime = self::getExpireTime($entityElement, $maxExpireTime); $this->validators = $validators; $this->validators[] = $entityElement; // process Extensions element, if it exists $ext = self::processExtensions($entityElement, $parentExtensions); $this->scopes = $ext['scope']; $this->tags = $ext['tags']; $this->entityAttributes = $ext['EntityAttributes']; $this->registrationInfo = $ext['RegistrationInfo']; // look over the RoleDescriptors foreach ($entityElement->getRoleDescriptor() as $child) { if ($child instanceof SPSSODescriptor) { $this->processSPSSODescriptor($child, $expireTime); } elseif ($child instanceof IDPSSODescriptor) { $this->processIDPSSODescriptor($child, $expireTime); } elseif ($child instanceof AttributeAuthorityDescriptor) { $this->processAttributeAuthorityDescriptor($child, $expireTime); } } $organization = $entityElement->getOrganization(); if ($organization !== null) { $this->processOrganization($organization); } if ($entityElement->getContactPerson() !== []) { foreach ($entityElement->getContactPerson() as $contact) { $this->processContactPerson($contact); } } } /** * This function parses a file which contains XML encoded metadata. * * @param string $file The path to the file which contains the metadata. * * @return SAMLParser An instance of this class with the metadata loaded. * @throws \Exception If the file does not parse as XML. */ public static function parseFile($file) { /** @var string $data */ $data = Utils\HTTP::fetch($file); try { $doc = DOMDocumentFactory::fromString($data); } catch (\Exception $e) { throw new \Exception('Failed to read XML from file: ' . $file); } return self::parseDocument($doc); } /** * This function parses a string which contains XML encoded metadata. * * @param string $metadata A string which contains XML encoded metadata. * * @return SAMLParser An instance of this class with the metadata loaded. * @throws \Exception If the string does not parse as XML. */ public static function parseString($metadata) { try { $doc = DOMDocumentFactory::fromString($metadata); } catch (\Exception $e) { throw new \Exception('Failed to parse XML string.'); } return self::parseDocument($doc); } /** * This function parses a \DOMDocument which is assumed to contain a single EntityDescriptor element. * * @param \DOMDocument $document The \DOMDocument which contains the EntityDescriptor element. * * @return SAMLParser An instance of this class with the metadata loaded. */ public static function parseDocument($document) { assert($document instanceof DOMDocument); $entityElement = self::findEntityDescriptor($document); return self::parseElement($entityElement); } /** * This function parses a \SAML2\XML\md\EntityDescriptor object which represents a EntityDescriptor element. * * @param \SAML2\XML\md\EntityDescriptor $entityElement A \SAML2\XML\md\EntityDescriptor object which represents a * EntityDescriptor element. * * @return SAMLParser An instance of this class with the metadata loaded. */ public static function parseElement($entityElement) { assert($entityElement instanceof EntityDescriptor); return new SAMLParser($entityElement, null, []); } /** * This function parses a file where the root node is either an EntityDescriptor element or an * EntitiesDescriptor element. In both cases it will return an associative array of SAMLParser instances. If * the file contains a single EntityDescriptorElement, then the array will contain a single SAMLParser * instance. * * @param string|null $file The path to the file which contains the EntityDescriptor or EntitiesDescriptor element. * * @return SAMLParser[] An array of SAMLParser instances. * @throws \Exception If the file does not parse as XML. */ public static function parseDescriptorsFile($file) { if ($file === null) { throw new \Exception('Cannot open file NULL. File name not specified.'); } /** @var string $data */ $data = Utils\HTTP::fetch($file); try { $doc = DOMDocumentFactory::fromString($data); } catch (\Exception $e) { throw new \Exception('Failed to read XML from file: ' . $file); } return self::parseDescriptorsElement($doc->documentElement); } /** * This function parses a string with XML data. The root node of the XML data is expected to be either an * EntityDescriptor element or an EntitiesDescriptor element. It will return an associative array of * SAMLParser instances. * * @param string $string The string with XML data. * * @return SAMLParser[] An associative array of SAMLParser instances. The key of the array will * be the entity id. * @throws \Exception If the string does not parse as XML. */ public static function parseDescriptorsString($string) { try { $doc = DOMDocumentFactory::fromString($string); } catch (\Exception $e) { throw new \Exception('Failed to parse XML string.'); } return self::parseDescriptorsElement($doc->documentElement); } /** * This function parses a DOMElement which represents either an EntityDescriptor element or an * EntitiesDescriptor element. It will return an associative array of SAMLParser instances in both cases. * * @param \DOMElement|NULL $element The DOMElement which contains the EntityDescriptor element or the * EntitiesDescriptor element. * * @return SAMLParser[] An associative array of SAMLParser instances. The key of the array will * be the entity id. * @throws \Exception if the document is empty or the root is an unexpected node. */ public static function parseDescriptorsElement(DOMElement $element = null) { if ($element === null) { throw new \Exception('Document was empty.'); } if (Utils\XML::isDOMNodeOfType($element, 'EntityDescriptor', '@md') === true) { return self::processDescriptorsElement(new EntityDescriptor($element)); } elseif (Utils\XML::isDOMNodeOfType($element, 'EntitiesDescriptor', '@md') === true) { return self::processDescriptorsElement(new EntitiesDescriptor($element)); } else { throw new \Exception('Unexpected root node: [' . $element->namespaceURI . ']:' . $element->localName); } } /** * * @param \SAML2\XML\md\EntityDescriptor|\SAML2\XML\md\EntitiesDescriptor $element The element we should process. * @param int|NULL $maxExpireTime The maximum expiration time of the entities. * @param array $validators The parent-elements that may be signed. * @param array $parentExtensions An optional array of extensions from the parent element. * * @return SAMLParser[] Array of SAMLParser instances. */ private static function processDescriptorsElement( SignedElementHelper $element, int $maxExpireTime = null, array $validators = [], array $parentExtensions = [] ): array { if ($element instanceof EntityDescriptor) { $ret = new SAMLParser($element, $maxExpireTime, $validators, $parentExtensions); $ret = [$ret->getEntityId() => $ret]; /** @var SAMLParser[] $ret */ return $ret; } assert($element instanceof EntitiesDescriptor); $extensions = self::processExtensions($element, $parentExtensions); $expTime = self::getExpireTime($element, $maxExpireTime); $validators[] = $element; $ret = []; foreach ($element->getChildren() as $child) { $ret += self::processDescriptorsElement($child, $expTime, $validators, $extensions); } return $ret; } /** * Determine how long a given element can be cached. * * This function looks for the 'validUntil' attribute to determine * how long a given XML-element is valid. It returns this as a unix timestamp. * * @param mixed $element The element we should determine the expiry time of. * @param int|null $maxExpireTime The maximum expiration time. * * @return int|null The unix timestamp for when the element should expire. Will be NULL if no * limit is set for the element. */ private static function getExpireTime($element, int $maxExpireTime = null): ?int { // validUntil may be null $expire = $element->getValidUntil(); if ($maxExpireTime !== null && ($expire === null || $maxExpireTime < $expire)) { $expire = $maxExpireTime; } return $expire; } /** * This function returns the entity id of this parsed entity. * * @return string The entity id of this parsed entity. */ public function getEntityId() { return $this->entityId; } /** * @return array */ private function getMetadataCommon(): array { $ret = []; $ret['entityid'] = $this->entityId; $ret['entityDescriptor'] = $this->entityDescriptor; // add organizational metadata if (!empty($this->organizationName)) { $ret['description'] = $this->organizationName; $ret['OrganizationName'] = $this->organizationName; } if (!empty($this->organizationDisplayName)) { $ret['name'] = $this->organizationDisplayName; $ret['OrganizationDisplayName'] = $this->organizationDisplayName; } if (!empty($this->organizationURL)) { $ret['url'] = $this->organizationURL; $ret['OrganizationURL'] = $this->organizationURL; } //add contact metadata $ret['contacts'] = $this->contacts; return $ret; } /** * Add data parsed from extensions to metadata. * * @param array &$metadata The metadata that should be updated. * @param array $roleDescriptor The parsed role descriptor. * @return void */ private function addExtensions(array &$metadata, array $roleDescriptor): void { assert(array_key_exists('scope', $roleDescriptor)); assert(array_key_exists('tags', $roleDescriptor)); $scopes = array_merge($this->scopes, array_diff($roleDescriptor['scope'], $this->scopes)); if (!empty($scopes)) { $metadata['scope'] = $scopes; } $tags = array_merge($this->tags, array_diff($roleDescriptor['tags'], $this->tags)); if (!empty($tags)) { $metadata['tags'] = $tags; } if (!empty($this->registrationInfo)) { $metadata['RegistrationInfo'] = $this->registrationInfo; } if (!empty($this->entityAttributes)) { $metadata['EntityAttributes'] = $this->entityAttributes; // check for entity categories if (Utils\Config\Metadata::isHiddenFromDiscovery($metadata)) { $metadata['hide.from.discovery'] = true; } } if (!empty($roleDescriptor['UIInfo'])) { $metadata['UIInfo'] = $roleDescriptor['UIInfo']; } if (!empty($roleDescriptor['DiscoHints'])) { $metadata['DiscoHints'] = $roleDescriptor['DiscoHints']; } } /** * This function returns the metadata for SAML 1.x SPs in the format SimpleSAMLphp expects. * This is an associative array with the following fields: * - 'entityid': The entity id of the entity described in the metadata. * - 'AssertionConsumerService': String with the URL of the assertion consumer service which supports * the browser-post binding. * - 'certData': X509Certificate for entity (if present). * * Metadata must be loaded with one of the parse functions before this function can be called. * * @return array|null An associative array with metadata or NULL if we are unable to * generate metadata for a SAML 1.x SP. */ public function getMetadata1xSP() { $ret = $this->getMetadataCommon(); $ret['metadata-set'] = 'shib13-sp-remote'; // find SP information which supports one of the SAML 1.x protocols $spd = $this->getSPDescriptors(self::$SAML1xProtocols); if (count($spd) === 0) { return null; } // we currently only look at the first SPDescriptor which supports SAML 1.x $spd = $spd[0]; // add expire time to metadata if (array_key_exists('expire', $spd)) { $ret['expire'] = $spd['expire']; } // find the assertion consumer service endpoints $ret['AssertionConsumerService'] = $spd['AssertionConsumerService']; // add the list of attributes the SP should receive if (array_key_exists('attributes', $spd)) { $ret['attributes'] = $spd['attributes']; } if (array_key_exists('attributes.required', $spd)) { $ret['attributes.required'] = $spd['attributes.required']; } if (array_key_exists('attributes.NameFormat', $spd)) { $ret['attributes.NameFormat'] = $spd['attributes.NameFormat']; } // add name & description if (array_key_exists('name', $spd)) { $ret['name'] = $spd['name']; } if (array_key_exists('description', $spd)) { $ret['description'] = $spd['description']; } // add public keys if (!empty($spd['keys'])) { $ret['keys'] = $spd['keys']; } // add extensions $this->addExtensions($ret, $spd); // prioritize mdui:DisplayName as the name if available if (!empty($ret['UIInfo']['DisplayName'])) { $ret['name'] = $ret['UIInfo']['DisplayName']; } return $ret; } /** * This function returns the metadata for SAML 1.x IdPs in the format SimpleSAMLphp expects. * This is an associative array with the following fields: * - 'entityid': The entity id of the entity described in the metadata. * - 'name': Auto generated name for this entity. Currently set to the entity id. * - 'SingleSignOnService': String with the URL of the SSO service which supports the redirect binding. * - 'SingleLogoutService': String with the URL where we should send logout requests/responses. * - 'certData': X509Certificate for entity (if present). * - 'certFingerprint': Fingerprint of the X509Certificate from the metadata. (deprecated) * * Metadata must be loaded with one of the parse functions before this function can be called. * * @return array|null An associative array with metadata or NULL if we are unable to * generate metadata for a SAML 1.x IdP. */ public function getMetadata1xIdP() { $ret = $this->getMetadataCommon(); $ret['metadata-set'] = 'shib13-idp-remote'; // find IdP information which supports the SAML 1.x protocol $idp = $this->getIdPDescriptors(self::$SAML1xProtocols); if (count($idp) === 0) { return null; } // we currently only look at the first IDP descriptor which supports SAML 1.x $idp = $idp[0]; // fdd expire time to metadata if (array_key_exists('expire', $idp)) { $ret['expire'] = $idp['expire']; } // find the SSO service endpoints $ret['SingleSignOnService'] = $idp['SingleSignOnService']; // find the ArtifactResolutionService endpoint $ret['ArtifactResolutionService'] = $idp['ArtifactResolutionService']; // add public keys if (!empty($idp['keys'])) { $ret['keys'] = $idp['keys']; } // add extensions $this->addExtensions($ret, $idp); // prioritize mdui:DisplayName as the name if available if (!empty($ret['UIInfo']['DisplayName'])) { $ret['name'] = $ret['UIInfo']['DisplayName']; } return $ret; } /** * This function returns the metadata for SAML 2.0 SPs in the format SimpleSAMLphp expects. * This is an associative array with the following fields: * - 'entityid': The entity id of the entity described in the metadata. * - 'AssertionConsumerService': String with the URL of the assertion consumer service which supports * the browser-post binding. * - 'SingleLogoutService': String with the URL where we should send logout requests/responses. * - 'NameIDFormat': The name ID format this SP expects. This may be unset. * - 'certData': X509Certificate for entity (if present). * * Metadata must be loaded with one of the parse functions before this function can be called. * * @return array|null An associative array with metadata or NULL if we are unable to * generate metadata for a SAML 2.x SP. */ public function getMetadata20SP() { $ret = $this->getMetadataCommon(); $ret['metadata-set'] = 'saml20-sp-remote'; // find SP information which supports the SAML 2.0 protocol $spd = $this->getSPDescriptors(self::$SAML20Protocols); if (count($spd) === 0) { return null; } // we currently only look at the first SPDescriptor which supports SAML 2.0 $spd = $spd[0]; // add expire time to metadata if (array_key_exists('expire', $spd)) { $ret['expire'] = $spd['expire']; } // find the assertion consumer service endpoints $ret['AssertionConsumerService'] = $spd['AssertionConsumerService']; // find the single logout service endpoint $ret['SingleLogoutService'] = $spd['SingleLogoutService']; // find the NameIDFormat. This may not exist if (count($spd['nameIDFormats']) > 0) { // SimpleSAMLphp currently only supports a single NameIDFormat per SP. We use the first one $ret['NameIDFormat'] = $spd['nameIDFormats'][0]; } // add the list of attributes the SP should receive if (array_key_exists('attributes', $spd)) { $ret['attributes'] = $spd['attributes']; } if (array_key_exists('attributes.required', $spd)) { $ret['attributes.required'] = $spd['attributes.required']; } if (array_key_exists('attributes.NameFormat', $spd)) { $ret['attributes.NameFormat'] = $spd['attributes.NameFormat']; } if (array_key_exists('attributes.index', $spd)) { $ret['attributes.index'] = $spd['attributes.index']; } if (array_key_exists('attributes.isDefault', $spd)) { $ret['attributes.isDefault'] = $spd['attributes.isDefault']; } // add name & description if (array_key_exists('name', $spd)) { $ret['name'] = $spd['name']; } if (array_key_exists('description', $spd)) { $ret['description'] = $spd['description']; } // add public keys if (!empty($spd['keys'])) { $ret['keys'] = $spd['keys']; } // add validate.authnrequest if (array_key_exists('AuthnRequestsSigned', $spd)) { $ret['validate.authnrequest'] = $spd['AuthnRequestsSigned']; } // add saml20.sign.assertion if (array_key_exists('WantAssertionsSigned', $spd)) { $ret['saml20.sign.assertion'] = $spd['WantAssertionsSigned']; } // add extensions $this->addExtensions($ret, $spd); // prioritize mdui:DisplayName as the name if available if (!empty($ret['UIInfo']['DisplayName'])) { $ret['name'] = $ret['UIInfo']['DisplayName']; } return $ret; } /** * This function returns the metadata for SAML 2.0 IdPs in the format SimpleSAMLphp expects. * This is an associative array with the following fields: * - 'entityid': The entity id of the entity described in the metadata. * - 'name': Auto generated name for this entity. Currently set to the entity id. * - 'SingleSignOnService': String with the URL of the SSO service which supports the redirect binding. * - 'SingleLogoutService': String with the URL where we should send logout requests(/responses). * - 'SingleLogoutServiceResponse': String where we should send logout responses (if this is different from * the 'SingleLogoutService' endpoint. * - 'NameIDFormats': The name ID formats this IdP supports. * - 'certData': X509Certificate for entity (if present). * - 'certFingerprint': Fingerprint of the X509Certificate from the metadata. (deprecated) * * Metadata must be loaded with one of the parse functions before this function can be called. * * @return array|null An associative array with metadata or NULL if we are unable to * generate metadata for a SAML 2.0 IdP. */ public function getMetadata20IdP() { $ret = $this->getMetadataCommon(); $ret['metadata-set'] = 'saml20-idp-remote'; // find IdP information which supports the SAML 2.0 protocol $idp = $this->getIdPDescriptors(self::$SAML20Protocols); if (count($idp) === 0) { return null; } // we currently only look at the first IDP descriptor which supports SAML 2.0 $idp = $idp[0]; // add expire time to metadata if (array_key_exists('expire', $idp)) { $ret['expire'] = $idp['expire']; } // enable redirect.sign if WantAuthnRequestsSigned is enabled if ($idp['WantAuthnRequestsSigned']) { $ret['sign.authnrequest'] = true; } // find the SSO service endpoint $ret['SingleSignOnService'] = $idp['SingleSignOnService']; // find the single logout service endpoint $ret['SingleLogoutService'] = $idp['SingleLogoutService']; // find the ArtifactResolutionService endpoint $ret['ArtifactResolutionService'] = $idp['ArtifactResolutionService']; // add supported nameIDFormats $ret['NameIDFormats'] = $idp['nameIDFormats']; // add public keys if (!empty($idp['keys'])) { $ret['keys'] = $idp['keys']; } // add extensions $this->addExtensions($ret, $idp); // prioritize mdui:DisplayName as the name if available if (!empty($ret['UIInfo']['DisplayName'])) { $ret['name'] = $ret['UIInfo']['DisplayName']; } return $ret; } /** * Retrieve AttributeAuthorities from the metadata. * * @return array Array of AttributeAuthorityDescriptor entries. */ public function getAttributeAuthorities() { return $this->attributeAuthorityDescriptors; } /** * Parse a RoleDescriptorType element. * * The returned associative array has the following elements: * - 'protocols': Array with the protocols supported. * - 'expire': Timestamp for when this descriptor expires. * - 'keys': Array of associative arrays with the elements from parseKeyDescriptor. * * @param \SAML2\XML\md\RoleDescriptor $element The element we should extract metadata from. * @param int|null $expireTime The unix timestamp for when this element should expire, or * NULL if unknown. * * @return array An associative array with metadata we have extracted from this element. */ private static function parseRoleDescriptorType(RoleDescriptor $element, int $expireTime = null): array { $ret = []; $expireTime = self::getExpireTime($element, $expireTime); if ($expireTime !== null) { // we got an expired timestamp, either from this element or one of the parent elements $ret['expire'] = $expireTime; } $ret['protocols'] = $element->getProtocolSupportEnumeration(); // process KeyDescriptor elements $ret['keys'] = []; foreach ($element->getKeyDescriptor() as $kd) { $key = self::parseKeyDescriptor($kd); if ($key !== null) { $ret['keys'][] = $key; } } $ext = self::processExtensions($element); $ret['scope'] = $ext['scope']; $ret['tags'] = $ext['tags']; $ret['EntityAttributes'] = $ext['EntityAttributes']; $ret['UIInfo'] = $ext['UIInfo']; $ret['DiscoHints'] = $ext['DiscoHints']; return $ret; } /** * This function extracts metadata from a SSODescriptor element. * * The returned associative array has the following elements: * - 'protocols': Array with the protocols this SSODescriptor supports. * - 'SingleLogoutService': Array with the single logout service endpoints. Each endpoint is stored * as an associative array with the elements that parseGenericEndpoint returns. * - 'nameIDFormats': The NameIDFormats supported by this SSODescriptor. This may be an empty array. * - 'keys': Array of associative arrays with the elements from parseKeyDescriptor: * * @param \SAML2\XML\md\SSODescriptorType $element The element we should extract metadata from. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or * NULL if unknown. * * @return array An associative array with metadata we have extracted from this element. */ private static function parseSSODescriptor(SSODescriptorType $element, int $expireTime = null): array { $sd = self::parseRoleDescriptorType($element, $expireTime); // find all SingleLogoutService elements $sd['SingleLogoutService'] = self::extractEndpoints($element->getSingleLogoutService()); // find all ArtifactResolutionService elements $sd['ArtifactResolutionService'] = self::extractEndpoints($element->getArtifactResolutionService()); // process NameIDFormat elements $sd['nameIDFormats'] = $element->getNameIDFormat(); return $sd; } /** * This function extracts metadata from a SPSSODescriptor element. * * @param \SAML2\XML\md\SPSSODescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or * NULL if unknown. * @return void */ private function processSPSSODescriptor(SPSSODescriptor $element, int $expireTime = null): void { $sp = self::parseSSODescriptor($element, $expireTime); // find all AssertionConsumerService elements $sp['AssertionConsumerService'] = self::extractEndpoints($element->getAssertionConsumerService()); // find all the attributes and SP name... $attcs = $element->getAttributeConsumingService(); if (count($attcs) > 0) { self::parseAttributeConsumerService($attcs[0], $sp); } // check AuthnRequestsSigned if ($element->getAuthnRequestsSigned() !== null) { $sp['AuthnRequestsSigned'] = $element->getAuthnRequestsSigned(); } // check WantAssertionsSigned if ($element->wantAssertionsSigned() !== null) { $sp['WantAssertionsSigned'] = $element->wantAssertionsSigned(); } $this->spDescriptors[] = $sp; } /** * This function extracts metadata from a IDPSSODescriptor element. * * @param \SAML2\XML\md\IDPSSODescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should expire, or * NULL if unknown. * @return void */ private function processIDPSSODescriptor(IDPSSODescriptor $element, int $expireTime = null): void { $idp = self::parseSSODescriptor($element, $expireTime); // find all SingleSignOnService elements $idp['SingleSignOnService'] = self::extractEndpoints($element->getSingleSignOnService()); if ($element->wantAuthnRequestsSigned()) { $idp['WantAuthnRequestsSigned'] = true; } else { $idp['WantAuthnRequestsSigned'] = false; } $this->idpDescriptors[] = $idp; } /** * This function extracts metadata from a AttributeAuthorityDescriptor element. * * @param \SAML2\XML\md\AttributeAuthorityDescriptor $element The element which should be parsed. * @param int|NULL $expireTime The unix timestamp for when this element should * expire, or NULL if unknown. * @return void */ private function processAttributeAuthorityDescriptor( AttributeAuthorityDescriptor $element, $expireTime ): void { assert($expireTime === null || is_int($expireTime)); $aad = self::parseRoleDescriptorType($element, $expireTime); $aad['entityid'] = $this->getEntityId(); $aad['metadata-set'] = 'attributeauthority-remote'; $aad['AttributeService'] = self::extractEndpoints($element->getAttributeService()); $aad['AssertionIDRequestService'] = self::extractEndpoints($element->getAssertionIDRequestService()); $aad['NameIDFormat'] = $element->getNameIDFormat(); $this->attributeAuthorityDescriptors[] = $aad; } /** * Parse an Extensions element. Extensions may appear in multiple elements and certain extension may get inherited * from a parent element. * * @param mixed $element The element which contains the Extensions element. * @param array $parentExtensions An optional array of extensions from the parent element. * * @return array An associative array with the extensions parsed. */ private static function processExtensions($element, array $parentExtensions = []): array { $ret = [ 'scope' => [], 'tags' => [], 'EntityAttributes' => [], 'RegistrationInfo' => [], 'UIInfo' => [], 'DiscoHints' => [], ]; // Some extensions may get inherited from a parent element if ( ($element instanceof EntityDescriptor || $element instanceof EntitiesDescriptor) && !empty($parentExtensions['RegistrationInfo']) ) { $ret['RegistrationInfo'] = $parentExtensions['RegistrationInfo']; } foreach ($element->getExtensions() as $e) { if ($e instanceof Scope) { $ret['scope'][] = $e->getScope(); continue; } // Entity Attributes are only allowed at entity level extensions and not at RoleDescriptor level if ( $element instanceof EntityDescriptor || $element instanceof EntitiesDescriptor ) { if ($e instanceof RegistrationInfo) { // Registration Authority cannot be overridden (warn only if override attempts to change the value) if ( isset($ret['RegistrationInfo']['registrationAuthority']) && $ret['RegistrationInfo']['registrationAuthority'] !== $e->getRegistrationAuthority() ) { Logger::warning( 'Invalid attempt to override registrationAuthority \'' . $ret['RegistrationInfo']['registrationAuthority'] . "' with '{$e->getRegistrationAuthority()}'" ); } else { $ret['RegistrationInfo']['registrationAuthority'] = $e->getRegistrationAuthority(); } } if ($e instanceof EntityAttributes && !empty($e->getChildren())) { foreach ($e->getChildren() as $attr) { // only saml:Attribute are currently supported here. The specifications also allows // saml:Assertions, which more complex processing if ($attr instanceof Attribute) { /** @psalm-var string|null $attrName Remove for SSP 2.0 */ $attrName = $attr->getName(); $attrNameFormat = $attr->getNameFormat(); $attrValue = $attr->getAttributeValue(); if ($attrName === null || $attrValue === []) { continue; } // attribute names that is not URI is prefixed as this: '{nameformat}name' $name = $attrName; if ($attrNameFormat === null) { $name = '{' . Constants::NAMEFORMAT_UNSPECIFIED . '}' . $attrName; } elseif ($attrNameFormat !== Constants::NAMEFORMAT_URI) { $name = '{' . $attrNameFormat . '}' . $attrName; } $values = []; foreach ($attrValue as $attrval) { $values[] = $attrval->getString(); } $ret['EntityAttributes'][$name] = $values; } } } } // UIInfo elements are only allowed at RoleDescriptor level extensions if ($element instanceof RoleDescriptor) { if ($e instanceof UIInfo) { $ret['UIInfo']['DisplayName'] = $e->getDisplayName(); $ret['UIInfo']['Description'] = $e->getDescription(); $ret['UIInfo']['InformationURL'] = $e->getInformationURL(); $ret['UIInfo']['PrivacyStatementURL'] = $e->getPrivacyStatementURL(); foreach ($e->getKeywords() as $uiItem) { $keywords = $uiItem->getKeywords(); /** @psalm-var string|null $language */ $language = $uiItem->getLanguage(); if (($keywords === []) || ($language === null)) { continue; } $ret['UIInfo']['Keywords'][$language] = $keywords; } foreach ($e->getLogo() as $uiItem) { /** @psalm-suppress TypeDoesNotContainNull Remove in SSP 2.0 */ if ( !($uiItem instanceof Logo) || ($uiItem->getUrl() === null) || ($uiItem->getHeight() === null) || ($uiItem->getWidth() === null) ) { continue; } $logo = [ 'url' => $uiItem->getUrl(), 'height' => $uiItem->getHeight(), 'width' => $uiItem->getWidth(), ]; if ($uiItem->getLanguage() !== null) { $logo['lang'] = $uiItem->getLanguage(); } $ret['UIInfo']['Logo'][] = $logo; } } } // DiscoHints elements are only allowed at IDPSSODescriptor level extensions if ($element instanceof IDPSSODescriptor) { if ($e instanceof DiscoHints) { $ret['DiscoHints']['IPHint'] = $e->getIPHint(); $ret['DiscoHints']['DomainHint'] = $e->getDomainHint(); $ret['DiscoHints']['GeolocationHint'] = $e->getGeolocationHint(); } } if (!($e instanceof Chunk)) { continue; } if ($e->getLocalName() === 'Attribute' && $e->getNamespaceURI() === Constants::NS_SAML) { $attribute = $e->getXML(); $name = $attribute->getAttribute('Name'); $values = array_map( '\SimpleSAML\Utils\XML::getDOMText', Utils\XML::getDOMChildren($attribute, 'AttributeValue', '@saml2') ); if ($name === 'tags') { foreach ($values as $tagname) { if (!empty($tagname)) { $ret['tags'][] = $tagname; } } } } } return $ret; } /** * Parse and process a Organization element. * * @param \SAML2\XML\md\Organization $element The Organization element. * @return void */ private function processOrganization(Organization $element): void { $this->organizationName = $element->getOrganizationName(); $this->organizationDisplayName = $element->getOrganizationDisplayName(); $this->organizationURL = $element->getOrganizationURL(); } /** * Parse and process a ContactPerson element. * * @param \SAML2\XML\md\ContactPerson $element The ContactPerson element. * @return void */ private function processContactPerson(ContactPerson $element): void { $contactPerson = []; if ($element->getContactType() !== '') { $contactPerson['contactType'] = $element->getContactType(); } if ($element->getCompany() !== null) { $contactPerson['company'] = $element->getCompany(); } if ($element->getGivenName() !== null) { $contactPerson['givenName'] = $element->getGivenName(); } if ($element->getSurName() !== null) { $contactPerson['surName'] = $element->getSurName(); } if ($element->getEmailAddress() !== []) { $contactPerson['emailAddress'] = $element->getEmailAddress(); } if ($element->getTelephoneNumber() !== []) { $contactPerson['telephoneNumber'] = $element->getTelephoneNumber(); } if (!empty($contactPerson)) { $this->contacts[] = $contactPerson; } } /** * This function parses AttributeConsumerService elements. * * @param \SAML2\XML\md\AttributeConsumingService $element The AttributeConsumingService to parse. * @param array $sp The array with the SP's metadata. * @return void */ private static function parseAttributeConsumerService(AttributeConsumingService $element, array &$sp): void { $sp['name'] = $element->getServiceName(); $sp['description'] = $element->getServiceDescription(); $format = null; $sp['attributes'] = []; $sp['attributes.required'] = []; foreach ($element->getRequestedAttribute() as $child) { $attrname = $child->getName(); $sp['attributes'][] = $attrname; if ($child->getIsRequired() === true) { $sp['attributes.required'][] = $attrname; } if ($child->getNameFormat() !== null) { $attrformat = $child->getNameFormat(); } else { $attrformat = Constants::NAMEFORMAT_UNSPECIFIED; } if ($format === null) { $format = $attrformat; } elseif ($format !== $attrformat) { $format = Constants::NAMEFORMAT_UNSPECIFIED; } } if (empty($sp['attributes'])) { // a really invalid configuration: all AttributeConsumingServices should have one or more attributes unset($sp['attributes']); } if (empty($sp['attributes.required'])) { unset($sp['attributes.required']); } if ($format !== Constants::NAMEFORMAT_UNSPECIFIED && $format !== null) { $sp['attributes.NameFormat'] = $format; } } /** * This function is a generic endpoint element parser. * * The returned associative array has the following elements: * - 'Binding': The binding this endpoint uses. * - 'Location': The URL to this endpoint. * - 'ResponseLocation': The URL where responses should be sent. This may not exist. * - 'index': The index of this endpoint. This attribute is only for indexed endpoints. * - 'isDefault': Whether this endpoint is the default endpoint for this type. This attribute may not exist. * * @param \SAML2\XML\md\EndpointType $element The element which should be parsed. * * @return array An associative array with the data we have extracted from the element. */ private static function parseGenericEndpoint(EndpointType $element): array { $ep = []; $ep['Binding'] = $element->getBinding(); $ep['Location'] = $element->getLocation(); if ($element->getResponseLocation() !== null) { $ep['ResponseLocation'] = $element->getResponseLocation(); } if ($element instanceof IndexedEndpointType) { $ep['index'] = $element->getIndex(); if ($element->getIsDefault() !== null) { $ep['isDefault'] = $element->getIsDefault(); } } return $ep; } /** * Extract generic endpoints. * * @param array $endpoints The endpoints we should parse. * * @return array Array of parsed endpoints. */ private static function extractEndpoints(array $endpoints): array { return array_map('self::parseGenericEndpoint', $endpoints); } /** * This function parses a KeyDescriptor element. It currently only supports keys with a single * X509 certificate. * * The associative array for a key can contain: * - 'encryption': Indicates whether this key can be used for encryption. * - 'signing': Indicates whether this key can be used for signing. * - 'type: The type of the key. 'X509Certificate' is the only key type we support. * - 'X509Certificate': The contents of the first X509Certificate element (if the type is 'X509Certificate '). * * @param \SAML2\XML\md\KeyDescriptor $kd The KeyDescriptor element. * * @return array|null An associative array describing the key, or null if this is an unsupported key. */ private static function parseKeyDescriptor(KeyDescriptor $kd): ?array { $r = []; if ($kd->getUse() === 'encryption') { $r['encryption'] = true; $r['signing'] = false; } elseif ($kd->getUse() === 'signing') { $r['encryption'] = false; $r['signing'] = true; } else { $r['encryption'] = true; $r['signing'] = true; } $keyInfo = $kd->getKeyInfo(); /** @psalm-suppress PossiblyNullReference This will be fixed in saml2 5.0 */ foreach ($keyInfo->getInfo() as $i) { if ($i instanceof X509Data) { foreach ($i->getData() as $d) { if ($d instanceof X509Certificate) { $r['type'] = 'X509Certificate'; $r['X509Certificate'] = $d->getCertificate(); return $r; } } } } return null; } /** * This function finds SP descriptors which supports one of the given protocols. * * @param array $protocols Array with the protocols we accept. * * @return array with SP descriptors which supports one of the given protocols. */ private function getSPDescriptors(array $protocols): array { $ret = []; foreach ($this->spDescriptors as $spd) { $sharedProtocols = array_intersect($protocols, $spd['protocols']); if (count($sharedProtocols) > 0) { $ret[] = $spd; } } return $ret; } /** * This function finds IdP descriptors which supports one of the given protocols. * * @param array $protocols Array with the protocols we accept. * * @return array with IdP descriptors which supports one of the given protocols. */ private function getIdPDescriptors(array $protocols): array { $ret = []; foreach ($this->idpDescriptors as $idpd) { $sharedProtocols = array_intersect($protocols, $idpd['protocols']); if (count($sharedProtocols) > 0) { $ret[] = $idpd; } } return $ret; } /** * This function locates the EntityDescriptor node in a DOMDocument. This node should * be the first (and only) node in the document. * * This function will throw an exception if it is unable to locate the node. * * @param \DOMDocument $doc The \DOMDocument where we should find the EntityDescriptor node. * * @return \SAML2\XML\md\EntityDescriptor The \DOMEntity which represents the EntityDescriptor. * @throws \Exception If the document is empty or the first element is not an EntityDescriptor element. */ private static function findEntityDescriptor(DOMDocument $doc): EntityDescriptor { // find the EntityDescriptor DOMElement. This should be the first (and only) child of the DOMDocument $ed = $doc->documentElement; if (Utils\XML::isDOMNodeOfType($ed, 'EntityDescriptor', '@md') === false) { throw new \Exception('Expected first element in the metadata document to be an EntityDescriptor element.'); } return new EntityDescriptor($ed); } /** * If this EntityDescriptor was signed this function use the public key to check the signature. * * @param array $certificates One ore more certificates with the public key. This makes it possible * to do a key rollover. * * @return boolean True if it is possible to check the signature with the certificate, false otherwise. * @throws \Exception If the certificate file cannot be found. */ public function validateSignature($certificates) { foreach ($certificates as $cert) { assert(is_string($cert)); $certFile = Utils\Config::getCertPath($cert); if (!file_exists($certFile)) { throw new \Exception( 'Could not find certificate file [' . $certFile . '], which is needed to validate signature' ); } $certData = file_get_contents($certFile); foreach ($this->validators as $validator) { $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'public']); $key->loadKey($certData); try { if ($validator->validate($key)) { return true; } } catch (\Exception $e) { // this certificate did not sign this element, skip } } } Logger::debug('Could not validate signature'); return false; } /** * @param string $algorithm * @param string $data * @throws \UnexpectedValueException * @return string */ private function computeFingerprint(string $algorithm, string $data): string { switch ($algorithm) { case XMLSecurityDSig::SHA1: $algo = 'SHA1'; break; case XMLSecurityDSig::SHA256: $algo = 'SHA256'; break; case XMLSecurityDSig::SHA384: $algo = 'SHA384'; break; case XMLSecurityDSig::SHA512: $algo = 'SHA512'; break; default: $known_opts = implode(", ", [ XMLSecurityDSig::SHA1, XMLSecurityDSig::SHA256, XMLSecurityDSig::SHA384, XMLSecurityDSig::SHA512, ]); throw new \UnexpectedValueException( "Unsupported hashing function {$algorithm}. " . "Known options: [{$known_opts}]" ); } return hash($algo, $data); } /** * This function checks if this EntityDescriptor was signed with a certificate with the * given fingerprint. * * @param string $fingerprint Fingerprint of the certificate which should have been used to sign this * EntityDescriptor. * @param string $algorithm Algorithm used to compute the fingerprint of the signing certicate. * * @return boolean True if it was signed with the certificate with the given fingerprint, false otherwise. */ public function validateFingerprint($fingerprint, $algorithm) { assert(is_string($fingerprint)); $fingerprint = strtolower(str_replace(":", "", $fingerprint)); $candidates = []; foreach ($this->validators as $validator) { foreach ($validator->getValidatingCertificates() as $cert) { $decoded_cert = base64_decode($cert); $fp = $this->computeFingerprint($algorithm, $decoded_cert); $candidates[] = $fp; if ($fp === $fingerprint) { return true; } } } Logger::debug('Fingerprint was [' . $fingerprint . '] not one of [' . join(', ', $candidates) . ']'); return false; } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatFile.php0000644000000000000000000000775314042503475026016 0ustar rootroot * @package SimpleSAMLphp */ class MetaDataStorageHandlerFlatFile extends MetaDataStorageSource { /** * This is the directory we will load metadata files from. The path will always end * with a '/'. * * @var string */ private $directory = '/'; /** * This is an associative array which stores the different metadata sets we have loaded. * * @var array */ private $cachedMetadata = []; /** * This constructor initializes the flatfile metadata storage handler with the * specified configuration. The configuration is an associative array with the following * possible elements: * - 'directory': The directory we should load metadata from. The default directory is * set in the 'metadatadir' configuration option in 'config.php'. * * @param array $config An associative array with the configuration for this handler. */ protected function __construct($config) { assert(is_array($config)); // get the configuration $globalConfig = Configuration::getInstance(); // find the path to the directory we should search for metadata in if (array_key_exists('directory', $config)) { $this->directory = $config['directory'] ?: 'metadata/'; } else { $this->directory = $globalConfig->getString('metadatadir', 'metadata/'); } /* Resolve this directory relative to the SimpleSAMLphp directory (unless it is * an absolute path). */ /** @var string $base */ $base = $globalConfig->resolvePath($this->directory); $this->directory = $base . '/'; } /** * This function loads the given set of metadata from a file our metadata directory. * This function returns null if it is unable to locate the given set in the metadata directory. * * @param string $set The set of metadata we are loading. * * @return array|null An associative array with the metadata, * or null if we are unable to load metadata from the given file. * @throws \Exception If the metadata set cannot be loaded. */ private function load(string $set): ?array { $metadatasetfile = $this->directory . $set . '.php'; if (!file_exists($metadatasetfile)) { return null; } /** @psalm-var mixed $metadata We cannot be sure what the include below will do with this var */ $metadata = []; include($metadatasetfile); if (!is_array($metadata)) { throw new \Exception('Could not load metadata set [' . $set . '] from file: ' . $metadatasetfile); } return $metadata; } /** * This function retrieves the given set of metadata. It will return an empty array if it is * unable to locate it. * * @param string $set The set of metadata we are retrieving. * * @return array An associative array with the metadata. Each element in the array is an entity, and the * key is the entity id. */ public function getMetadataSet($set) { if (array_key_exists($set, $this->cachedMetadata)) { return $this->cachedMetadata[$set]; } /** @var array|null $metadataSet */ $metadataSet = $this->load($set); if ($metadataSet === null) { $metadataSet = []; } // add the entity id of an entry to each entry in the metadata foreach ($metadataSet as $entityId => &$entry) { $entry = $this->updateEntityID($set, $entityId, $entry); } $this->cachedMetadata[$set] = $metadataSet; return $metadataSet; } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php0000644000000000000000000002077714042503475026260 0ustar rootrootdirectory = $cfgHelp->getString('directory'); /* Resolve this directory relative to the SimpleSAMLphp directory (unless it is * an absolute path). */ $this->directory = Utils\System::resolvePath($this->directory, $globalConfig->getBaseDir()); } /** * Helper function for retrieving the path of a metadata file. * * @param string $entityId The entity ID. * @param string $set The metadata set. * * @return string The path to the metadata file. */ private function getMetadataPath(string $entityId, string $set): string { return $this->directory . '/' . rawurlencode($set) . '/' . rawurlencode($entityId) . self::EXTENSION; } /** * Retrieve a list of all available metadata sets. * * @return array An array with the available sets. */ public function getMetadataSets() { $ret = []; $dh = @opendir($this->directory); if ($dh === false) { Logger::warning( 'Serialize metadata handler: Unable to open directory: ' . var_export($this->directory, true) ); return $ret; } while (($entry = readdir($dh)) !== false) { if ($entry[0] === '.') { // skip '..', '.' and hidden files continue; } $path = $this->directory . '/' . $entry; if (!is_dir($path)) { Logger::warning( 'Serialize metadata handler: Metadata directory contained a file where only directories should ' . 'exist: ' . var_export($path, true) ); continue; } $ret[] = rawurldecode($entry); } closedir($dh); return $ret; } /** * Retrieve a list of all available metadata for a given set. * * @param string $set The set we are looking for metadata in. * * @return array An associative array with all the metadata for the given set. */ public function getMetadataSet($set) { assert(is_string($set)); $ret = []; $dir = $this->directory . '/' . rawurlencode($set); if (!is_dir($dir)) { // probably some code asked for a metadata set which wasn't available return $ret; } $dh = @opendir($dir); if ($dh === false) { Logger::warning( 'Serialize metadata handler: Unable to open directory: ' . var_export($dir, true) ); return $ret; } $extLen = strlen(self::EXTENSION); while (($file = readdir($dh)) !== false) { if (strlen($file) <= $extLen) { continue; } if (substr($file, -$extLen) !== self::EXTENSION) { continue; } $entityId = substr($file, 0, -$extLen); $entityId = rawurldecode($entityId); $md = $this->getMetaData($entityId, $set); if ($md !== null) { $ret[$entityId] = $md; } } closedir($dh); return $ret; } /** * Retrieve a metadata entry. * * @param string $index The entityId we are looking up. * @param string $set The set we are looking for metadata in. * * @return array|null An associative array with metadata for the given entity, or NULL if we are unable to * locate the entity. */ public function getMetaData($index, $set) { assert(is_string($index)); assert(is_string($set)); $filePath = $this->getMetadataPath($index, $set); if (!file_exists($filePath)) { return null; } $data = @file_get_contents($filePath); if ($data === false) { /** @var array $error */ $error = error_get_last(); Logger::warning( 'Error reading file ' . $filePath . ': ' . $error['message'] ); return null; } $data = @unserialize($data); if ($data === false) { Logger::warning('Error unserializing file: ' . $filePath); return null; } if (!array_key_exists('entityid', $data)) { $data['entityid'] = $index; } return $data; } /** * Save a metadata entry. * * @param string $entityId The entityId of the metadata entry. * @param string $set The metadata set this metadata entry belongs to. * @param array $metadata The metadata. * * @return bool True if successfully saved, false otherwise. */ public function saveMetadata($entityId, $set, $metadata) { assert(is_string($entityId)); assert(is_string($set)); assert(is_array($metadata)); $filePath = $this->getMetadataPath($entityId, $set); $newPath = $filePath . '.new'; $dir = dirname($filePath); if (!is_dir($dir)) { Logger::info('Creating directory: ' . $dir); $res = @mkdir($dir, 0777, true); if ($res === false) { /** @var array $error */ $error = error_get_last(); Logger::error('Failed to create directory ' . $dir . ': ' . $error['message']); return false; } } $data = serialize($metadata); Logger::debug('Writing: ' . $newPath); $res = file_put_contents($newPath, $data); if ($res === false) { /** @var array $error */ $error = error_get_last(); Logger::error('Error saving file ' . $newPath . ': ' . $error['message']); return false; } $res = rename($newPath, $filePath); if ($res === false) { /** @var array $error */ $error = error_get_last(); Logger::error('Error renaming ' . $newPath . ' to ' . $filePath . ': ' . $error['message']); return false; } return true; } /** * Delete a metadata entry. * * @param string $entityId The entityId of the metadata entry. * @param string $set The metadata set this metadata entry belongs to. * @return void */ public function deleteMetadata($entityId, $set) { assert(is_string($entityId)); assert(is_string($set)); $filePath = $this->getMetadataPath($entityId, $set); if (!file_exists($filePath)) { Logger::warning( 'Attempted to erase nonexistent metadata entry ' . var_export($entityId, true) . ' in set ' . var_export($set, true) . '.' ); return; } $res = unlink($filePath); if ($res === false) { /** @var array $error */ $error = error_get_last(); Logger::error( 'Failed to delete file ' . $filePath . ': ' . $error['message'] ); } } /** * This function loads the metadata for entity IDs in $entityIds. It is returned as an associative array * where the key is the entity id. An empty array may be returned if no matching entities were found * @param array $entityIds The entity ids to load * @param string $set The set we want to get metadata from. * @return array An associative array with the metadata for the requested entities, if found. */ public function getMetaDataForEntities(array $entityIds, $set) { return $this->getMetaDataForEntitiesIndividually($entityIds, $set); } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/Signer.php0000644000000000000000000002754514042503475021334 0ustar rootroot $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 = ['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 = [ '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'] . '".' ); } /** * Determine whether metadata signing is enabled for the given metadata. * * @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 boolean True if metadata signing is enabled, false otherwise. * @throws \Exception If the value of the 'metadata.sign.enable' option is not a boolean. */ private static function isMetadataSigningEnabled(Configuration $config, array $entityMetadata, string $type): bool { // first check the metadata for the entity if (array_key_exists('metadata.sign.enable', $entityMetadata)) { if (!is_bool($entityMetadata['metadata.sign.enable'])) { throw new \Exception( 'Invalid value for the "metadata.sign.enable" configuration option for' . ' the ' . $type . ' "' . $entityMetadata['entityid'] . '". This option' . ' should be a boolean.' ); } return $entityMetadata['metadata.sign.enable']; } $enabled = $config->getBoolean('metadata.sign.enable', false); return $enabled; } /** * Determine the signature and digest algorithms to use when signing metadata. * * This method will look for the 'metadata.sign.algorithm' key in the $entityMetadata array, or look for such * a configuration option in the $config object. * * @param \SimpleSAML\Configuration $config The global configuration. * @param array $entityMetadata An array containing the metadata related to this entity. * @param string $type A string describing the type of entity. E.g. 'SAML 2 IdP' or 'Shib 1.3 SP'. * * @return array An array with two keys, 'algorithm' and 'digest', corresponding to the signature and digest * algorithms to use, respectively. * * @throws \SimpleSAML\Error\CriticalConfigurationError */ private static function getMetadataSigningAlgorithm( Configuration $config, array $entityMetadata, string $type ): array { // configure the algorithm to use if (array_key_exists('metadata.sign.algorithm', $entityMetadata)) { if (!is_string($entityMetadata['metadata.sign.algorithm'])) { throw new Error\CriticalConfigurationError( "Invalid value for the 'metadata.sign.algorithm' configuration option for the " . $type . "'" . $entityMetadata['entityid'] . "'. This option has restricted values" ); } $alg = $entityMetadata['metadata.sign.algorithm']; } else { $alg = $config->getString('metadata.sign.algorithm', XMLSecurityKey::RSA_SHA256); } $supported_algs = [ XMLSecurityKey::RSA_SHA1, XMLSecurityKey::RSA_SHA256, XMLSecurityKey::RSA_SHA384, XMLSecurityKey::RSA_SHA512, ]; if (!in_array($alg, $supported_algs, true)) { throw new Error\CriticalConfigurationError("Unknown signature algorithm '$alg'"); } switch ($alg) { case XMLSecurityKey::RSA_SHA256: $digest = XMLSecurityDSig::SHA256; break; case XMLSecurityKey::RSA_SHA384: $digest = XMLSecurityDSig::SHA384; break; case XMLSecurityKey::RSA_SHA512: $digest = XMLSecurityDSig::SHA512; break; default: $digest = XMLSecurityDSig::SHA1; } return [ 'algorithm' => $alg, 'digest' => $digest, ]; } /** * Signs the given metadata if metadata signing is enabled. * * @param string $metadataString A string with the metadata. * @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 string The $metadataString with the signature embedded. * @throws \Exception If the certificate or private key cannot be loaded, or the metadata doesn't parse properly. */ public static function sign($metadataString, $entityMetadata, $type) { $config = Configuration::getInstance(); // check if metadata signing is enabled if (!self::isMetadataSigningEnabled($config, $entityMetadata, $type)) { return $metadataString; } // find the key & certificate which should be used to sign the metadata $keyCertFiles = self::findKeyCert($config, $entityMetadata, $type); $keyFile = Utils\Config::getCertPath($keyCertFiles['privatekey']); if (!file_exists($keyFile)) { throw new \Exception( 'Could not find private key file [' . $keyFile . '], which is needed to sign the metadata' ); } $keyData = file_get_contents($keyFile); $certFile = Utils\Config::getCertPath($keyCertFiles['certificate']); if (!file_exists($certFile)) { throw new \Exception( 'Could not find certificate file [' . $certFile . '], which is needed to sign the metadata' ); } $certData = file_get_contents($certFile); // convert the metadata to a DOM tree try { $xml = DOMDocumentFactory::fromString($metadataString); } catch (\Exception $e) { throw new \Exception('Error parsing self-generated metadata.'); } $signature_cf = self::getMetadataSigningAlgorithm($config, $entityMetadata, $type); // load the private key $objKey = new XMLSecurityKey($signature_cf['algorithm'], ['type' => 'private']); if (array_key_exists('privatekey_pass', $keyCertFiles)) { $objKey->passphrase = $keyCertFiles['privatekey_pass']; } $objKey->loadKey($keyData, false); // get the EntityDescriptor node we should sign /** @var \DOMElement $rootNode */ $rootNode = $xml->firstChild; $rootNode->setAttribute('ID', '_' . hash('sha256', $metadataString)); // sign the metadata with our private key $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList( [$rootNode], $signature_cf['digest'], ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N], ['id_name' => 'ID', 'overwrite' => false] ); $objXMLSecDSig->sign($objKey); // add the certificate to the signature $objXMLSecDSig->add509Cert($certData, true); // add the signature to the metadata $objXMLSecDSig->insertSignature($rootNode, $rootNode->firstChild); // return the DOM tree as a string return $xml->saveXML(); } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageSource.php0000644000000000000000000003254514042503475024267 0ustar rootrootgetMetadataSet($set); /** @psalm-suppress DocblockTypeContradiction */ if ($metadataSet === null) { // this metadata source does not have this metadata set return null; } foreach ($metadataSet as $index => $entry) { if (!array_key_exists('host', $entry)) { continue; } if ($hostPath === $entry['host']) { if ($type === 'entityid') { return $entry['entityid']; } else { return $index; } } } // no entries matched, we should return null return null; } /** * This function will go through all the metadata, and check the DiscoHints->IPHint * parameter, which defines a network space (ip range) for each remote entry. * This function returns the entityID for any of the entities that have an * IP range which the IP falls within. * * @param string $set Which set of metadata we are looking it up in. * @param string $ip IP address * @param string $type Do you want to return the metaindex or the entityID. [entityid|metaindex] * * @return string|null The entity id of a entity which have a CIDR hint where the provided * IP address match. */ public function getPreferredEntityIdFromCIDRhint($set, $ip, $type = 'entityid') { $metadataSet = $this->getMetadataSet($set); foreach ($metadataSet as $index => $entry) { $cidrHints = []; // support hint.cidr for idp discovery if (array_key_exists('hint.cidr', $entry) && is_array($entry['hint.cidr'])) { $cidrHints = $entry['hint.cidr']; } // support discohints in idp metadata for idp discovery if ( array_key_exists('DiscoHints', $entry) && array_key_exists('IPHint', $entry['DiscoHints']) && is_array($entry['DiscoHints']['IPHint']) ) { // merge with hints derived from discohints, but prioritize hint.cidr in case it is used $cidrHints = array_merge($entry['DiscoHints']['IPHint'], $cidrHints); } if (empty($cidrHints)) { continue; } foreach ($cidrHints as $hint_entry) { if (Utils\Net::ipCIDRcheck($hint_entry, $ip)) { if ($type === 'entityid') { return $entry['entityid']; } else { return $index; } } } } // no entries matched, we should return null return null; } /** * This function retrieves metadata for the given entity id in the given set of metadata. * It will return NULL if it is unable to locate the metadata. * * This class implements this function using the getMetadataSet-function. A subclass should * override this function if it doesn't implement the getMetadataSet function, or if the * implementation of getMetadataSet is slow. * * @param string $index The entityId or metaindex we are looking up. * @param string $set The set we are looking for metadata in. * * @return array|null An associative array with metadata for the given entity, or NULL if we are unable to * locate the entity. */ public function getMetaData($index, $set) { assert(is_string($index)); assert(isset($set)); $metadataSet = $this->getMetadataSet($set); $indexLookup = $this->lookupIndexFromEntityId($index, $metadataSet); if (isset($indexLookup) && array_key_exists($indexLookup, $metadataSet)) { return $metadataSet[$indexLookup]; } return null; } /** * This function loads the metadata for entity IDs in $entityIds. It is returned as an associative array * where the key is the entity id. An empty array may be returned if no matching entities were found. * Subclasses should override if their getMetadataSet returns nothing or is slow. Subclasses may want to * delegate to getMetaDataForEntitiesIndividually if loading entities one at a time is faster. * @param array $entityIds The entity ids to load * @param string $set The set we want to get metadata from. * @return array An associative array with the metadata for the requested entities, if found. */ public function getMetaDataForEntities(array $entityIds, $set) { if (count($entityIds) === 1) { return $this->getMetaDataForEntitiesIndividually($entityIds, $set); } $entities = $this->getMetadataSet($set); return array_intersect_key($entities, array_flip($entityIds)); } /** * Loads metadata entities one at a time, rather than the default implementation of loading all entities * and filtering. * @see MetaDataStorageSource::getMetaDataForEntities() * @param array $entityIds The entity ids to load * @param string $set The set we want to get metadata from. * @return array An associative array with the metadata for the requested entities, if found. */ protected function getMetaDataForEntitiesIndividually(array $entityIds, $set) { $entities = []; foreach ($entityIds as $entityId) { $metadata = $this->getMetaData($entityId, $set); if ($metadata !== null) { $entities[$entityId] = $metadata; } } return $entities; } /** * This method returns the full metadata set for a given entity id or null if the entity id cannot be found * in the given metadata set. * * @param string $entityId * @param array $metadataSet the already loaded metadata set * @return mixed|null */ protected function lookupIndexFromEntityId($entityId, array $metadataSet) { assert(is_string($entityId)); // check for hostname $currentHost = Utils\HTTP::getSelfHost(); // sp.example.org foreach ($metadataSet as $index => $entry) { // explicit index match if ($index === $entityId) { return $index; } if ($entry['entityid'] === $entityId) { if ($entry['host'] === '__DEFAULT__' || $entry['host'] === $currentHost) { return $index; } } } return null; } /** * @param string $set * @throws \Exception * @return string */ private function getDynamicHostedUrl(string $set): string { // get the configuration $baseUrl = Utils\HTTP::getBaseURL(); if ($set === 'saml20-idp-hosted') { return $baseUrl . 'saml2/idp/metadata.php'; } elseif ($set === 'saml20-sp-hosted') { return $baseUrl . 'saml2/sp/metadata.php'; } elseif ($set === 'shib13-idp-hosted') { return $baseUrl . 'shib13/idp/metadata.php'; } elseif ($set === 'shib13-sp-hosted') { return $baseUrl . 'shib13/sp/metadata.php'; } elseif ($set === 'adfs-idp-hosted') { return 'urn:federation:' . Utils\HTTP::getSelfHost() . ':idp'; } else { throw new \Exception('Can not generate dynamic EntityID for metadata of this type: [' . $set . ']'); } } /** * Updates the metadata entry's entity id and returns the modified array. If the entity id is __DYNAMIC:*__ a * the current url is assigned. If it is explicit the entityid array key is updated to the entityId that was * provided. * * @param string $metadataSet a metadata set (saml20-idp-hosted, saml20-sp-remote, etc) * @param string $entityId the entity id we are modifying * @param array $metadataEntry the fully populated metadata entry * @return array modified metadata to include the valid entityid * * @throws \Exception */ protected function updateEntityID($metadataSet, $entityId, array $metadataEntry) { assert(is_string($metadataSet)); assert(is_string($entityId)); $modifiedMetadataEntry = $metadataEntry; // generate a dynamic hosted url if (preg_match('/__DYNAMIC(:[0-9]+)?__/', $entityId)) { $modifiedMetadataEntry['entityid'] = $this->getDynamicHostedUrl($metadataSet); } else { // set the entityid metadata array key to the provided entity id $modifiedMetadataEntry['entityid'] = $entityId; } return $modifiedMetadataEntry; } } simplesamlphp-1.19.1/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php0000644000000000000000000002321514042503475025041 0ustar rootrootdb = Database::getInstance(); } /** * This function loads the given set of metadata from a file to a configured database. * This function returns NULL if it is unable to locate the given set in the metadata directory. * * @param string $set The set of metadata we are loading. * * @return array|null $metadata Associative array with the metadata, or NULL if we are unable to load * metadata from the given file. * * @throws \Exception If a database error occurs. * @throws \SimpleSAML\Error\Exception If the metadata can be retrieved from the database, but cannot be decoded. */ private function load(string $set): ?array { $tableName = $this->getTableName($set); if (!in_array($set, $this->supportedSets, true)) { return null; } $stmt = $this->db->read("SELECT entity_id, entity_data FROM $tableName"); if ($stmt->execute()) { $metadata = []; while ($d = $stmt->fetch()) { $data = json_decode($d['entity_data'], true); if ($data === null) { throw new Error\Exception("Cannot decode metadata for entity '${d['entity_id']}'"); } if (!array_key_exists('entityid', $data)) { $data['entityid'] = $d['entity_id']; } $metadata[$d['entity_id']] = $data; } return $metadata; } else { throw new \Exception( 'PDO metadata handler: Database error: ' . var_export($this->db->getLastError(), true) ); } } /** * Retrieve a list of all available metadata for a given set. * * @param string $set The set we are looking for metadata in. * * @return array $metadata An associative array with all the metadata for the given set. */ public function getMetadataSet($set) { assert(is_string($set)); if (array_key_exists($set, $this->cachedMetadata)) { return $this->cachedMetadata[$set]; } $metadataSet = $this->load($set); if ($metadataSet === null) { $metadataSet = []; } /** @var array $metadataSet */ foreach ($metadataSet as $entityId => &$entry) { $entry = $this->updateEntityID($set, $entityId, $entry); } $this->cachedMetadata[$set] = $metadataSet; return $metadataSet; } /** * Retrieve a metadata entry. * * @param string $index The entityId we are looking up. * @param string $set The set we are looking for metadata in. * * @return array|null An associative array with metadata for the given entity, or NULL if we are unable to * locate the entity. */ public function getMetaData($index, $set) { assert(is_string($index)); assert(is_string($set)); // validate the metadata set is valid if (!in_array($set, $this->supportedSets, true)) { return null; } // support caching if (isset($this->cachedMetadata[$index][$set])) { return $this->cachedMetadata[$index][$set]; } $tableName = $this->getTableName($set); // according to the docs, it looks like *-idp-hosted metadata are the types // that allow the __DYNAMIC:*__ entity id. with the current table design // we need to lookup the specific metadata entry but also we need to lookup // any dynamic entries to see if the dynamic hosted entity id matches if (substr($set, -10) == 'idp-hosted') { $stmt = $this->db->read( "SELECT entity_id, entity_data FROM {$tableName} " . "WHERE (entity_id LIKE :dynamicId OR entity_id = :entityId)", ['dynamicId' => '__DYNAMIC%', 'entityId' => $index] ); } else { // other metadata types should be able to match on entity id $stmt = $this->db->read( "SELECT entity_id, entity_data FROM {$tableName} WHERE entity_id = :entityId", ['entityId' => $index] ); } // throw pdo exception upon execution failure if (!$stmt->execute()) { throw new \Exception( 'PDO metadata handler: Database error: ' . var_export($this->db->getLastError(), true) ); } // load the metadata into an array $metadataSet = []; while ($d = $stmt->fetch()) { $data = json_decode($d['entity_data'], true); if (json_last_error() != JSON_ERROR_NONE) { throw new \SimpleSAML\Error\Exception( "Cannot decode metadata for entity '${d['entity_id']}'" ); } // update the entity id to either the key (if not dynamic or generate the dynamic hosted url) $metadataSet[$d['entity_id']] = $this->updateEntityID($set, $index, $data); } $indexLookup = $this->lookupIndexFromEntityId($index, $metadataSet); if (isset($indexLookup) && array_key_exists($indexLookup, $metadataSet)) { $this->cachedMetadata[$indexLookup][$set] = $metadataSet[$indexLookup]; return $this->cachedMetadata[$indexLookup][$set]; } return null; } /** * Add metadata to the configured database * * @param string $index Entity ID * @param string $set The set to add the metadata to * @param array $entityData Metadata * * @return bool True/False if entry was successfully added */ public function addEntry($index, $set, $entityData) { assert(is_string($index)); assert(is_string($set)); assert(is_array($entityData)); if (!in_array($set, $this->supportedSets, true)) { return false; } $tableName = $this->getTableName($set); $metadata = $this->db->read( "SELECT entity_id, entity_data FROM $tableName WHERE entity_id = :entity_id", [ 'entity_id' => $index, ] ); $retrivedEntityIDs = $metadata->fetch(); $params = [ 'entity_id' => $index, 'entity_data' => json_encode($entityData), ]; if ($retrivedEntityIDs !== false && count($retrivedEntityIDs) > 0) { $rows = $this->db->write( "UPDATE $tableName SET entity_data = :entity_data WHERE entity_id = :entity_id", $params ); } else { $rows = $this->db->write( "INSERT INTO $tableName (entity_id, entity_data) VALUES (:entity_id, :entity_data)", $params ); } return $rows === 1; } /** * Replace the -'s to an _ in table names for Metadata sets * since SQL does not allow a - in a table name. * * @param string $table Table * * @return string Replaced table name */ private function getTableName(string $table): string { return $this->db->applyPrefix(str_replace("-", "_", $this->tablePrefix . $table)); } /** * Initialize the configured database * * @return int|false The number of SQL statements successfully executed, false if some error occurred. */ public function initDatabase() { $stmt = 0; $fine = true; foreach ($this->supportedSets as $set) { $tableName = $this->getTableName($set); $rows = $this->db->write( "CREATE TABLE IF NOT EXISTS $tableName (entity_id VARCHAR(255) PRIMARY KEY NOT NULL, entity_data " . "TEXT NOT NULL)" ); if ($rows === false) { $fine = false; } else { $stmt += $rows; } } if (!$fine) { return false; } return $stmt; } } simplesamlphp-1.19.1/lib/SimpleSAML/IdP.php0000644000000000000000000004002014042503475017020 0ustar rootrootid = $id; $this->associationGroup = $id; $metadata = MetaDataStorageHandler::getMetadataHandler(); $globalConfig = Configuration::getInstance(); if (substr($id, 0, 6) === 'saml2:') { if (!$globalConfig->getBoolean('enable.saml20-idp', false)) { throw new 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 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 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 { throw new \Exception("Protocol not implemented."); } $auth = $this->config->getString('auth'); if (Auth\Source::getById($auth) !== null) { $this->authSource = new Auth\Simple($auth); } else { throw new Error\Exception('No such "' . $auth . '" auth source found.'); } } /** * Retrieve the ID of this IdP. * * @return string The ID of this IdP. */ public function getId() { return $this->id; } /** * Retrieve an IdP by ID. * * @param string $id The identifier of the IdP. * * @return IdP The IdP. */ public static function getById($id) { assert(is_string($id)); if (isset(self::$idpCache[$id])) { return self::$idpCache[$id]; } $idp = new self($id); self::$idpCache[$id] = $idp; return $idp; } /** * Retrieve the IdP "owning" the state. * * @param array &$state The state array. * * @return IdP The IdP. */ public static function getByState(array &$state) { assert(isset($state['core:IdP'])); return self::getById($state['core:IdP']); } /** * Retrieve the configuration for this IdP. * * @return Configuration The configuration object. */ public function getConfig() { return $this->config; } /** * Get SP name. * * @param string $assocId The association identifier. * * @return array|null The name of the SP, as an associative array of language => text, or null if this isn't an SP. */ public function getSPName($assocId) { assert(is_string($assocId)); $prefix = substr($assocId, 0, 4); $spEntityId = substr($assocId, strlen($prefix) + 1); $metadata = MetaDataStorageHandler::getMetadataHandler(); if ($prefix === 'saml') { try { $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote'); } catch (\Exception $e) { try { $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'shib13-sp-remote'); } catch (\Exception $e) { return null; } } } else { if ($prefix === 'adfs') { $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'adfs-sp-remote'); } else { return null; } } if ($spMetadata->hasValue('name')) { return $spMetadata->getLocalizedString('name'); } elseif ($spMetadata->hasValue('OrganizationDisplayName')) { return $spMetadata->getLocalizedString('OrganizationDisplayName'); } else { return ['en' => $spEntityId]; } } /** * Add an SP association. * * @param array $association The SP association. * @return void */ public function addAssociation(array $association) { assert(isset($association['id'])); assert(isset($association['Handler'])); $association['core:IdP'] = $this->id; $session = Session::getSessionFromRequest(); $session->addAssociation($this->associationGroup, $association); } /** * Retrieve list of SP associations. * * @return array List of SP associations. */ public function getAssociations() { $session = Session::getSessionFromRequest(); return $session->getAssociations($this->associationGroup); } /** * Remove an SP association. * * @param string $assocId The association id. * @return void */ public function terminateAssociation($assocId) { assert(is_string($assocId)); $session = Session::getSessionFromRequest(); $session->terminateAssociation($this->associationGroup, $assocId); } /** * Is the current user authenticated? * * @return boolean True if the user is authenticated, false otherwise. */ public function isAuthenticated() { return $this->authSource->isAuthenticated(); } /** * Called after authproc has run. * * @param array $state The authentication request state array. * @return void */ public static function postAuthProc(array $state) { assert(is_callable($state['Responder'])); if (isset($state['core:SP'])) { $session = Session::getSessionFromRequest(); $session->setData( 'core:idp-ssotime', $state['core:IdP'] . ';' . $state['core:SP'], time(), Session::DATA_TIMEOUT_SESSION_END ); } call_user_func($state['Responder'], $state); assert(false); } /** * The user is authenticated. * * @param array $state The authentication request state array. * * @throws \SimpleSAML\Error\Exception If we are not authenticated. * @return void */ public static function postAuth(array $state) { $idp = IdP::getByState($state); if (!$idp->isAuthenticated()) { throw new Error\Exception('Not authenticated.'); } $state['Attributes'] = $idp->authSource->getAttributes(); if (isset($state['SPMetadata'])) { $spMetadata = $state['SPMetadata']; } else { $spMetadata = []; } if (isset($state['core:SP'])) { $session = Session::getSessionFromRequest(); $previousSSOTime = $session->getData('core:idp-ssotime', $state['core:IdP'] . ';' . $state['core:SP']); if ($previousSSOTime !== null) { $state['PreviousSSOTimestamp'] = $previousSSOTime; } } $idpMetadata = $idp->getConfig()->toArray(); $pc = new Auth\ProcessingChain($idpMetadata, $spMetadata, 'idp'); $state['ReturnCall'] = ['\SimpleSAML\IdP', 'postAuthProc']; $state['Destination'] = $spMetadata; $state['Source'] = $idpMetadata; $pc->processState($state); self::postAuthProc($state); } /** * Authenticate the user. * * This function authenticates the user. * * @param array &$state The authentication request state. * * @throws \SimpleSAML\Module\saml\Error\NoPassive If we were asked to do passive authentication. * @return void */ private function authenticate(array &$state): void { if (isset($state['isPassive']) && (bool) $state['isPassive']) { throw new NoPassive(SAML2::STATUS_RESPONDER, 'Passive authentication not supported.'); } $this->authSource->login($state); } /** * Re-authenticate the user. * * This function re-authenticates an user with an existing session. This gives the authentication source a chance * to do additional work when re-authenticating for SSO. * * Note: This function is not used when ForceAuthn=true. * * @param array &$state The authentication request state. * * @throws \Exception If there is no auth source defined for this IdP. * @return void */ private function reauthenticate(array &$state): void { $sourceImpl = $this->authSource->getAuthSource(); $sourceImpl->reauthenticate($state); } /** * Process authentication requests. * * @param array &$state The authentication request state. * @return void */ public function handleAuthenticationRequest(array &$state) { assert(isset($state['Responder'])); $state['core:IdP'] = $this->id; if (isset($state['SPMetadata']['entityid'])) { $spEntityId = $state['SPMetadata']['entityid']; } elseif (isset($state['SPMetadata']['entityID'])) { $spEntityId = $state['SPMetadata']['entityID']; } else { $spEntityId = null; } $state['core:SP'] = $spEntityId; // first, check whether we need to authenticate the user if (isset($state['ForceAuthn']) && (bool) $state['ForceAuthn']) { // force authentication is in effect $needAuth = true; } else { $needAuth = !$this->isAuthenticated(); } $state['IdPMetadata'] = $this->getConfig()->toArray(); $state['ReturnCallback'] = ['\SimpleSAML\IdP', 'postAuth']; try { if ($needAuth) { $this->authenticate($state); assert(false); } else { $this->reauthenticate($state); } $this->postAuth($state); } catch (Error\Exception $e) { Auth\State::throwException($state, $e); } catch (\Exception $e) { $e = new Error\UnserializableException($e); Auth\State::throwException($state, $e); } } /** * Find the logout handler of this IdP. * * @return IdP\LogoutHandlerInterface The logout handler class. * @throws \Exception If we cannot find a logout handler. */ public function getLogoutHandler() { // find the logout handler $logouttype = $this->getConfig()->getString('logouttype', 'traditional'); switch ($logouttype) { case 'traditional': $handler = '\SimpleSAML\IdP\TraditionalLogoutHandler'; break; case 'iframe': $handler = '\SimpleSAML\IdP\IFrameLogoutHandler'; break; default: throw new Error\Exception('Unknown logout handler: ' . var_export($logouttype, true)); } /** @var IdP\LogoutHandlerInterface */ return new $handler($this); } /** * Finish the logout operation. * * This function will never return. * * @param array &$state The logout request state. * @return void */ public function finishLogout(array &$state) { assert(isset($state['Responder'])); $idp = IdP::getByState($state); call_user_func($state['Responder'], $idp, $state); assert(false); } /** * Process a logout request. * * This function will never return. * * @param array &$state The logout request state. * @param string|null $assocId The association we received the logout request from, or null if there was no * association. * @return void */ public function handleLogoutRequest(array &$state, $assocId) { assert(isset($state['Responder'])); assert(is_string($assocId) || $assocId === null); $state['core:IdP'] = $this->id; $state['core:TerminatedAssocId'] = $assocId; if ($assocId !== null) { $this->terminateAssociation($assocId); $session = Session::getSessionFromRequest(); $session->deleteData('core:idp-ssotime', $this->id . ';' . $state['saml:SPEntityId']); } // terminate the local session $id = Auth\State::saveState($state, 'core:Logout:afterbridge'); $returnTo = Module::getModuleURL('core/idp/resumelogout.php', ['id' => $id]); $this->authSource->logout($returnTo); if ($assocId !== null) { $handler = $this->getLogoutHandler(); $handler->startLogout($state, $assocId); } assert(false); } /** * Process a logout response. * * This function will never return. * * @param string $assocId The association that is terminated. * @param string|null $relayState The RelayState from the start of the logout. * @param \SimpleSAML\Error\Exception|null $error The error that occurred during session termination (if any). * @return void */ public function handleLogoutResponse($assocId, $relayState, Error\Exception $error = null) { assert(is_string($assocId)); assert(is_string($relayState) || $relayState === null); $index = strpos($assocId, ':'); assert(is_int($index)); $session = Session::getSessionFromRequest(); $session->deleteData('core:idp-ssotime', $this->id . ';' . substr($assocId, $index + 1)); $handler = $this->getLogoutHandler(); $handler->onResponse($assocId, $relayState, $error); assert(false); } /** * Log out, then redirect to a URL. * * This function never returns. * * @param string $url The URL the user should be returned to after logout. * @return void */ public function doLogoutRedirect($url) { assert(is_string($url)); $state = [ 'Responder' => ['\SimpleSAML\IdP', 'finishLogoutRedirect'], 'core:Logout:URL' => $url, ]; $this->handleLogoutRequest($state, null); assert(false); } /** * Redirect to a URL after logout. * * This function never returns. * * @param IdP $idp Deprecated. Will be removed. * @param array &$state The logout state from doLogoutRedirect(). * @return void */ public static function finishLogoutRedirect(IdP $idp, array $state) { assert(isset($state['core:Logout:URL'])); Utils\HTTP::redirectTrustedURL($state['core:Logout:URL']); assert(false); } } simplesamlphp-1.19.1/lib/SimpleSAML/Database.php0000644000000000000000000002106314042503475020056 0ustar rootroot * @package SimpleSAMLphp */ class Database { /** * This variable holds the instance of the session - Singleton approach. */ private static $instance = []; /** * PDO Object for the Master database server */ private $dbMaster; /** * Array of PDO Objects for configured database slaves */ private $dbSlaves = []; /** * Prefix to apply to the tables */ private $tablePrefix; /** * Array with information on the last error occurred. */ private $lastError; /** * Retrieves the current database instance. Will create a new one if there isn't an existing connection. * * @param \SimpleSAML\Configuration $altConfig Optional: Instance of a \SimpleSAML\Configuration class * * @return \SimpleSAML\Database The shared database connection. */ public static function getInstance($altConfig = null) { $config = ($altConfig) ? $altConfig : Configuration::getInstance(); $instanceId = self::generateInstanceId($config); // check if we already have initialized the session if (isset(self::$instance[$instanceId])) { return self::$instance[$instanceId]; } // create a new session self::$instance[$instanceId] = new Database($config); return self::$instance[$instanceId]; } /** * Private constructor that restricts instantiation to getInstance(). * * @param \SimpleSAML\Configuration $config Instance of the \SimpleSAML\Configuration class */ private function __construct(Configuration $config) { $driverOptions = $config->getArray('database.driver_options', []); if ($config->getBoolean('database.persistent', true)) { $driverOptions = [PDO::ATTR_PERSISTENT => true]; } // connect to the master $this->dbMaster = $this->connect( $config->getString('database.dsn'), $config->getString('database.username', null), $config->getString('database.password', null), $driverOptions ); // connect to any configured slaves $slaves = $config->getArray('database.slaves', []); foreach ($slaves as $slave) { array_push( $this->dbSlaves, $this->connect( $slave['dsn'], $slave['username'], $slave['password'], $driverOptions ) ); } $this->tablePrefix = $config->getString('database.prefix', ''); } /** * Generate an Instance ID based on the database configuration. * * @param \SimpleSAML\Configuration $config Configuration class * * @return string $instanceId */ private static function generateInstanceId(Configuration $config): string { $assembledConfig = [ 'master' => [ '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', []), ]; return sha1(serialize($assembledConfig)); } /** * This function connects to a database. * * @param string $dsn Database connection string * @param string|null $username SQL user * @param string|null $password SQL password * @param array $options PDO options * * @throws \Exception If an error happens while trying to connect to the database. * @return \PDO object */ private function connect(string $dsn, string $username = null, string $password = null, array $options): PDO { try { $db = new PDO($dsn, $username, $password, $options); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $db; } catch (PDOException $e) { throw new \Exception("Database error: " . $e->getMessage()); } } /** * This function randomly selects a slave database server to query. In the event no slaves are configured, it will * return the master. * * @return \PDO object */ private function getSlave(): PDO { if (count($this->dbSlaves) > 0) { $slaveId = rand(0, count($this->dbSlaves) - 1); return $this->dbSlaves[$slaveId]; } else { return $this->dbMaster; } } /** * This function simply applies the table prefix to a supplied table name. * * @param string $table Table to apply prefix to, if configured * * @return string Table with configured prefix */ public function applyPrefix($table) { return $this->tablePrefix . $table; } /** * This function queries the database * * @param \PDO $db PDO object to use * @param string $stmt Prepared SQL statement * @param array $params Parameters * * @throws \Exception If an error happens while trying to execute the query. * @return \PDOStatement object */ private function query(PDO $db, string $stmt, array $params): PDOStatement { try { $query = $db->prepare($stmt); foreach ($params as $param => $value) { if (is_array($value)) { $query->bindValue(":$param", $value[0], ($value[1]) ? $value[1] : PDO::PARAM_STR); } else { $query->bindValue(":$param", $value, PDO::PARAM_STR); } } $query->execute(); return $query; } catch (PDOException $e) { $this->lastError = $db->errorInfo(); throw new \Exception("Database error: " . $e->getMessage()); } } /** * This function queries the database without using a prepared statement. * * @param \PDO $db PDO object to use * @param string $stmt An SQL statement to execute, previously escaped. * * @throws \Exception If an error happens while trying to execute the query. * @return int The number of rows affected. */ private function exec(PDO $db, string $stmt): int { try { return $db->exec($stmt); } catch (PDOException $e) { $this->lastError = $db->errorInfo(); throw new \Exception("Database error: " . $e->getMessage()); } } /** * This executes queries directly on the master. * * @param string $stmt Prepared SQL statement * @param array $params Parameters * * @return int|false The number of rows affected by the query or false on error. */ public function write($stmt, $params = []) { $db = $this->dbMaster; if (is_array($params)) { return $this->query($db, $stmt, $params)->rowCount(); } else { return $this->exec($db, $stmt); } } /** * This executes queries on a database server that is determined by this::getSlave(). * * @param string $stmt Prepared SQL statement * @param array $params Parameters * * @return \PDOStatement object */ public function read($stmt, $params = []) { $db = $this->getSlave(); return $this->query($db, $stmt, $params); } /** * Return an array with information about the last operation performed in the database. * * @return array The array with error information. */ public function getLastError() { return $this->lastError; } } simplesamlphp-1.19.1/LICENSE0000644000000000000000000005764714042503475014213 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS simplesamlphp-1.19.1/cert/0000755000000000000000000000000014042503574014120 5ustar rootrootsimplesamlphp-1.19.1/composer.lock0000644000000000000000000075662014042503475015704 0ustar rootroot{ "_readme": [ "This file locks the dependencies of your project to a known state", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], "content-hash": "72459231e4f7d1628f797359eb9fc3a8", "packages": [ { "name": "gettext/gettext", "version": "v4.8.4", "source": { "type": "git", "url": "https://github.com/php-gettext/Gettext.git", "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1", "shasum": "" }, "require": { "gettext/languages": "^2.3", "php": ">=5.4.0" }, "require-dev": { "illuminate/view": "*", "phpunit/phpunit": "^4.8|^5.7|^6.5", "squizlabs/php_codesniffer": "^3.0", "symfony/yaml": "~2", "twig/extensions": "*", "twig/twig": "^1.31|^2.0" }, "suggest": { "illuminate/view": "Is necessary if you want to use the Blade extractor", "symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator", "twig/extensions": "Is necessary if you want to use the Twig extractor", "twig/twig": "Is necessary if you want to use the Twig extractor" }, "type": "library", "autoload": { "psr-4": { "Gettext\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Oscar Otero", "email": "oom@oscarotero.com", "homepage": "http://oscarotero.com", "role": "Developer" } ], "description": "PHP gettext manager", "homepage": "https://github.com/oscarotero/Gettext", "keywords": [ "JS", "gettext", "i18n", "mo", "po", "translation" ], "funding": [ { "url": "https://paypal.me/oscarotero", "type": "custom" }, { "url": "https://github.com/oscarotero", "type": "github" }, { "url": "https://www.patreon.com/misteroom", "type": "patreon" } ], "time": "2021-03-10T19:35:49+00:00" }, { "name": "gettext/languages", "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/php-gettext/Languages.git", "reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-gettext/Languages/zipball/38ea0482f649e0802e475f0ed19fa993bcb7a618", "reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618", "shasum": "" }, "require": { "php": ">=5.3" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.16.0", "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4" }, "bin": [ "bin/export-plural-rules" ], "type": "library", "autoload": { "psr-4": { "Gettext\\Languages\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Michele Locati", "email": "mlocati@gmail.com", "role": "Developer" } ], "description": "gettext languages with plural rules", "homepage": "https://github.com/php-gettext/Languages", "keywords": [ "cldr", "i18n", "internationalization", "l10n", "language", "languages", "localization", "php", "plural", "plural rules", "plurals", "translate", "translations", "unicode" ], "time": "2019-11-13T10:30:21+00:00" }, { "name": "phpfastcache/riak-client", "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/PHPSocialNetwork/riak-php-client.git", "reference": "d771f75d16196006604a30bb15adc1c6a9b0fcc9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/PHPSocialNetwork/riak-php-client/zipball/d771f75d16196006604a30bb15adc1c6a9b0fcc9", "reference": "d771f75d16196006604a30bb15adc1c6a9b0fcc9", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", "php": ">=5.4" }, "conflict": { "basho/riak": "*" }, "require-dev": { "apigen/apigen": "4.1.*", "phpunit/phpunit": "4.8.*" }, "type": "library", "autoload": { "psr-4": { "Basho\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Georges.L", "email": "contact@geolim4.com", "homepage": "https://github.com/Geolim4", "role": "Maintainer" }, { "name": "Christopher Mancini", "email": "cmancini@basho.com", "homepage": "https://github.com/christophermancini", "role": "Former Lead Developer" }, { "name": "Alex Moore", "email": "amoore@basho.com", "homepage": "https://github.com/alexmoore", "role": "Former Developer" } ], "description": "Riak client for PHP (Fork of the official basho/riak due to maintainer significant inactivity)", "homepage": "https://github.com/PHPSocialNetwork/riak-php-client", "keywords": [ "basho", "client", "crdt", "data", "database", "datatype", "driver", "kv", "nosql", "riak" ], "time": "2017-11-23T21:33:15+00:00" }, { "name": "phpmailer/phpmailer", "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", "reference": "4a08cf4cdd2c38d12ee2b9fa69e5d235f37a6dcb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/4a08cf4cdd2c38d12ee2b9fa69e5d235f37a6dcb", "reference": "4a08cf4cdd2c38d12ee2b9fa69e5d235f37a6dcb", "shasum": "" }, "require": { "ext-ctype": "*", "ext-filter": "*", "ext-hash": "*", "php": ">=5.5.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.2", "phpcompatibility/php-compatibility": "^9.3.5", "roave/security-advisories": "dev-latest", "squizlabs/php_codesniffer": "^3.5.6", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { "ext-mbstring": "Needed to send email in multibyte encoding charset", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication", "psr/log": "For optional PSR-3 debug logging", "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" }, "type": "library", "autoload": { "psr-4": { "PHPMailer\\PHPMailer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-only" ], "authors": [ { "name": "Marcus Bointon", "email": "phpmailer@synchromedia.co.uk" }, { "name": "Jim Jagielski", "email": "jimjag@gmail.com" }, { "name": "Andy Prevost", "email": "codeworxtech@users.sourceforge.net" }, { "name": "Brent R. Matzelle" } ], "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "funding": [ { "url": "https://github.com/Synchro", "type": "github" } ], "time": "2021-02-19T15:28:08+00:00" }, { "name": "psr/cache", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Psr\\Cache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for caching libraries", "keywords": [ "cache", "psr", "psr-6" ], "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", "homepage": "https://github.com/php-fig/container", "keywords": [ "PSR-11", "container", "container-interface", "container-interop", "psr" ], "time": "2017-02-14T16:28:37+00:00" }, { "name": "psr/log", "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } }, "autoload": { "psr-4": { "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for logging libraries", "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], "time": "2020-03-23T09:12:05+00:00" }, { "name": "robrichards/xmlseclibs", "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/robrichards/xmlseclibs.git", "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df", "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df", "shasum": "" }, "require": { "ext-openssl": "*", "php": ">= 5.4" }, "type": "library", "autoload": { "psr-4": { "RobRichards\\XMLSecLibs\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "A PHP library for XML Security", "homepage": "https://github.com/robrichards/xmlseclibs", "keywords": [ "security", "signature", "xml", "xmldsig" ], "time": "2020-09-05T13:00:25+00:00" }, { "name": "simplesamlphp/assert", "version": "v0.0.13", "source": { "type": "git", "url": "https://github.com/simplesamlphp/assert.git", "reference": "5429921b320ca4f9d1844225884ac52f649ea1e3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/assert/zipball/5429921b320ca4f9d1844225884ac52f649ea1e3", "reference": "5429921b320ca4f9d1844225884ac52f649ea1e3", "shasum": "" }, "require": { "ext-spl": "*", "php": "^7.1 || ^8.0", "webmozart/assert": "^1.9" }, "require-dev": { "phpunit/phpunit": "^8.5", "sensiolabs/security-checker": "~6.0", "simplesamlphp/simplesamlphp-test-framework": "^0.2.7", "squizlabs/php_codesniffer": "~3.5", "vimeo/psalm": "~3.13" }, "type": "library", "extra": { "branch-alias": { "dev-master": "v0.0.x-dev" } }, "autoload": { "psr-4": { "SimpleSAML\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" }, { "name": "Jaime Perez Crespo", "email": "jaimepc@gmail.com" } ], "description": "A wrapper around webmozart/assert to make it useful beyond checking method arguments", "time": "2020-08-17T20:40:49+00:00" }, { "name": "simplesamlphp/composer-module-installer", "version": "v1.1.8", "source": { "type": "git", "url": "https://github.com/simplesamlphp/composer-module-installer.git", "reference": "45161b5406f3e9c82459d0f9a5a1dba064953cfa" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/composer-module-installer/zipball/45161b5406f3e9c82459d0f9a5a1dba064953cfa", "reference": "45161b5406f3e9c82459d0f9a5a1dba064953cfa", "shasum": "" }, "require": { "composer-plugin-api": "^1.1|^2.0", "simplesamlphp/simplesamlphp": "*" }, "type": "composer-plugin", "extra": { "class": "SimpleSamlPhp\\Composer\\ModuleInstallerPlugin" }, "autoload": { "psr-0": { "SimpleSamlPhp\\Composer": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-only" ], "description": "A Composer plugin that allows installing SimpleSAMLphp modules through Composer.", "time": "2020-08-25T19:04:33+00:00" }, { "name": "simplesamlphp/saml2", "version": "v4.2.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/saml2.git", "reference": "3bc980feb96ecf57898014c1bb5b26f0859f1316" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/3bc980feb96ecf57898014c1bb5b26f0859f1316", "reference": "3bc980feb96ecf57898014c1bb5b26f0859f1316", "shasum": "" }, "require": { "ext-dom": "*", "ext-openssl": "*", "ext-zlib": "*", "php": ">=7.1", "psr/log": "~1.1", "robrichards/xmlseclibs": "^3.1.0", "webmozart/assert": "^1.5" }, "require-dev": { "mockery/mockery": "~1.2", "phpunit/phpunit": "^7.5", "sebastian/phpcpd": "~4.1", "sensiolabs/security-checker": "~6.0", "simplesamlphp/simplesamlphp-test-framework": "~0.1.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "v4.0.x-dev" } }, "autoload": { "psr-4": { "SAML2\\": "src/SAML2" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "SAML2 PHP library from SimpleSAMLphp", "time": "2021-04-26T14:40:29+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-adfs", "version": "v0.9.6", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-adfs.git", "reference": "425e5ebbdd097c92fe5265a6b48d32a3095c7237" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-adfs/zipball/425e5ebbdd097c92fe5265a6b48d32a3095c7237", "reference": "425e5ebbdd097c92fe5265a6b48d32a3095c7237", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "webmozart/assert": "<1.7" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\adfs\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that implements the WS-federation IDP", "keywords": [ "adfs", "simplesamlphp" ], "time": "2020-03-31T14:29:24+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authcrypt", "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authcrypt.git", "reference": "9a2c1a761e2d94394a4f2d3499fd6f0853899530" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authcrypt/zipball/9a2c1a761e2d94394a4f2d3499fd6f0853899530", "reference": "9a2c1a761e2d94394a4f2d3499fd6f0853899530", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "~1.4", "whitehat101/apr1-md5": "~1.0" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\authcrypt\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "This module provides authentication against password hashes or .htpasswd files", "keywords": [ "authcrypt", "simplesamlphp" ], "time": "2021-01-08T09:09:33+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authfacebook", "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authfacebook.git", "reference": "9152731e939ad4a49e0f06da5f0009ebde0d2b5c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authfacebook/zipball/9152731e939ad4a49e0f06da5f0009ebde0d2b5c", "reference": "9152731e939ad4a49e0f06da5f0009ebde0d2b5c", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.10" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\authfacebook\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Andjelko Horvat", "email": "comel@vingd.com" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to authenticate against Facebook", "keywords": [ "facebook", "simplesamlphp" ], "time": "2020-03-13T11:29:21+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authorize", "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authorize.git", "reference": "0593bfcb84fca9d9133f415246ab8ca51b412c92" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authorize/zipball/0593bfcb84fca9d9133f415246ab8ca51b412c92", "reference": "0593bfcb84fca9d9133f415246ab8ca51b412c92", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\authorize\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Ernesto Revilla", "email": "erny@yaco.es" } ], "description": "This module provides a user authorization filter based on attribute matching", "keywords": [ "authorize", "simplesamlphp" ], "time": "2021-03-24T10:37:17+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authtwitter", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authtwitter.git", "reference": "29a15e58061222632fea9eb2c807aef5e2c0d54a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authtwitter/zipball/29a15e58061222632fea9eb2c807aef5e2c0d54a", "reference": "29a15e58061222632fea9eb2c807aef5e2c0d54a", "shasum": "" }, "require": { "php": ">=5.5", "simplesamlphp/composer-module-installer": "~1.0", "simplesamlphp/simplesamlphp-module-oauth": "^0.9" }, "require-dev": { "phpunit/phpunit": "~4.8.35", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\authtwitter\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to perform authentication against Twitter", "keywords": [ "simplesamlphp", "twitter" ], "time": "2019-12-03T09:00:09+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authwindowslive", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authwindowslive.git", "reference": "f40aecec6c0adaedb6693309840c98cec783876e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authwindowslive/zipball/f40aecec6c0adaedb6693309840c98cec783876e", "reference": "f40aecec6c0adaedb6693309840c98cec783876e", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\authwindowslive\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to perform authentication against Windows Live", "keywords": [ "live", "simplesamlphp", "windows", "windowslive" ], "time": "2019-12-03T09:01:13+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authx509", "version": "v0.9.8", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authX509.git", "reference": "66525b1ec4145ec8d0d0e9db4534624b6be4c1fb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authX509/zipball/66525b1ec4145ec8d0d0e9db4534624b6be4c1fb", "reference": "66525b1ec4145ec8d0d0e9db4534624b6be4c1fb", "shasum": "" }, "require": { "php": ">=5.5", "simplesamlphp/composer-module-installer": "~1.1", "simplesamlphp/simplesamlphp-module-ldap": "^0.9" }, "require-dev": { "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.15" }, "type": "simplesamlphp-module", "extra": { "ssp-mixedcase-module-name": "authX509" }, "autoload": { "psr-4": { "SimpleSAML\\Module\\authX509\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Joost van Dijk", "email": "Joost.vanDijk@surfnet.nl" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to authenticate users based on X509 client certificates", "keywords": [ "simplesamlphp", "x509" ], "time": "2020-12-15T23:06:47+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-authyubikey", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-authyubikey.git", "reference": "8c27bfeb4981d2e6fa40a831e945f40c5a4ad3d2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-authyubikey/zipball/8c27bfeb4981d2e6fa40a831e945f40c5a4ad3d2", "reference": "8c27bfeb4981d2e6fa40a831e945f40c5a4ad3d2", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "extra": { "ssp-mixedcase-module-name": "authYubikey" }, "autoload": { "psr-4": { "SimpleSAML\\modules\\yubikey\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to authenticate against YubiKey", "keywords": [ "authyubikey", "simplesamlphp" ], "time": "2019-12-03T08:52:49+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-cas", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-cas.git", "reference": "63b72e4600550c507cdfc32fdd208ad59a64321e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-cas/zipball/63b72e4600550c507cdfc32fdd208ad59a64321e", "reference": "63b72e4600550c507cdfc32fdd208ad59a64321e", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "simplesamlphp/simplesamlphp-module-ldap": "^0.9", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\cas\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "A module that provides CAS authentication", "keywords": [ "cas", "simplesamlphp" ], "time": "2019-12-03T09:03:06+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-cdc", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-cdc.git", "reference": "16a5bfac7299e04e5feb472af328e07598708166" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-cdc/zipball/16a5bfac7299e04e5feb472af328e07598708166", "reference": "16a5bfac7299e04e5feb472af328e07598708166", "shasum": "" }, "require": { "simplesamlphp/composer-module-installer": ">=1.1.6" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\cdc\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olav.morken@uninett.no" }, { "name": "Jaime Perez Crespo", "email": "jaime.perez@uninett.no" } ], "description": "A SimpleSAMLphp module that allows integration with CDC", "homepage": "https://simplesamlphp.org/", "keywords": [ "cdc", "simplesamlphp" ], "time": "2019-12-03T09:04:11+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-consent", "version": "v0.9.6", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-consent.git", "reference": "2f84d15e96afb5a32b6d1cff93370f501ca7867d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-consent/zipball/2f84d15e96afb5a32b6d1cff93370f501ca7867d", "reference": "2f84d15e96afb5a32b6d1cff93370f501ca7867d", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "webmozart/assert": "<1.7" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\consent\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "lavmrk@gmail.com" } ], "description": "A module that will ask for user consent before releasing attributes", "keywords": [ "consent", "simplesamlphp" ], "time": "2020-06-15T14:26:23+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-consentadmin", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-consentadmin.git", "reference": "466e8d0d751f0080162d78e63ab2e125b24d17a1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-consentadmin/zipball/466e8d0d751f0080162d78e63ab2e125b24d17a1", "reference": "466e8d0d751f0080162d78e63ab2e125b24d17a1", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "simplesamlphp/simplesamlphp-module-consent": "^0.9", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "extra": { "ssp-mixedcase-module-name": "consentAdmin" }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Jacob Christiansen", "email": "jach@wayf.dk" }, { "name": "Olav Morken", "email": "olav.morken@uninett.no" } ], "description": "A module that allows users to manage their consent", "keywords": [ "consentadmin", "simplesamlphp" ], "time": "2019-12-03T09:06:40+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-discopower", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-discopower.git", "reference": "006c0617610f1bae11cf4d17e8ce4c509239a60e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-discopower/zipball/006c0617610f1bae11cf4d17e8ce4c509239a60e", "reference": "006c0617610f1bae11cf4d17e8ce4c509239a60e", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\modules\\discopower\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "Fancy tabbed discovery service with filtering capabilities where SPs can have different sets of metadata listed", "keywords": [ "discopower", "discovery", "simplesamlphp" ], "time": "2019-11-27T20:34:37+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-exampleattributeserver", "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-exampleattributeserver.git", "reference": "63e0323e81c32bc3c9eaa01ea45194bb10153708" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-exampleattributeserver/zipball/63e0323e81c32bc3c9eaa01ea45194bb10153708", "reference": "63e0323e81c32bc3c9eaa01ea45194bb10153708", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\exampleattributeserver\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "An example for SAML attributes queries", "keywords": [ "exampleattributeserver", "simplesamlphp" ], "time": "2019-05-28T12:37:15+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-expirycheck", "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-expirycheck.git", "reference": "59c59cdf87e2679257b46c07bb4c27666a11cc20" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-expirycheck/zipball/59c59cdf87e2679257b46c07bb4c27666a11cc20", "reference": "59c59cdf87e2679257b46c07bb4c27666a11cc20", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "~1.4" }, "require-dev": { "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.10" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\expirycheck\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Alex Mihičinac", "email": "alexm@arnes.si" } ], "description": "The expirycheck module validates user's expiry date", "keywords": [ "expirycheck", "simplesamlphp" ], "time": "2019-12-14T13:20:46+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-ldap", "version": "v0.9.10", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-ldap.git", "reference": "78f04cbe41bfb9dcbcdeff4b5f12e67c060e1a77" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-ldap/zipball/78f04cbe41bfb9dcbcdeff4b5f12e67c060e1a77", "reference": "78f04cbe41bfb9dcbcdeff4b5f12e67c060e1a77", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "suggest": { "ext-ldap": "Needed when using LDAP authentication in SimpleSAMLphp" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\ldap\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that provides authentication against LDAP stores", "keywords": [ "ldap", "simplesamlphp" ], "time": "2020-09-16T21:09:07+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-memcachemonitor", "version": "v0.9.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-memcachemonitor.git", "reference": "900b5c6b59913d9013b8dae090841a127ae55ae5" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-memcachemonitor/zipball/900b5c6b59913d9013b8dae090841a127ae55ae5", "reference": "900b5c6b59913d9013b8dae090841a127ae55ae5", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "~0.0.6" }, "type": "simplesamlphp-module", "extra": { "ssp-mixedcase-module-name": "memcacheMonitor" }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" }, { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able display usage statistics of a memcache(d) store", "keywords": [ "memcachemonitor", "simplesamlphp" ], "time": "2021-01-25T15:44:44+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-memcookie", "version": "v1.2.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-memcookie.git", "reference": "39535304e8d464b7baa1e82cb441fa432947ff57" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-memcookie/zipball/39535304e8d464b7baa1e82cb441fa432947ff57", "reference": "39535304e8d464b7baa1e82cb441fa432947ff57", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": ">=1.1.6" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.6" }, "type": "simplesamlphp-module", "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1" ], "authors": [ { "name": "Olav Morken", "email": "olav.morken@uninett.no" }, { "name": "Jaime Perez Crespo", "email": "jaime.perez@uninett.no" } ], "description": "A SimpleSAMLphp module that allows integration with Auth MemCookie, allowing web applications written in other languages than PHP to integrate with SimpleSAMLphp.", "homepage": "https://simplesamlphp.org/", "keywords": [ "Auth MemCookie", "apache", "cookies", "simplesamlphp" ], "time": "2019-08-08T18:33:47+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-metarefresh", "version": "v0.9.6", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-metarefresh.git", "reference": "e284306a7097297765b5b78a4e28f19f18d4e001" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-metarefresh/zipball/e284306a7097297765b5b78a4e28f19f18d4e001", "reference": "e284306a7097297765b5b78a4e28f19f18d4e001", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.18" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\metarefresh\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "The metarefresh module will download and parse metadata documents and store them locally", "keywords": [ "metarefresh", "simplesamlphp" ], "time": "2020-07-31T14:43:37+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-negotiate", "version": "v0.9.10", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-negotiate.git", "reference": "db05ff40399c66e3f14697a8162da6b2fbdab47d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-negotiate/zipball/db05ff40399c66e3f14697a8162da6b2fbdab47d", "reference": "db05ff40399c66e3f14697a8162da6b2fbdab47d", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "simplesamlphp/simplesamlphp-module-ldap": "^0.9", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "sensiolabs/security-checker": "^5.0.3", "simplesamlphp/simplesamlphp": "dev-testing-1.18", "simplesamlphp/simplesamlphp-test-framework": "^0.0.14", "squizlabs/php_codesniffer": "^3.5" }, "suggest": { "ext-krb5": "Needed in case the SimpleSAMLphp negotiate module is used" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\negotiate\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "The Negotiate module implements Microsofts Kerberos SPNEGO mechanism", "keywords": [ "negotiate", "simplesamlphp" ], "time": "2021-01-22T13:36:09+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-oauth", "version": "v0.9.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-oauth.git", "reference": "d14d7aca6e699ec12b3f4dd0128373faa1a2cc61" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-oauth/zipball/d14d7aca6e699ec12b3f4dd0128373faa1a2cc61", "reference": "d14d7aca6e699ec12b3f4dd0128373faa1a2cc61", "shasum": "" }, "require": { "simplesamlphp/composer-module-installer": ">=1.1.6" }, "require-dev": { "phpunit/phpunit": "~4.8.36", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olav.morken@uninett.no" }, { "name": "Jaime Perez Crespo", "email": "jaime.perez@uninett.no" } ], "description": "A SimpleSAMLphp module that allows integration with OAuth1,", "homepage": "https://simplesamlphp.org/", "keywords": [ "oauth1", "simplesamlphp" ], "time": "2020-04-29T19:37:43+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-preprodwarning", "version": "v0.9.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-preprodwarning.git", "reference": "8e032de33a75eb44857dc06d886ad94ee3af4638" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-preprodwarning/zipball/8e032de33a75eb44857dc06d886ad94ee3af4638", "reference": "8e032de33a75eb44857dc06d886ad94ee3af4638", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "webmozart/assert": "^1.4" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\preprodwarning\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "Display a warning when using a pre-production environment", "keywords": [ "preprodwarning", "simplesamlphp" ], "time": "2020-04-09T13:05:27+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-radius", "version": "v0.9.3", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-radius.git", "reference": "36bd0f39f9a13f7eb96ead97c97c3634aa1c3f2d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-radius/zipball/36bd0f39f9a13f7eb96ead97c97c3634aa1c3f2d", "reference": "36bd0f39f9a13f7eb96ead97c97c3634aa1c3f2d", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.7" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\radius\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "A module that is able perform authentication against a RADIUS server", "keywords": [ "radius", "simplesamlphp" ], "time": "2019-10-03T18:13:07+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-riak", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-riak.git", "reference": "c1a9d9545cb4e05b9205b34624850bb777aca991" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-riak/zipball/c1a9d9545cb4e05b9205b34624850bb777aca991", "reference": "c1a9d9545cb4e05b9205b34624850bb777aca991", "shasum": "" }, "require": { "php": ">=5.6", "phpfastcache/riak-client": "^3.4", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\riak\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "A module that is able to store key/value pairs in a Riak store", "keywords": [ "riak", "simplesamlphp" ], "time": "2019-12-03T08:28:45+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-sanitycheck", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-sanitycheck.git", "reference": "15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-sanitycheck/zipball/15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a", "reference": "15d6664eae73a233c3c4c72fd8a5c2be72b6ed2a", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "~1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\sanitycheck\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "Perform sanity checks on configuration", "keywords": [ "sanitycheck", "simplesamlphp" ], "time": "2020-05-07T11:34:29+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-smartattributes", "version": "v0.9.1", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-smartattributes.git", "reference": "b45d3ecd916e359a9cae05f9ae9df09b5c42f4e6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-smartattributes/zipball/b45d3ecd916e359a9cae05f9ae9df09b5c42f4e6", "reference": "b45d3ecd916e359a9cae05f9ae9df09b5c42f4e6", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\smartattributes\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "The SmartAttributes module provides additional authentication processing filters to manipulate attributes.", "keywords": [ "simplesamlphp", "smartattributes" ], "time": "2019-12-03T09:24:09+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-sqlauth", "version": "v0.9.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-sqlauth.git", "reference": "a53475236787630d7872ca97445f7e75f2609257" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-sqlauth/zipball/a53475236787630d7872ca97445f7e75f2609257", "reference": "a53475236787630d7872ca97445f7e75f2609257", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "webmozart/assert": "^1.4 <1.7" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\sqlauth\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Olav Morken", "email": "olavmrk@gmail.com" } ], "description": "This is a authentication module for authenticating a user against a SQL database", "keywords": [ "simplesamlphp", "sqlauth" ], "time": "2021-04-23T08:14:10+00:00" }, { "name": "simplesamlphp/simplesamlphp-module-statistics", "version": "v0.9.6", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-module-statistics.git", "reference": "03fb6bdbbf5ce0a0cb257208db79aacac227ac10" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-statistics/zipball/03fb6bdbbf5ce0a0cb257208db79aacac227ac10", "reference": "03fb6bdbbf5ce0a0cb257208db79aacac227ac10", "shasum": "" }, "require": { "php": ">=5.6", "simplesamlphp/composer-module-installer": "~1.1", "webmozart/assert": "^1.4" }, "require-dev": { "phpunit/phpunit": "~5.7", "simplesamlphp/simplesamlphp": "^1.17", "simplesamlphp/simplesamlphp-test-framework": "^0.0.12" }, "type": "simplesamlphp-module", "autoload": { "psr-4": { "SimpleSAML\\Module\\statistics\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1-or-later" ], "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" } ], "description": "The SimpleSAMLphp statistics module", "keywords": [ "simplesamlphp", "statistics" ], "time": "2021-01-25T15:15:26+00:00" }, { "name": "simplesamlphp/twig-configurable-i18n", "version": "v2.3.4", "source": { "type": "git", "url": "https://github.com/simplesamlphp/twig-configurable-i18n.git", "reference": "e2bffc7eed3112a0b3870ef5b4da0fd74c7c4b8a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/twig-configurable-i18n/zipball/e2bffc7eed3112a0b3870ef5b4da0fd74c7c4b8a", "reference": "e2bffc7eed3112a0b3870ef5b4da0fd74c7c4b8a", "shasum": "" }, "require": { "php": ">=7.1", "twig/extensions": "@dev" }, "require-dev": { "phpunit/phpunit": "^7.5", "sensiolabs/security-checker": "~6.0.3", "simplesamlphp/simplesamlphp-test-framework": "~0.1.2", "squizlabs/php_codesniffer": "^3.5", "twig/twig": "^2.13" }, "type": "project", "autoload": { "psr-4": { "SimpleSAML\\TwigConfigurableI18n\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-2.1" ], "authors": [ { "name": "Jaime Perez", "email": "jaime.perez@uninett.no" } ], "description": "This is an extension on top of Twig's i18n extension, allowing you to customize which functions to use for translations.", "keywords": [ "extension", "gettext", "i18n", "internationalization", "translation", "twig" ], "time": "2020-08-27T12:51:10+00:00" }, { "name": "symfony/cache", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", "reference": "8fa248b0105d962ac279ae973dee2a32ae009dee" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/cache/zipball/8fa248b0105d962ac279ae973dee2a32ae009dee", "reference": "8fa248b0105d962ac279ae973dee2a32ae009dee", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/cache": "^1.0|^2.0", "psr/log": "~1.0", "symfony/cache-contracts": "^1.1.7|^2", "symfony/service-contracts": "^1.1|^2", "symfony/var-exporter": "^4.2|^5.0" }, "conflict": { "doctrine/dbal": "<2.6", "symfony/dependency-injection": "<3.4", "symfony/http-kernel": "<4.4|>=5.0", "symfony/var-dumper": "<4.4" }, "provide": { "psr/cache-implementation": "1.0|2.0", "psr/simple-cache-implementation": "1.0", "symfony/cache-implementation": "1.0|2.0" }, "require-dev": { "cache/integration-tests": "dev-master", "doctrine/cache": "^1.6", "doctrine/dbal": "^2.6|^3.0", "predis/predis": "^1.1", "psr/simple-cache": "^1.0", "symfony/config": "^4.2|^5.0", "symfony/dependency-injection": "^3.4|^4.1|^5.0", "symfony/filesystem": "^4.4|^5.0", "symfony/http-kernel": "^4.4", "symfony/var-dumper": "^4.4|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Cache\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", "homepage": "https://symfony.com", "keywords": [ "caching", "psr6" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-25T23:52:11+00:00" }, { "name": "symfony/cache-contracts", "version": "v1.1.10", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", "reference": "8d5489c10ef90aa7413e4921fc3c0520e24cbed7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8d5489c10ef90aa7413e4921fc3c0520e24cbed7", "reference": "8d5489c10ef90aa7413e4921fc3c0520e24cbed7", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/cache": "^1.0" }, "suggest": { "symfony/cache-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Cache\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to caching", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2020-09-02T16:08:58+00:00" }, { "name": "symfony/config", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/config.git", "reference": "98606c6fa1a8f55ff964ccdd704275bf5b9f71b3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/config/zipball/98606c6fa1a8f55ff964ccdd704275bf5b9f71b3", "reference": "98606c6fa1a8f55ff964ccdd704275bf5b9f71b3", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/finder": "<3.4" }, "require-dev": { "symfony/event-dispatcher": "^3.4|^4.0|^5.0", "symfony/finder": "^3.4|^4.0|^5.0", "symfony/messenger": "^4.1|^5.0", "symfony/service-contracts": "^1.1|^2", "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-22T15:36:50+00:00" }, { "name": "symfony/console", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/console.git", "reference": "c98349bda966c70d6c08b4cd8658377c94166492" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/console/zipball/c98349bda966c70d6c08b4cd8658377c94166492", "reference": "c98349bda966c70d6c08b4cd8658377c94166492", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2" }, "conflict": { "symfony/dependency-injection": "<3.4", "symfony/event-dispatcher": "<4.3|>=5", "symfony/lock": "<4.4", "symfony/process": "<3.3" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", "symfony/config": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/event-dispatcher": "^4.3", "symfony/lock": "^4.4|^5.0", "symfony/process": "^3.4|^4.0|^5.0", "symfony/var-dumper": "^4.3|^5.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-22T18:44:15+00:00" }, { "name": "symfony/debug", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", "reference": "157bbec4fd773bae53c5483c50951a5530a2cc16" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/debug/zipball/157bbec4fd773bae53c5483c50951a5530a2cc16", "reference": "157bbec4fd773bae53c5483c50951a5530a2cc16", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/log": "~1.0", "symfony/polyfill-php80": "^1.15" }, "conflict": { "symfony/http-kernel": "<3.4" }, "require-dev": { "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Debug\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides tools to ease debugging PHP code", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-28T16:54:48+00:00" }, { "name": "symfony/dependency-injection", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", "reference": "4b3e341ce4436df9a9abc2914cb120b4d41796d7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b3e341ce4436df9a9abc2914cb120b4d41796d7", "reference": "4b3e341ce4436df9a9abc2914cb120b4d41796d7", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/container": "^1.0", "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { "symfony/config": "<4.3|>=5.0", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" }, "provide": { "psr/container-implementation": "1.0", "symfony/service-implementation": "1.0|2.0" }, "require-dev": { "symfony/config": "^4.3", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/config": "", "symfony/expression-language": "For using expressions in service container configuration", "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", "symfony/yaml": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-03-03T12:11:09+00:00" }, { "name": "symfony/error-handler", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", "reference": "a191550d46b73a527b9d244f185fef439d41cf15" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/error-handler/zipball/a191550d46b73a527b9d244f185fef439d41cf15", "reference": "a191550d46b73a527b9d244f185fef439d41cf15", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/log": "~1.0", "symfony/debug": "^4.4.5", "symfony/polyfill-php80": "^1.15", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { "symfony/http-kernel": "^4.4|^5.0", "symfony/serializer": "^4.4|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\ErrorHandler\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-11T08:19:35+00:00" }, { "name": "symfony/event-dispatcher", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c352647244bd376bf7d31efbd5401f13f50dad0c", "reference": "c352647244bd376bf7d31efbd5401f13f50dad0c", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/event-dispatcher-contracts": "^1.1" }, "conflict": { "symfony/dependency-injection": "<3.4" }, "provide": { "psr/event-dispatcher-implementation": "1.0", "symfony/event-dispatcher-implementation": "1.1" }, "require-dev": { "psr/log": "~1.0", "symfony/config": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/error-handler": "~3.4|~4.4", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^3.4|^4.0|^5.0", "symfony/service-contracts": "^1.1|^2", "symfony/stopwatch": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/event-dispatcher-contracts", "version": "v1.1.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", "shasum": "" }, "require": { "php": ">=7.1.3" }, "suggest": { "psr/event-dispatcher": "", "symfony/event-dispatcher-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\EventDispatcher\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to dispatching event", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2020-07-06T13:19:58+00:00" }, { "name": "symfony/filesystem", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", "reference": "715e7a531bdae109a828f9e91629e5b3b2926beb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/filesystem/zipball/715e7a531bdae109a828f9e91629e5b3b2926beb", "reference": "715e7a531bdae109a828f9e91629e5b3b2926beb", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-11T19:34:41+00:00" }, { "name": "symfony/finder", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", "reference": "2543795ab1570df588b9bbd31e1a2bd7037b94f6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/finder/zipball/2543795ab1570df588b9bbd31e1a2bd7037b94f6", "reference": "2543795ab1570df588b9bbd31e1a2bd7037b94f6", "shasum": "" }, "require": { "php": ">=7.1.3" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-12T10:48:09+00:00" }, { "name": "symfony/framework-bundle", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", "reference": "5b5aefc0542e2b42f6f3b9b90d6ef2ff75fee19a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5b5aefc0542e2b42f6f3b9b90d6ef2ff75fee19a", "reference": "5b5aefc0542e2b42f6f3b9b90d6ef2ff75fee19a", "shasum": "" }, "require": { "ext-xml": "*", "php": ">=7.1.3", "symfony/cache": "^4.4|^5.0", "symfony/config": "^4.3.4|^5.0", "symfony/dependency-injection": "^4.4.1|^5.0.1", "symfony/error-handler": "^4.4.1|^5.0.1", "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/finder": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^4.4|^5.0", "symfony/http-kernel": "^4.4", "symfony/polyfill-mbstring": "~1.0", "symfony/routing": "^4.4.12|^5.1.4" }, "conflict": { "doctrine/persistence": "<1.3", "phpdocumentor/reflection-docblock": "<3.0|>=3.2.0,<3.2.2", "phpdocumentor/type-resolver": "<0.3.0|1.3.*", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/asset": "<3.4", "symfony/browser-kit": "<4.3", "symfony/console": "<4.3", "symfony/dom-crawler": "<4.3", "symfony/dotenv": "<4.3.6", "symfony/form": "<4.3.5", "symfony/http-client": "<4.4", "symfony/lock": "<4.4", "symfony/mailer": "<4.4", "symfony/messenger": "<4.4", "symfony/mime": "<4.4", "symfony/property-info": "<3.4", "symfony/security-bundle": "<4.4", "symfony/serializer": "<4.4", "symfony/stopwatch": "<3.4", "symfony/translation": "<4.4", "symfony/twig-bridge": "<4.1.1", "symfony/twig-bundle": "<4.4", "symfony/validator": "<4.4", "symfony/web-profiler-bundle": "<4.4", "symfony/workflow": "<4.3.6" }, "require-dev": { "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.0", "doctrine/persistence": "^1.3|^2.0", "paragonie/sodium_compat": "^1.8", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/asset": "^3.4|^4.0|^5.0", "symfony/browser-kit": "^4.3|^5.0", "symfony/console": "^4.3.4|^5.0", "symfony/css-selector": "^3.4|^4.0|^5.0", "symfony/dom-crawler": "^4.3|^5.0", "symfony/dotenv": "^4.3.6|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/form": "^4.3.5|^5.0", "symfony/http-client": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", "symfony/mailer": "^4.4|^5.0", "symfony/messenger": "^4.4|^5.0", "symfony/mime": "^4.4|^5.0", "symfony/polyfill-intl-icu": "~1.0", "symfony/process": "^3.4|^4.0|^5.0", "symfony/property-info": "^3.4|^4.0|^5.0", "symfony/security-core": "^3.4|^4.4|^5.2", "symfony/security-csrf": "^3.4|^4.0|^5.0", "symfony/security-http": "^3.4|^4.0|^5.0", "symfony/serializer": "^4.4|^5.0", "symfony/stopwatch": "^3.4|^4.0|^5.0", "symfony/templating": "^3.4|^4.0|^5.0", "symfony/translation": "^4.4|^5.0", "symfony/twig-bundle": "^4.4|^5.0", "symfony/validator": "^4.4|^5.0", "symfony/web-link": "^4.4|^5.0", "symfony/workflow": "^4.3.6|^5.0", "symfony/yaml": "^3.4|^4.0|^5.0", "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "ext-apcu": "For best performance of the system caches", "symfony/console": "For using the console commands", "symfony/form": "For using forms", "symfony/property-info": "For using the property_info service", "symfony/serializer": "For using the serializer service", "symfony/validator": "For using validation", "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", "symfony/yaml": "For using the debug:config and lint:yaml commands" }, "type": "symfony-bundle", "autoload": { "psr-4": { "Symfony\\Bundle\\FrameworkBundle\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-22T15:36:50+00:00" }, { "name": "symfony/http-client-contracts", "version": "v1.1.10", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", "reference": "7e86f903f9720d0caa7688f5c29a2de2d77cbb89" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e86f903f9720d0caa7688f5c29a2de2d77cbb89", "reference": "7e86f903f9720d0caa7688f5c29a2de2d77cbb89", "shasum": "" }, "require": { "php": ">=7.1.3" }, "suggest": { "symfony/http-client-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\HttpClient\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to HTTP clients", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2020-08-17T09:35:39+00:00" }, { "name": "symfony/http-foundation", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", "reference": "02d968647fe61b2f419a8dc70c468a9d30a48d3a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/02d968647fe61b2f419a8dc70c468a9d30a48d3a", "reference": "02d968647fe61b2f419a8dc70c468a9d30a48d3a", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/mime": "^4.3|^5.0", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php80": "^1.15" }, "require-dev": { "predis/predis": "~1.0", "symfony/expression-language": "^3.4|^4.0|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-25T17:11:33+00:00" }, { "name": "symfony/http-kernel", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", "reference": "4f36548465489f293b05406f1770492f6efb8adb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4f36548465489f293b05406f1770492f6efb8adb", "reference": "4f36548465489f293b05406f1770492f6efb8adb", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/log": "~1.0", "symfony/error-handler": "^4.4", "symfony/event-dispatcher": "^4.4", "symfony/http-client-contracts": "^1.1|^2", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.15" }, "conflict": { "symfony/browser-kit": "<4.3", "symfony/config": "<3.4", "symfony/console": ">=5", "symfony/dependency-injection": "<4.3", "symfony/translation": "<4.2", "twig/twig": "<1.43|<2.13,>=2" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", "symfony/browser-kit": "^4.3|^5.0", "symfony/config": "^3.4|^4.0|^5.0", "symfony/console": "^3.4|^4.0", "symfony/css-selector": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^4.3|^5.0", "symfony/dom-crawler": "^3.4|^4.0|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/finder": "^3.4|^4.0|^5.0", "symfony/process": "^3.4|^4.0|^5.0", "symfony/routing": "^3.4|^4.0|^5.0", "symfony/stopwatch": "^3.4|^4.0|^5.0", "symfony/templating": "^3.4|^4.0|^5.0", "symfony/translation": "^4.2|^5.0", "symfony/translation-contracts": "^1.1|^2", "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "symfony/browser-kit": "", "symfony/config": "", "symfony/console": "", "symfony/dependency-injection": "" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\HttpKernel\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-03-04T18:00:27+00:00" }, { "name": "symfony/mime", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", "reference": "6db092f97cd6eee8d4b2026e3a8fa3f576b396d4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/mime/zipball/6db092f97cd6eee8d4b2026e3a8fa3f576b396d4", "reference": "6db092f97cd6eee8d4b2026e3a8fa3f576b396d4", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/mailer": "<4.4" }, "require-dev": { "egulias/email-validator": "^2.1.10", "symfony/dependency-injection": "^3.4|^4.1|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Mime\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Allows manipulating MIME messages", "homepage": "https://symfony.com", "keywords": [ "mime", "mime-type" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-14T12:29:41+00:00" }, { "name": "symfony/polyfill-ctype", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "ctype", "polyfill", "portable" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-idn", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", "shasum": "" }, "require": { "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Laurent Bassin", "email": "laurent@bassin.info" }, { "name": "Trevor Rowbotham", "email": "trevor.rowbotham@pm.me" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "idn", "intl", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "intl", "normalizer", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-mbstring", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", "mbstring", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php72", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, "files": [ "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php73", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php80", "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, "files": [ "bootstrap.php" ], "classmap": [ "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Ion Bazan", "email": "ion.bazan@gmail.com" }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", "shim" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/routing", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", "reference": "69919991c845b34626664ddc9b3aef9d09d2a5df" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/routing/zipball/69919991c845b34626664ddc9b3aef9d09d2a5df", "reference": "69919991c845b34626664ddc9b3aef9d09d2a5df", "shasum": "" }, "require": { "php": ">=7.1.3" }, "conflict": { "symfony/config": "<4.2", "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, "require-dev": { "doctrine/annotations": "^1.10.4", "psr/log": "~1.0", "symfony/config": "^4.2|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^3.4|^4.0|^5.0", "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", "symfony/config": "For using the all-in-one router or any loader", "symfony/expression-language": "For using expression matching", "symfony/http-foundation": "For using a Symfony Request object", "symfony/yaml": "For using the YAML loader" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Routing\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Maps an HTTP request to a set of configuration variables", "homepage": "https://symfony.com", "keywords": [ "router", "routing", "uri", "url" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-22T15:37:04+00:00" }, { "name": "symfony/service-contracts", "version": "v1.1.9", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/container": "^1.0" }, "suggest": { "symfony/service-implementation": "" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ "abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2020-07-06T13:19:58+00:00" }, { "name": "symfony/var-dumper", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", "reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a1eab2f69906dc83c5ddba4632180260d0ab4f7f", "reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php72": "~1.5", "symfony/polyfill-php80": "^1.15" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/console": "<3.4" }, "require-dev": { "ext-iconv": "*", "symfony/console": "^3.4|^4.0|^5.0", "symfony/process": "^4.4|^5.0", "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", "ext-intl": "To show region name in time zone dump", "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" }, "bin": [ "Resources/bin/var-dump-server" ], "type": "library", "autoload": { "files": [ "Resources/functions/dump.php" ], "psr-4": { "Symfony\\Component\\VarDumper\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ "debug", "dump" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/var-exporter", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", "reference": "3a3ea598bba6901d20b58c2579f68700089244ed" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/var-exporter/zipball/3a3ea598bba6901d20b58c2579f68700089244ed", "reference": "3a3ea598bba6901d20b58c2579f68700089244ed", "shasum": "" }, "require": { "php": ">=7.1.3" }, "require-dev": { "symfony/var-dumper": "^4.4.9|^5.0.9" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\VarExporter\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Allows exporting any serializable PHP data structure to plain PHP code", "homepage": "https://symfony.com", "keywords": [ "clone", "construct", "export", "hydrate", "instantiate", "serialize" ], "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/yaml", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", "reference": "29e61305e1c79d25f71060903982ead8f533e267" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/yaml/zipball/29e61305e1c79d25f71060903982ead8f533e267", "reference": "29e61305e1c79d25f71060903982ead8f533e267", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" }, "require-dev": { "symfony/console": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-22T15:36:50+00:00" }, { "name": "twig/extensions", "version": "v1.5.4", "source": { "type": "git", "url": "https://github.com/twigphp/Twig-extensions.git", "reference": "57873c8b0c1be51caa47df2cdb824490beb16202" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/twigphp/Twig-extensions/zipball/57873c8b0c1be51caa47df2cdb824490beb16202", "reference": "57873c8b0c1be51caa47df2cdb824490beb16202", "shasum": "" }, "require": { "twig/twig": "^1.27|^2.0" }, "require-dev": { "symfony/phpunit-bridge": "^3.4", "symfony/translation": "^2.7|^3.4" }, "suggest": { "symfony/translation": "Allow the time_diff output to be translated" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.5-dev" } }, "autoload": { "psr-0": { "Twig_Extensions_": "lib/" }, "psr-4": { "Twig\\Extensions\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" } ], "description": "Common additional features for Twig that do not directly belong in core", "keywords": [ "i18n", "text" ], "abandoned": true, "time": "2018-12-05T18:34:18+00:00" }, { "name": "twig/twig", "version": "v2.13.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", "reference": "57e96259776ddcacf1814885fc3950460c8e18ef" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/twigphp/Twig/zipball/57e96259776ddcacf1814885fc3950460c8e18ef", "reference": "57e96259776ddcacf1814885fc3950460c8e18ef", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "psr/container": "^1.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.13-dev" } }, "autoload": { "psr-0": { "Twig_": "lib/" }, "psr-4": { "Twig\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com", "homepage": "http://fabien.potencier.org", "role": "Lead Developer" }, { "name": "Twig Team", "role": "Contributors" }, { "name": "Armin Ronacher", "email": "armin.ronacher@active-4.com", "role": "Project Founder" } ], "description": "Twig, the flexible, fast, and secure template language for PHP", "homepage": "https://twig.symfony.com", "keywords": [ "templating" ], "funding": [ { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/twig/twig", "type": "tidelift" } ], "time": "2020-08-05T15:09:04+00:00" }, { "name": "webmozart/assert", "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", "vimeo/psalm": "<3.9.1" }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", "keywords": [ "assert", "check", "validate" ], "time": "2020-07-08T17:02:28+00:00" }, { "name": "whitehat101/apr1-md5", "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/whitehat101/apr1-md5.git", "reference": "8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/whitehat101/apr1-md5/zipball/8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819", "reference": "8b261c9fc0481b4e9fa9d01c6ca70867b5d5e819", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { "phpunit/phpunit": "4.0.*" }, "type": "library", "autoload": { "psr-4": { "WhiteHat101\\Crypt\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jeremy Ebler", "email": "jebler@gmail.com" } ], "description": "Apache's APR1-MD5 algorithm in pure PHP", "homepage": "https://github.com/whitehat101/apr1-md5", "keywords": [ "MD5", "apr1" ], "time": "2015-02-11T11:06:42+00:00" } ], "packages-dev": [ { "name": "amphp/amp", "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", "reference": "efca2b32a7580087adb8aabbff6be1dc1bb924a9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/amp/zipball/efca2b32a7580087adb8aabbff6be1dc1bb924a9", "reference": "efca2b32a7580087adb8aabbff6be1dc1bb924a9", "shasum": "" }, "require": { "php": ">=7" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1", "ext-json": "*", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^6.0.9 | ^7", "psalm/phar": "^3.11@dev", "react/promise": "^2" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { "Amp\\": "lib" }, "files": [ "lib/functions.php", "lib/Internal/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Daniel Lowrey", "email": "rdlowrey@php.net" }, { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Bob Weinand", "email": "bobwei9@hotmail.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A non-blocking concurrency framework for PHP applications.", "homepage": "http://amphp.org/amp", "keywords": [ "async", "asynchronous", "awaitable", "concurrency", "event", "event-loop", "future", "non-blocking", "promise" ], "funding": [ { "url": "https://github.com/amphp", "type": "github" } ], "time": "2021-01-10T17:06:37+00:00" }, { "name": "amphp/byte-stream", "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/amphp/byte-stream.git", "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/amphp/byte-stream/zipball/f0c20cf598a958ba2aa8c6e5a71c697d652c7088", "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088", "shasum": "" }, "require": { "amphp/amp": "^2", "php": ">=7.1" }, "require-dev": { "amphp/php-cs-fixer-config": "dev-master", "amphp/phpunit-util": "^1.4", "friendsofphp/php-cs-fixer": "^2.3", "jetbrains/phpstorm-stubs": "^2019.3", "phpunit/phpunit": "^6 || ^7 || ^8", "psalm/phar": "^3.11.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "Amp\\ByteStream\\": "lib" }, "files": [ "lib/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Aaron Piotrowski", "email": "aaron@trowski.com" }, { "name": "Niklas Keller", "email": "me@kelunik.com" } ], "description": "A stream abstraction to make working with non-blocking I/O simple.", "homepage": "http://amphp.org/byte-stream", "keywords": [ "amp", "amphp", "async", "io", "non-blocking", "stream" ], "time": "2020-06-29T18:35:05+00:00" }, { "name": "composer/package-versions-deprecated", "version": "1.11.99.1", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "shasum": "" }, "require": { "composer-plugin-api": "^1.1.0 || ^2.0", "php": "^7 || ^8" }, "replace": { "ocramius/package-versions": "1.11.99" }, "require-dev": { "composer/composer": "^1.9.3 || ^2.0@dev", "ext-zip": "^1.13", "phpunit/phpunit": "^6.5 || ^7" }, "type": "composer-plugin", "extra": { "class": "PackageVersions\\Installer", "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "PackageVersions\\": "src/PackageVersions" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be" } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2020-11-11T10:22:58+00:00" }, { "name": "composer/semver", "version": "3.2.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^0.12.54", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nils Adermann", "email": "naderman@naderman.de", "homepage": "http://www.naderman.de" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be" }, { "name": "Rob Bast", "email": "rob.bast@gmail.com", "homepage": "http://robbast.nl" } ], "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ "semantic", "semver", "validation", "versioning" ], "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2020-11-13T08:59:24+00:00" }, { "name": "composer/xdebug-handler", "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", "reference": "f28d44c286812c714741478d968104c5e604a1d4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", "reference": "f28d44c286812c714741478d968104c5e604a1d4", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" }, "type": "library", "autoload": { "psr-4": { "Composer\\XdebugHandler\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "John Stevenson", "email": "john-stevenson@blueyonder.co.uk" } ], "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "time": "2020-11-13T08:04:11+00:00" }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", "source": { "type": "git", "url": "https://github.com/dnoegel/php-xdg-base-dir.git", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", "shasum": "" }, "require": { "php": ">=5.3.2" }, "require-dev": { "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" }, "type": "library", "autoload": { "psr-4": { "XdgBaseDir\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "implementation of xdg base directory specification for php", "time": "2019-12-04T15:06:13+00:00" }, { "name": "doctrine/instantiator", "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { "url": "https://www.patreon.com/phpdoctrine", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", "type": "tidelift" } ], "time": "2020-11-10T18:47:58+00:00" }, { "name": "felixfbecker/advanced-json-rpc", "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", "reference": "06f0b06043c7438959dbdeed8bb3f699a19be22e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/06f0b06043c7438959dbdeed8bb3f699a19be22e", "reference": "06f0b06043c7438959dbdeed8bb3f699a19be22e", "shasum": "" }, "require": { "netresearch/jsonmapper": "^1.0 || ^2.0", "php": "^7.1 || ^8.0", "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" }, "require-dev": { "phpunit/phpunit": "^7.0 || ^8.0" }, "type": "library", "autoload": { "psr-4": { "AdvancedJsonRpc\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "A more advanced JSONRPC implementation", "time": "2021-01-10T17:48:47+00:00" }, { "name": "felixfbecker/language-server-protocol", "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/felixfbecker/php-language-server-protocol.git", "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/9d846d1f5cf101deee7a61c8ba7caa0a975cd730", "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpstan/phpstan": "*", "squizlabs/php_codesniffer": "^3.1", "vimeo/psalm": "^4.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "LanguageServerProtocol\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "ISC" ], "authors": [ { "name": "Felix Becker", "email": "felix.b@outlook.com" } ], "description": "PHP classes for the Language Server Protocol", "keywords": [ "language", "microsoft", "php", "server" ], "time": "2021-02-22T14:02:09+00:00" }, { "name": "mikey179/vfsstream", "version": "v1.6.8", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { "phpunit/phpunit": "^4.5|^5.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.6.x-dev" } }, "autoload": { "psr-0": { "org\\bovigo\\vfs\\": "src/main/php" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Frank Kleine", "homepage": "http://frankkleine.de/", "role": "Developer" } ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", "time": "2019-10-30T15:31:00+00:00" }, { "name": "myclabs/deep-copy", "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "replace": { "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", "keywords": [ "clone", "copy", "duplicate", "object", "object graph" ], "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], "time": "2020-11-13T09:40:50+00:00" }, { "name": "netresearch/jsonmapper", "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/cweiske/jsonmapper.git", "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", "shasum": "" }, "require": { "ext-json": "*", "ext-pcre": "*", "ext-reflection": "*", "ext-spl": "*", "php": ">=5.6" }, "require-dev": { "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", "squizlabs/php_codesniffer": "~3.5" }, "type": "library", "autoload": { "psr-0": { "JsonMapper": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "OSL-3.0" ], "authors": [ { "name": "Christian Weiske", "email": "cweiske@cweiske.de", "homepage": "http://github.com/cweiske/jsonmapper/", "role": "Developer" } ], "description": "Map nested JSON structures onto PHP classes", "time": "2020-04-16T18:48:43+00:00" }, { "name": "nikic/php-parser", "version": "v4.10.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=7.0" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { "dev-master": "4.9-dev" } }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Nikita Popov" } ], "description": "A PHP parser written in PHP", "keywords": [ "parser", "php" ], "time": "2020-12-20T10:01:03+00:00" }, { "name": "openlss/lib-array2xml", "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/nullivex/lib-array2xml.git", "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", "shasum": "" }, "require": { "php": ">=5.3.2" }, "type": "library", "autoload": { "psr-0": { "LSS": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Bryan Tong", "email": "bryan@nullivex.com", "homepage": "https://www.nullivex.com" }, { "name": "Tony Butler", "email": "spudz76@gmail.com", "homepage": "https://www.nullivex.com" } ], "description": "Array2XML conversion library credit to lalit.org", "homepage": "https://www.nullivex.com", "keywords": [ "array", "array conversion", "xml", "xml conversion" ], "time": "2019-03-29T20:06:56+00:00" }, { "name": "phar-io/manifest", "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "description": "Library for handling version information and constraints", "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-common", "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jaap van Otterdijk", "email": "opensource@ijaap.nl" } ], "description": "Common reflection classes used by phpdocumentor to reflect the code structure", "homepage": "http://www.phpdoc.org", "keywords": [ "FQSEN", "phpDocumentor", "phpdoc", "reflection", "static analysis" ], "time": "2020-04-27T09:25:28+00:00" }, { "name": "phpdocumentor/reflection-docblock", "version": "4.3.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", "shasum": "" }, "require": { "php": "^7.0", "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpdocumentor/type-resolver": "0.4.*", "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ "src/" ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "time": "2019-12-28T18:55:12+00:00" }, { "name": "phpdocumentor/type-resolver", "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { "php": "^7.1", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "^7.1", "mockery/mockery": "~1", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Mike van Riel", "email": "me@mikevanriel.com" } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", "version": "v1.10.3", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", "reference": "451c3cd1418cf640de218914901e51b064abb093" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", "reference": "451c3cd1418cf640de218914901e51b064abb093", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" }, "require-dev": { "phpspec/phpspec": "^2.5 || ^3.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.10.x-dev" } }, "autoload": { "psr-4": { "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Konstantin Kudryashov", "email": "ever.zet@gmail.com", "homepage": "http://everzet.com" }, { "name": "Marcello Duarte", "email": "marcello.duarte@gmail.com" } ], "description": "Highly opinionated mocking framework for PHP 5.3+", "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", "fake", "mock", "spy", "stub" ], "time": "2020-03-05T15:02:03+00:00" }, { "name": "phpunit/php-code-coverage", "version": "6.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", "php": "^7.1", "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", "sebastian/environment": "^3.1 || ^4.0", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "suggest": { "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "6.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ "coverage", "testing", "xunit" ], "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ "filesystem", "iterator" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T08:25:21+00:00" }, { "name": "phpunit/php-text-template", "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Simple template engine.", "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ "template" ], "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Utility class for timing", "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T08:20:02+00:00" }, { "name": "phpunit/php-token-stream", "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ "tokenizer" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "abandoned": true, "time": "2020-11-30T08:38:46+00:00" }, { "name": "phpunit/phpunit", "version": "7.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", "shasum": "" }, "require": { "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.2", "phar-io/version": "^2.0", "php": "^7.1", "phpspec/prophecy": "^1.7", "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^4.0", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, "conflict": { "phpunit/phpunit-mock-objects": "*" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-soap": "*", "ext-xdebug": "*", "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { "dev-master": "7.5-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "The PHP Unit Testing framework.", "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], "time": "2020-01-08T08:45:45+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", "shasum": "" }, "require": { "php": ">=5.6" }, "require-dev": { "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", "shasum": "" }, "require": { "php": ">=7.1", "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" } ], "description": "Provides the functionality to compare PHP values for equality", "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T08:04:30+00:00" }, { "name": "sebastian/diff", "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff", "udiff", "unidiff", "unified diff" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:59:04+00:00" }, { "name": "sebastian/environment", "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", "shasum": "" }, "require": { "php": ">=7.1" }, "require-dev": { "phpunit/phpunit": "^7.5" }, "suggest": { "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.2-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", "hhvm" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:53:42+00:00" }, { "name": "sebastian/exporter", "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", "shasum": "" }, "require": { "php": ">=7.0", "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.1.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Volker Dusch", "email": "github@wallbash.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" }, { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:47:53+00:00" }, { "name": "sebastian/global-state", "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { "php": "^7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Snapshotting of global state", "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", "shasum": "" }, "require": { "php": ">=7.0", "sebastian/object-reflector": "^1.1.1", "sebastian/recursion-context": "^3.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:40:27+00:00" }, { "name": "sebastian/object-reflector", "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", "shasum": "" }, "require": { "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "1.1-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:37:18+00:00" }, { "name": "sebastian/recursion-context", "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", "shasum": "" }, "require": { "php": ">=7.0" }, "require-dev": { "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { "dev-master": "3.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, { "name": "Adam Harvey", "email": "aharvey@php.net" } ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:34:24+00:00" }, { "name": "sebastian/resource-operations", "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", "shasum": "" }, "require": { "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" } ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], "time": "2020-11-30T07:30:19+00:00" }, { "name": "sebastian/version", "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { "php": ">=5.6" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "lead" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, { "name": "sensiolabs/security-checker", "version": "v6.0.3", "source": { "type": "git", "url": "https://github.com/sensiolabs/security-checker.git", "reference": "a576c01520d9761901f269c4934ba55448be4a54" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/a576c01520d9761901f269c4934ba55448be4a54", "reference": "a576c01520d9761901f269c4934ba55448be4a54", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/console": "^2.8|^3.4|^4.2|^5.0", "symfony/http-client": "^4.3|^5.0", "symfony/mime": "^4.3|^5.0", "symfony/polyfill-ctype": "^1.11" }, "bin": [ "security-checker" ], "type": "library", "extra": { "branch-alias": { "dev-master": "6.0-dev" } }, "autoload": { "psr-4": { "SensioLabs\\Security\\": "SensioLabs/Security" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Fabien Potencier", "email": "fabien.potencier@gmail.com" } ], "description": "A security checker for your composer.lock", "abandoned": "https://github.com/fabpot/local-php-security-checker", "time": "2019-11-01T13:20:14+00:00" }, { "name": "simplesamlphp/simplesamlphp-test-framework", "version": "v0.1.2", "source": { "type": "git", "url": "https://github.com/simplesamlphp/simplesamlphp-test-framework.git", "reference": "f54a646a95f7b928d06a36d5f7f8303ac07f09b2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-test-framework/zipball/f54a646a95f7b928d06a36d5f7f8303ac07f09b2", "reference": "f54a646a95f7b928d06a36d5f7f8303ac07f09b2", "shasum": "" }, "require": { "php": ">=7.0", "phpunit/phpunit": "^6.5|^7.0|^8.0", "sensiolabs/security-checker": "^5.0|^6.0", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^3.2|^4.0" }, "require-dev": { "ext-curl": "*", "simplesamlphp/simplesamlphp": "dev-master" }, "bin": [ "bin/check-syntax-json.sh", "bin/check-syntax-php.sh", "bin/check-syntax-xml.sh", "bin/check-syntax-yaml.sh" ], "type": "project", "autoload": { "psr-4": { "SimpleSAML\\TestUtils\\": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "LGPL-3.0-or-later" ], "authors": [ { "name": "Tim van Dijen", "email": "tvdijen@gmail.com" } ], "description": "Test framework for SimpleSAMLphp and related repositories ", "keywords": [ "test-framework" ], "time": "2019-12-30T21:14:30+00:00" }, { "name": "squizlabs/php_codesniffer", "version": "3.5.8", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Greg Sherwood", "role": "lead" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], "time": "2020-10-23T02:01:07+00:00" }, { "name": "symfony/http-client", "version": "v4.4.20", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", "reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/http-client/zipball/67c5af7489b3c2eea771abd973243f5c58f5fb40", "reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/log": "^1.0", "symfony/http-client-contracts": "^1.1.10|^2", "symfony/polyfill-php73": "^1.11", "symfony/service-contracts": "^1.0|^2" }, "provide": { "php-http/async-client-implementation": "*", "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", "symfony/http-client-implementation": "1.1|2.0" }, "require-dev": { "guzzlehttp/promises": "^1.4", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", "symfony/dependency-injection": "^4.3|^5.0", "symfony/http-kernel": "^4.4.13", "symfony/process": "^4.2|^5.0" }, "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\HttpClient\\": "" }, "exclude-from-classmap": [ "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Nicolas Grekas", "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "funding": [ { "url": "https://symfony.com/sponsor", "type": "custom" }, { "url": "https://github.com/fabpot", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], "time": "2021-02-25T18:06:45+00:00" }, { "name": "theseer/tokenizer", "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", "php": "^7.0" }, "type": "library", "autoload": { "classmap": [ "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "time": "2019-06-13T22:48:21+00:00" }, { "name": "vimeo/psalm", "version": "3.18.2", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", "reference": "19aa905f7c3c7350569999a93c40ae91ae4e1626" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/vimeo/psalm/zipball/19aa905f7c3c7350569999a93c40ae91ae4e1626", "reference": "19aa905f7c3c7350569999a93c40ae91ae4e1626", "shasum": "" }, "require": { "amphp/amp": "^2.1", "amphp/byte-stream": "^1.5", "composer/package-versions-deprecated": "^1.8.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^1.1", "dnoegel/php-xdg-base-dir": "^0.1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-simplexml": "*", "ext-tokenizer": "*", "felixfbecker/advanced-json-rpc": "^3.0.3", "felixfbecker/language-server-protocol": "^1.4", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0", "nikic/php-parser": "4.3.* || 4.4.* || 4.5.* || 4.6.* || ^4.8", "openlss/lib-array2xml": "^1.0", "php": "^7.1.3|^8", "sebastian/diff": "^3.0 || ^4.0", "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", "webmozart/glob": "^4.1", "webmozart/path-util": "^2.3" }, "provide": { "psalm/psalm": "self.version" }, "require-dev": { "amphp/amp": "^2.4.2", "bamarni/composer-bin-plugin": "^1.2", "brianium/paratest": "^4.0.0", "ext-curl": "*", "phpdocumentor/reflection-docblock": "^4.3.4 || ^5", "phpmyadmin/sql-parser": "5.1.0", "phpspec/prophecy": ">=1.9.0", "phpunit/phpunit": "^7.5.16 || ^8.5 || ^9.0", "psalm/plugin-phpunit": "^0.11", "slevomat/coding-standard": "^5.0", "squizlabs/php_codesniffer": "^3.5", "symfony/process": "^4.3", "weirdan/prophecy-shim": "^1.0 || ^2.0" }, "suggest": { "ext-igbinary": "^2.0.5" }, "bin": [ "psalm", "psalm-language-server", "psalm-plugin", "psalm-refactor", "psalter" ], "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev", "dev-2.x": "2.x-dev", "dev-1.x": "1.x-dev" } }, "autoload": { "psr-4": { "Psalm\\": "src/Psalm/" }, "files": [ "src/functions.php", "src/spl_object_id.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Matthew Brown" } ], "description": "A static analysis tool for finding errors in PHP applications", "keywords": [ "code", "inspection", "php" ], "time": "2020-10-20T13:48:22+00:00" }, { "name": "webmozart/glob", "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/webmozarts/glob.git", "reference": "3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozarts/glob/zipball/3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe", "reference": "3cbf63d4973cf9d780b93d2da8eec7e4a9e63bbe", "shasum": "" }, "require": { "php": "^5.3.3|^7.0", "webmozart/path-util": "^2.2" }, "require-dev": { "phpunit/phpunit": "^4.6", "sebastian/version": "^1.0.1", "symfony/filesystem": "^2.5" }, "type": "library", "extra": { "branch-alias": { "dev-master": "4.1-dev" } }, "autoload": { "psr-4": { "Webmozart\\Glob\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "A PHP implementation of Ant's glob.", "time": "2015-12-29T11:14:33+00:00" }, { "name": "webmozart/path-util", "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/path-util.git", "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", "shasum": "" }, "require": { "php": ">=5.3.3", "webmozart/assert": "~1.0" }, "require-dev": { "phpunit/phpunit": "^4.6", "sebastian/version": "^1.0.1" }, "type": "library", "extra": { "branch-alias": { "dev-master": "2.3-dev" } }, "autoload": { "psr-4": { "Webmozart\\PathUtil\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" } ], "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=7.1 <8.0", "ext-spl": "*", "ext-zlib": "*", "ext-pcre": "*", "ext-openssl": "*", "ext-dom": "*", "ext-date": "*", "ext-hash": "*", "ext-json": "*", "ext-mbstring": "*" }, "platform-dev": { "ext-curl": "*" }, "plugin-api-version": "1.1.0" } simplesamlphp-1.19.1/composer.json0000644000000000000000000001175014042503477015713 0ustar rootroot{ "name": "simplesamlphp/simplesamlphp", "description": "A PHP implementation of a SAML 2.0 service provider and identity provider, also compatible with Shibboleth 1.3 and 2.0.", "type": "project", "keywords": [ "saml2", "shibboleth","oauth","ws-federation","sp","idp" ], "homepage": "http://simplesamlphp.org", "license": "LGPL-2.1-or-later", "version": "v1.19.1", "authors": [ { "name": "Andreas Åkre Solberg", "email": "andreas.solberg@uninett.no" }, { "name": "Olav Morken", "email": "olav.morken@uninett.no" }, { "name": "Jaime Perez", "email": "jaime.perez@uninett.no" } ], "autoload": { "psr-4": { "SimpleSAML\\": "lib/SimpleSAML" }, "files": ["lib/_autoload_modules.php"] }, "autoload-dev": { "psr-4": { "SimpleSAML\\Test\\": ["tests", "tests/lib/SimpleSAML"] }, "files": ["tests/_autoload_modules.php"] }, "require": { "php": ">=7.1 <8.0", "ext-SPL": "*", "ext-zlib": "*", "ext-pcre": "*", "ext-openssl": "*", "ext-dom": "*", "ext-date": "*", "ext-hash": "*", "ext-json": "*", "ext-mbstring": "*", "gettext/gettext": "^4.8", "phpmailer/phpmailer": "^6.1", "robrichards/xmlseclibs": "^3.1", "simplesamlphp/assert": "^0.0.13", "simplesamlphp/saml2": "^4.2", "simplesamlphp/simplesamlphp-module-adfs": "^0.9", "simplesamlphp/simplesamlphp-module-authcrypt": "^0.9", "simplesamlphp/simplesamlphp-module-authfacebook": "^0.9", "simplesamlphp/simplesamlphp-module-authorize": "^0.9", "simplesamlphp/simplesamlphp-module-authtwitter": "^0.9", "simplesamlphp/simplesamlphp-module-authwindowslive": "^0.9", "simplesamlphp/simplesamlphp-module-authx509": "^0.9", "simplesamlphp/simplesamlphp-module-authyubikey": "^0.9", "simplesamlphp/simplesamlphp-module-cas": "^0.9", "simplesamlphp/simplesamlphp-module-cdc": "^0.9", "simplesamlphp/simplesamlphp-module-consent": "^0.9", "simplesamlphp/simplesamlphp-module-consentadmin": "^0.9", "simplesamlphp/simplesamlphp-module-discopower": "^0.9", "simplesamlphp/simplesamlphp-module-exampleattributeserver": "^1.0", "simplesamlphp/simplesamlphp-module-expirycheck": "^0.9", "simplesamlphp/simplesamlphp-module-ldap": "^0.9 | ^1.0", "simplesamlphp/simplesamlphp-module-memcookie": "^1.2", "simplesamlphp/simplesamlphp-module-memcachemonitor": "^0.9", "simplesamlphp/simplesamlphp-module-metarefresh": "^0.9", "simplesamlphp/simplesamlphp-module-negotiate": "^0.9", "simplesamlphp/simplesamlphp-module-oauth": "^0.9", "simplesamlphp/simplesamlphp-module-preprodwarning": "^0.9", "simplesamlphp/simplesamlphp-module-radius": "^0.9", "simplesamlphp/simplesamlphp-module-riak": "^0.9", "simplesamlphp/simplesamlphp-module-smartattributes": "^0.9", "simplesamlphp/simplesamlphp-module-sanitycheck": "^0.9", "simplesamlphp/simplesamlphp-module-statistics": "^0.9", "simplesamlphp/simplesamlphp-module-sqlauth": "^0.9", "simplesamlphp/twig-configurable-i18n": "~2.3.3", "symfony/cache": "^4.4 || ^5.0", "symfony/config": "^4.4 || ^5.0", "symfony/console": "^4.4 || ^5.0", "symfony/dependency-injection": "^4.4 || ^5.0", "symfony/finder": "^4.4 || ^5.0", "symfony/framework-bundle": "^4.4 || ^5.0", "symfony/http-foundation": "^4.4 || ^5.0", "symfony/http-kernel": "^4.4 || ^5.0", "symfony/routing": "^4.4 || ^5.0", "symfony/var-exporter": "^4.4 || ^5.0", "symfony/yaml": "^4.4 || ^5.0", "twig/twig": "^1.43 || ^2.0" }, "require-dev": { "ext-curl": "*", "mikey179/vfsstream": "~1.6", "phpunit/phpunit": "^7.5", "simplesamlphp/simplesamlphp-test-framework": "^0.1.2", "vimeo/psalm": "~3.14" }, "suggest": { "predis/predis": "Needed if a Redis server is used to store session information", "ext-curl": "Needed in order to check for updates automatically", "ext-ldap": "Needed if an LDAP backend is used", "ext-radius": "Needed if a Radius backend is used", "ext-memcache": "Needed if a Memcache server is used to store session information", "ext-pdo": "Needed if a database backend is used, either for authentication or to store session information", "ext-mysql": "Needed if a MySQL backend is used, either for authentication or to store session information", "ext-pgsql": "Needed if a PostgreSQL backend is used, either for authentication or to store session information" }, "support": { "issues": "https://github.com/simplesamlphp/simplesamlphp/issues", "source": "https://github.com/simplesamlphp/simplesamlphp" } } simplesamlphp-1.19.1/attributemap/0000755000000000000000000000000014042503475015664 5ustar rootrootsimplesamlphp-1.19.1/attributemap/deprecatedSchacNS.php0000644000000000000000000000365114042503475021705 0ustar rootroot SCHAC_OLD_NS.'schacCountryOfCitizenship', SCHAC_NEW_NS.'schacCountryOfResidence' => SCHAC_OLD_NS.'schacCountryOfResidence', SCHAC_NEW_NS.'schacDateOfBirth' => SCHAC_OLD_NS.'schacDateOfBirth', SCHAC_NEW_NS.'schacExpiryDate' => SCHAC_OLD_NS.'schacExpiryDate', SCHAC_NEW_NS.'schacGender' => SCHAC_OLD_NS.'schacGender', SCHAC_NEW_NS.'schacHomeOrganization' => SCHAC_OLD_NS.'schacHomeOrganization', SCHAC_NEW_NS.'schacHomeOrganizationType' => SCHAC_OLD_NS.'schacHomeOrganizationType', SCHAC_NEW_NS.'schacMotherTongue' => SCHAC_OLD_NS.'schacMotherTongue', SCHAC_NEW_NS.'schacPersonalPosition' => SCHAC_OLD_NS.'schacPersonalPosition', SCHAC_NEW_NS.'schacPersonalTitle' => SCHAC_OLD_NS.'schacPersonalTitle', SCHAC_NEW_NS.'schacPersonalUniqueCode' => SCHAC_OLD_NS.'schacPersonalUniqueCode', SCHAC_NEW_NS.'schacPersonalUniqueID' => SCHAC_OLD_NS.'schacPersonalUniqueID', SCHAC_NEW_NS.'schacPlaceOfBirth' => SCHAC_OLD_NS.'schacPlaceOfBirth', SCHAC_NEW_NS.'schacProjectMembership' => SCHAC_OLD_NS.'schacProjectMembership', SCHAC_NEW_NS.'schacProjectSpecificRole' => SCHAC_OLD_NS.'schacProjectSpecificRole', SCHAC_NEW_NS.'schacSn1' => SCHAC_OLD_NS.'schacSn1', SCHAC_NEW_NS.'schacSn2' => SCHAC_OLD_NS.'schacSn2', SCHAC_NEW_NS.'schacUserPresenceID' => SCHAC_OLD_NS.'schacUserPresenceID', SCHAC_NEW_NS.'schacUserPrivateAttribute' => SCHAC_OLD_NS.'schacUserPrivateAttribute', SCHAC_NEW_NS.'schacUserStatus' => SCHAC_OLD_NS.'schacUserStatus', SCHAC_NEW_NS.'schacYearOfBirth' => SCHAC_OLD_NS.'schacYearOfBirth', ]; simplesamlphp-1.19.1/attributemap/name2urn.php0000644000000000000000000003700714042503475020133 0ustar rootroot 'urn:mace:dir:attribute-def:aRecord', 'aliasedEntryName' => 'urn:mace:dir:attribute-def:aliasedEntryName', 'aliasedObjectName' => 'urn:mace:dir:attribute-def:aliasedObjectName', 'associatedDomain' => 'urn:mace:dir:attribute-def:associatedDomain', 'associatedName' => 'urn:mace:dir:attribute-def:associatedName', 'audio' => 'urn:mace:dir:attribute-def:audio', 'authorityRevocationList' => 'urn:mace:dir:attribute-def:authorityRevocationList', 'buildingName' => 'urn:mace:dir:attribute-def:buildingName', 'businessCategory' => 'urn:mace:dir:attribute-def:businessCategory', 'c' => 'urn:mace:dir:attribute-def:c', 'cACertificate' => 'urn:mace:dir:attribute-def:cACertificate', 'cNAMERecord' => 'urn:mace:dir:attribute-def:cNAMERecord', 'carLicense' => 'urn:mace:dir:attribute-def:carLicense', 'certificateRevocationList' => 'urn:mace:dir:attribute-def:certificateRevocationList', 'cn' => 'urn:mace:dir:attribute-def:cn', 'co' => 'urn:mace:dir:attribute-def:co', 'commonName' => 'urn:mace:dir:attribute-def:commonName', 'countryName' => 'urn:mace:dir:attribute-def:countryName', 'crossCertificatePair' => 'urn:mace:dir:attribute-def:crossCertificatePair', 'dITRedirect' => 'urn:mace:dir:attribute-def:dITRedirect', 'dSAQuality' => 'urn:mace:dir:attribute-def:dSAQuality', 'dc' => 'urn:mace:dir:attribute-def:dc', 'deltaRevocationList' => 'urn:mace:dir:attribute-def:deltaRevocationList', 'departmentNumber' => 'urn:mace:dir:attribute-def:departmentNumber', 'description' => 'urn:mace:dir:attribute-def:description', 'destinationIndicator' => 'urn:mace:dir:attribute-def:destinationIndicator', 'displayName' => 'urn:mace:dir:attribute-def:displayName', 'distinguishedName' => 'urn:mace:dir:attribute-def:distinguishedName', 'dmdName' => 'urn:mace:dir:attribute-def:dmdName', 'dnQualifier' => 'urn:mace:dir:attribute-def:dnQualifier', 'documentAuthor' => 'urn:mace:dir:attribute-def:documentAuthor', 'documentIdentifier' => 'urn:mace:dir:attribute-def:documentIdentifier', 'documentLocation' => 'urn:mace:dir:attribute-def:documentLocation', 'documentPublisher' => 'urn:mace:dir:attribute-def:documentPublisher', 'documentTitle' => 'urn:mace:dir:attribute-def:documentTitle', 'documentVersion' => 'urn:mace:dir:attribute-def:documentVersion', 'domainComponent' => 'urn:mace:dir:attribute-def:domainComponent', 'drink' => 'urn:mace:dir:attribute-def:drink', 'eduOrgHomePageURI' => 'urn:mace:dir:attribute-def:eduOrgHomePageURI', 'eduOrgIdentityAuthNPolicyURI' => 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI', 'eduOrgLegalName' => 'urn:mace:dir:attribute-def:eduOrgLegalName', 'eduOrgSuperiorURI' => 'urn:mace:dir:attribute-def:eduOrgSuperiorURI', 'eduOrgWhitePagesURI' => 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI', 'eduPersonAffiliation' => 'urn:mace:dir:attribute-def:eduPersonAffiliation', 'eduPersonAssurance' => 'urn:mace:dir:attribute-def:eduPersonAssurance', 'eduPersonEntitlement' => 'urn:mace:dir:attribute-def:eduPersonEntitlement', 'eduPersonNickname' => 'urn:mace:dir:attribute-def:eduPersonNickname', 'eduPersonOrgDN' => 'urn:mace:dir:attribute-def:eduPersonOrgDN', 'eduPersonOrgUnitDN' => 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN', 'eduPersonPrimaryAffiliation' => 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation', 'eduPersonPrimaryOrgUnitDN' => 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN', 'eduPersonPrincipalName' => 'urn:mace:dir:attribute-def:eduPersonPrincipalName', 'eduPersonScopedAffiliation' => 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation', 'eduPersonTargetedID' => 'urn:mace:dir:attribute-def:eduPersonTargetedID', 'eduPersonUniqueId' => 'urn:mace:dir:attribute-def:eduPersonUniqueId', 'email' => 'urn:mace:dir:attribute-def:email', 'emailAddress' => 'urn:mace:dir:attribute-def:emailAddress', 'employeeNumber' => 'urn:mace:dir:attribute-def:employeeNumber', 'employeeType' => 'urn:mace:dir:attribute-def:employeeType', 'enhancedSearchGuide' => 'urn:mace:dir:attribute-def:enhancedSearchGuide', 'facsimileTelephoneNumber' => 'urn:mace:dir:attribute-def:facsimileTelephoneNumber', 'favouriteDrink' => 'urn:mace:dir:attribute-def:favouriteDrink', 'fax' => 'urn:mace:dir:attribute-def:fax', 'federationFeideSchemaVersion' => 'urn:mace:dir:attribute-def:federationFeideSchemaVersion', 'friendlyCountryName' => 'urn:mace:dir:attribute-def:friendlyCountryName', 'generationQualifier' => 'urn:mace:dir:attribute-def:generationQualifier', 'givenName' => 'urn:mace:dir:attribute-def:givenName', 'gn' => 'urn:mace:dir:attribute-def:gn', 'homePhone' => 'urn:mace:dir:attribute-def:homePhone', 'homePostalAddress' => 'urn:mace:dir:attribute-def:homePostalAddress', 'homeTelephoneNumber' => 'urn:mace:dir:attribute-def:homeTelephoneNumber', 'host' => 'urn:mace:dir:attribute-def:host', 'houseIdentifier' => 'urn:mace:dir:attribute-def:houseIdentifier', 'info' => 'urn:mace:dir:attribute-def:info', 'initials' => 'urn:mace:dir:attribute-def:initials', 'internationaliSDNNumber' => 'urn:mace:dir:attribute-def:internationaliSDNNumber', 'janetMailbox' => 'urn:mace:dir:attribute-def:janetMailbox', 'jpegPhoto' => 'urn:mace:dir:attribute-def:jpegPhoto', 'knowledgeInformation' => 'urn:mace:dir:attribute-def:knowledgeInformation', 'l' => 'urn:mace:dir:attribute-def:l', 'labeledURI' => 'urn:mace:dir:attribute-def:labeledURI', 'localityName' => 'urn:mace:dir:attribute-def:localityName', 'mDRecord' => 'urn:mace:dir:attribute-def:mDRecord', 'mXRecord' => 'urn:mace:dir:attribute-def:mXRecord', 'mail' => 'urn:mace:dir:attribute-def:mail', 'mailPreferenceOption' => 'urn:mace:dir:attribute-def:mailPreferenceOption', 'manager' => 'urn:mace:dir:attribute-def:manager', 'member' => 'urn:mace:dir:attribute-def:member', 'mobile' => 'urn:mace:dir:attribute-def:mobile', 'mobileTelephoneNumber' => 'urn:mace:dir:attribute-def:mobileTelephoneNumber', 'nSRecord' => 'urn:mace:dir:attribute-def:nSRecord', 'name' => 'urn:mace:dir:attribute-def:name', 'norEduOrgAcronym' => 'urn:mace:dir:attribute-def:norEduOrgAcronym', 'norEduOrgNIN' => 'urn:mace:dir:attribute-def:norEduOrgNIN', 'norEduOrgSchemaVersion' => 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion', 'norEduOrgUniqueIdentifier' => 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier', 'norEduOrgUniqueNumber' => 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber', 'norEduOrgUnitUniqueIdentifier' => 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier', 'norEduOrgUnitUniqueNumber' => 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber', 'norEduPersonBirthDate' => 'urn:mace:dir:attribute-def:norEduPersonBirthDate', 'norEduPersonLIN' => 'urn:mace:dir:attribute-def:norEduPersonLIN', 'norEduPersonNIN' => 'urn:mace:dir:attribute-def:norEduPersonNIN', 'o' => 'urn:mace:dir:attribute-def:o', 'objectClass' => 'urn:mace:dir:attribute-def:objectClass', 'organizationName' => 'urn:mace:dir:attribute-def:organizationName', 'organizationalStatus' => 'urn:mace:dir:attribute-def:organizationalStatus', 'organizationalUnitName' => 'urn:mace:dir:attribute-def:organizationalUnitName', 'otherMailbox' => 'urn:mace:dir:attribute-def:otherMailbox', 'ou' => 'urn:mace:dir:attribute-def:ou', 'owner' => 'urn:mace:dir:attribute-def:owner', 'pager' => 'urn:mace:dir:attribute-def:pager', 'pagerTelephoneNumber' => 'urn:mace:dir:attribute-def:pagerTelephoneNumber', 'pairwise-id' => 'urn:oasis:names:tc:SAML:attribute:pairwise-id', 'personalSignature' => 'urn:mace:dir:attribute-def:personalSignature', 'personalTitle' => 'urn:mace:dir:attribute-def:personalTitle', 'photo' => 'urn:mace:dir:attribute-def:photo', 'physicalDeliveryOfficeName' => 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName', 'pkcs9email' => 'urn:mace:dir:attribute-def:pkcs9email', 'postOfficeBox' => 'urn:mace:dir:attribute-def:postOfficeBox', 'postalAddress' => 'urn:mace:dir:attribute-def:postalAddress', 'postalCode' => 'urn:mace:dir:attribute-def:postalCode', 'preferredDeliveryMethod' => 'urn:mace:dir:attribute-def:preferredDeliveryMethod', 'preferredLanguage' => 'urn:mace:dir:attribute-def:preferredLanguage', 'presentationAddress' => 'urn:mace:dir:attribute-def:presentationAddress', 'protocolInformation' => 'urn:mace:dir:attribute-def:protocolInformation', 'pseudonym' => 'urn:mace:dir:attribute-def:pseudonym', 'registeredAddress' => 'urn:mace:dir:attribute-def:registeredAddress', 'rfc822Mailbox' => 'urn:mace:dir:attribute-def:rfc822Mailbox', 'roleOccupant' => 'urn:mace:dir:attribute-def:roleOccupant', 'roomNumber' => 'urn:mace:dir:attribute-def:roomNumber', 'sOARecord' => 'urn:mace:dir:attribute-def:sOARecord', 'schacCountryOfCitizenship' => 'urn:mace:terena.org:attribute-def:schacCountryOfCitizenship', 'schacCountryOfResidence' => 'urn:mace:terena.org:attribute-def:schacCountryOfResidence', 'schacDateOfBirth' => 'urn:mace:terena.org:attribute-def:schacDateOfBirth', 'schacExpiryDate' => 'urn:mace:terena.org:attribute-def:schacExpiryDate', 'schacGender' => 'urn:mace:terena.org:attribute-def:schacGender', 'schacHomeOrganization' => 'urn:mace:terena.org:attribute-def:schacHomeOrganization', 'schacHomeOrganizationType' => 'urn:mace:terena.org:attribute-def:schacHomeOrganizationType', 'schacMotherTongue' => 'urn:mace:terena.org:attribute-def:schacMotherTongue', 'schacPersonalPosition' => 'urn:mace:terena.org:attribute-def:schacPersonalPosition', 'schacPersonalTitle' => 'urn:mace:terena.org:attribute-def:schacPersonalTitle', 'schacPersonalUniqueCode' => 'urn:mace:terena.org:attribute-def:schacPersonalUniqueCode', 'schacPersonalUniqueID' => 'urn:mace:terena.org:attribute-def:schacPersonalUniqueID', 'schacPlaceOfBirth' => 'urn:mace:terena.org:attribute-def:schacPlaceOfBirth', 'schacProjectMembership' => 'urn:mace:terena.org:attribute-def:schacProjectMembership', 'schacProjectSpecificRole' => 'urn:mace:terena.org:attribute-def:schacProjectSpecificRole', 'schacSn1' => 'urn:mace:terena.org:attribute-def:schacSn1', 'schacSn2' => 'urn:mace:terena.org:attribute-def:schacSn2', 'schacUserPresenceID' => 'urn:mace:terena.org:attribute-def:schacUserPresenceID', 'schacUserPrivateAttribute' => 'urn:mace:terena.org:attribute-def:schacUserPrivateAttribute', 'schacUserStatus' => 'urn:mace:terena.org:attribute-def:schacUserStatus', 'schacYearOfBirth' => 'urn:mace:terena.org:attribute-def:schacYearOfBirth', 'searchGuide' => 'urn:mace:dir:attribute-def:searchGuide', 'secretary' => 'urn:mace:dir:attribute-def:secretary', 'seeAlso' => 'urn:mace:dir:attribute-def:seeAlso', 'serialNumber' => 'urn:mace:dir:attribute-def:serialNumber', 'singleLevelQuality' => 'urn:mace:dir:attribute-def:singleLevelQuality', 'sisSchoolGrade' => 'urn:mace:dir:attribute-def:sisSchoolGrade', 'sisLegalGuardianFor' => 'urn:mace:dir:attribute-def:sisLegalGuardianFor', 'sn' => 'urn:mace:dir:attribute-def:sn', 'st' => 'urn:mace:dir:attribute-def:st', 'stateOrProvinceName' => 'urn:mace:dir:attribute-def:stateOrProvinceName', 'street' => 'urn:mace:dir:attribute-def:street', 'streetAddress' => 'urn:mace:dir:attribute-def:streetAddress', 'subject-id' => 'urn:oasis:names:tc:SAML:attribute:subject-id', 'subtreeMaximumQuality' => 'urn:mace:dir:attribute-def:subtreeMaximumQuality', 'subtreeMinimumQuality' => 'urn:mace:dir:attribute-def:subtreeMinimumQuality', 'supportedAlgorithms' => 'urn:mace:dir:attribute-def:supportedAlgorithms', 'supportedApplicationContext' => 'urn:mace:dir:attribute-def:supportedApplicationContext', 'surname' => 'urn:mace:dir:attribute-def:surname', 'telephoneNumber' => 'urn:mace:dir:attribute-def:telephoneNumber', 'teletexTerminalIdentifier' => 'urn:mace:dir:attribute-def:teletexTerminalIdentifier', 'telexNumber' => 'urn:mace:dir:attribute-def:telexNumber', 'textEncodedORAddress' => 'urn:mace:dir:attribute-def:textEncodedORAddress', 'title' => 'urn:mace:dir:attribute-def:title', 'uid' => 'urn:mace:dir:attribute-def:uid', 'uniqueIdentifier' => 'urn:mace:dir:attribute-def:uniqueIdentifier', 'uniqueMember' => 'urn:mace:dir:attribute-def:uniqueMember', 'userCertificate' => 'urn:mace:dir:attribute-def:userCertificate', 'userClass' => 'urn:mace:dir:attribute-def:userClass', 'userPKCS12' => 'urn:mace:dir:attribute-def:userPKCS12', 'userPassword' => 'urn:mace:dir:attribute-def:userPassword', 'userSMIMECertificate' => 'urn:mace:dir:attribute-def:userSMIMECertificate', 'userid' => 'urn:mace:dir:attribute-def:userid', 'x121Address' => 'urn:mace:dir:attribute-def:x121Address', 'x500UniqueIdentifier' => 'urn:mace:dir:attribute-def:x500UniqueIdentifier', ]; simplesamlphp-1.19.1/attributemap/oid-feide.php0000644000000000000000000000073514042503475020227 0ustar rootroot 'mobile', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6' => 'eduPersonPrincipalName', 'urn:oid:0.9.2342.19200300.100.1.3' => 'mail', 'urn:oid:2.5.4.3' => 'cn', 'urn:oid:2.16.840.1.113730.3.1.241' => 'displayName', 'urn:oid:2.5.4.4' => 'sn', 'urn:oid:2.5.4.42' => 'givenName', 'urn:oid:2.16.756.1.2.5.1.1.1' => 'eduPerson', ]; simplesamlphp-1.19.1/attributemap/oid2name.php0000644000000000000000000002444614042503475020105 0ustar rootroot 'uid', 'urn:oid:0.9.2342.19200300.100.1.10' => 'manager', 'urn:oid:0.9.2342.19200300.100.1.11' => 'documentIdentifier', 'urn:oid:0.9.2342.19200300.100.1.12' => 'documentTitle', 'urn:oid:0.9.2342.19200300.100.1.13' => 'documentVersion', 'urn:oid:0.9.2342.19200300.100.1.14' => 'documentAuthor', 'urn:oid:0.9.2342.19200300.100.1.15' => 'documentLocation', 'urn:oid:0.9.2342.19200300.100.1.2' => 'textEncodedORAddress', 'urn:oid:0.9.2342.19200300.100.1.20' => 'homePhone', 'urn:oid:0.9.2342.19200300.100.1.21' => 'secretary', 'urn:oid:0.9.2342.19200300.100.1.22' => 'otherMailbox', 'urn:oid:0.9.2342.19200300.100.1.25' => 'dc', 'urn:oid:0.9.2342.19200300.100.1.26' => 'aRecord', 'urn:oid:0.9.2342.19200300.100.1.27' => 'mDRecord', 'urn:oid:0.9.2342.19200300.100.1.28' => 'mXRecord', 'urn:oid:0.9.2342.19200300.100.1.29' => 'nSRecord', 'urn:oid:0.9.2342.19200300.100.1.3' => 'mail', 'urn:oid:0.9.2342.19200300.100.1.30' => 'sOARecord', 'urn:oid:0.9.2342.19200300.100.1.31' => 'cNAMERecord', 'urn:oid:0.9.2342.19200300.100.1.37' => 'associatedDomain', 'urn:oid:0.9.2342.19200300.100.1.38' => 'associatedName', 'urn:oid:0.9.2342.19200300.100.1.39' => 'homePostalAddress', 'urn:oid:0.9.2342.19200300.100.1.4' => 'info', 'urn:oid:0.9.2342.19200300.100.1.40' => 'personalTitle', 'urn:oid:0.9.2342.19200300.100.1.41' => 'mobile', 'urn:oid:0.9.2342.19200300.100.1.42' => 'pager', 'urn:oid:0.9.2342.19200300.100.1.43' => 'co', 'urn:oid:0.9.2342.19200300.100.1.44' => 'uniqueIdentifier', 'urn:oid:0.9.2342.19200300.100.1.45' => 'organizationalStatus', 'urn:oid:0.9.2342.19200300.100.1.46' => 'janetMailbox', 'urn:oid:0.9.2342.19200300.100.1.47' => 'mailPreferenceOption', 'urn:oid:0.9.2342.19200300.100.1.48' => 'buildingName', 'urn:oid:0.9.2342.19200300.100.1.49' => 'dSAQuality', 'urn:oid:0.9.2342.19200300.100.1.5' => 'drink', 'urn:oid:0.9.2342.19200300.100.1.50' => 'singleLevelQuality', 'urn:oid:0.9.2342.19200300.100.1.51' => 'subtreeMinimumQuality', 'urn:oid:0.9.2342.19200300.100.1.52' => 'subtreeMaximumQuality', 'urn:oid:0.9.2342.19200300.100.1.53' => 'personalSignature', 'urn:oid:0.9.2342.19200300.100.1.54' => 'dITRedirect', 'urn:oid:0.9.2342.19200300.100.1.55' => 'audio', 'urn:oid:0.9.2342.19200300.100.1.56' => 'documentPublisher', 'urn:oid:0.9.2342.19200300.100.1.6' => 'roomNumber', 'urn:oid:0.9.2342.19200300.100.1.60' => 'jpegPhoto', 'urn:oid:0.9.2342.19200300.100.1.7' => 'photo', 'urn:oid:0.9.2342.19200300.100.1.8' => 'userClass', 'urn:oid:0.9.2342.19200300.100.1.9' => 'host', 'urn:oid:1.2.840.113549.1.9.1' => 'email', 'urn:oid:1.2.752.194.10.2.2' => 'sisSchoolGrade', 'urn:oid:1.2.752.194.10.2.1' => 'sisLegalGuardianFor', 'urn:oid:1.2.752.194.10.3' => 'sisOrgDepartment', 'urn:oid:1.2.752.194.10.2.4' => 'sisSchoolUnitCode', 'urn:oid:1.3.6.1.4.1.2428.90.1.1' => 'norEduOrgUniqueNumber', 'urn:oid:1.3.6.1.4.1.2428.90.1.11' => 'norEduOrgSchemaVersion', 'urn:oid:1.3.6.1.4.1.2428.90.1.12' => 'norEduOrgNIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.2' => 'norEduOrgUnitUniqueNumber', 'urn:oid:1.3.6.1.4.1.2428.90.1.3' => 'norEduPersonBirthDate', 'urn:oid:1.3.6.1.4.1.2428.90.1.4' => 'norEduPersonLIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.5' => 'norEduPersonNIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.6' => 'norEduOrgAcronym', 'urn:oid:1.3.6.1.4.1.2428.90.1.7' => 'norEduOrgUniqueIdentifier', 'urn:oid:1.3.6.1.4.1.2428.90.1.8' => 'norEduOrgUnitUniqueIdentifier', 'urn:oid:1.3.6.1.4.1.2428.90.1.9' => 'federationFeideSchemaVersion', 'urn:oid:1.3.6.1.4.1.24552.500.1.1.1.13' => 'sshPublicKey', 'urn:oid:1.3.6.1.4.1.250.1.57' => 'labeledURI', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1' => 'eduPersonAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.11' => 'eduPersonAssurance', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10' => 'eduPersonTargetedID', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.13' => 'eduPersonUniqueId', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.16' => 'eduPersonOrcid', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.2' => 'eduPersonNickname', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.3' => 'eduPersonOrgDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.4' => 'eduPersonOrgUnitDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.5' => 'eduPersonPrimaryAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6' => 'eduPersonPrincipalName', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.7' => 'eduPersonEntitlement', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.8' => 'eduPersonPrimaryOrgUnitDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.9' => 'eduPersonScopedAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.2' => 'eduOrgHomePageURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.3' => 'eduOrgIdentityAuthNPolicyURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.4' => 'eduOrgLegalName', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.5' => 'eduOrgSuperiorURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.6' => 'eduOrgWhitePagesURI', 'urn:oid:1.3.6.1.4.1.5923.1.5.1.1' => 'isMemberOf', 'urn:oid:1.3.6.1.4.1.25178.1.0.2.3' => 'schacYearOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.1' => 'schacMotherTongue', 'urn:oid:1.3.6.1.4.1.25178.1.2.2' => 'schacGender', 'urn:oid:1.3.6.1.4.1.25178.1.2.3' => 'schacDateOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.4' => 'schacPlaceOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.5' => 'schacCountryOfCitizenship', 'urn:oid:1.3.6.1.4.1.25178.1.2.6' => 'schacSn1', 'urn:oid:1.3.6.1.4.1.25178.1.2.7' => 'schacSn2', 'urn:oid:1.3.6.1.4.1.25178.1.2.8' => 'schacPersonalTitle', 'urn:oid:1.3.6.1.4.1.25178.1.2.9' => 'schacHomeOrganization', 'urn:oid:1.3.6.1.4.1.25178.1.2.10' => 'schacHomeOrganizationType', 'urn:oid:1.3.6.1.4.1.25178.1.2.11' => 'schacCountryOfResidence', 'urn:oid:1.3.6.1.4.1.25178.1.2.12' => 'schacUserPresenceID', 'urn:oid:1.3.6.1.4.1.25178.1.2.13' => 'schacPersonalPosition', 'urn:oid:1.3.6.1.4.1.25178.1.2.14' => 'schacPersonalUniqueCode', 'urn:oid:1.3.6.1.4.1.25178.1.2.15' => 'schacPersonalUniqueID', 'urn:oid:1.3.6.1.4.1.25178.1.2.17' => 'schacExpiryDate', 'urn:oid:1.3.6.1.4.1.25178.1.2.18' => 'schacUserPrivateAttribute', 'urn:oid:1.3.6.1.4.1.25178.1.2.19' => 'schacUserStatus', 'urn:oid:1.3.6.1.4.1.25178.1.2.20' => 'schacProjectMembership', 'urn:oid:1.3.6.1.4.1.25178.1.2.21' => 'schacProjectSpecificRole', 'urn:oid:2.16.840.1.113730.3.1.1' => 'carLicense', 'urn:oid:2.16.840.1.113730.3.1.2' => 'departmentNumber', 'urn:oid:2.16.840.1.113730.3.1.216' => 'userPKCS12', 'urn:oid:2.16.840.1.113730.3.1.241' => 'displayName', 'urn:oid:2.16.840.1.113730.3.1.3' => 'employeeNumber', 'urn:oid:2.16.840.1.113730.3.1.39' => 'preferredLanguage', 'urn:oid:2.16.840.1.113730.3.1.4' => 'employeeType', 'urn:oid:2.16.840.1.113730.3.1.40' => 'userSMIMECertificate', 'urn:oid:2.5.4.0' => 'objectClass', 'urn:oid:2.5.4.1' => 'aliasedObjectName', 'urn:oid:2.5.4.10' => 'o', 'urn:oid:2.5.4.11' => 'ou', 'urn:oid:2.5.4.12' => 'title', 'urn:oid:2.5.4.13' => 'description', 'urn:oid:2.5.4.14' => 'searchGuide', 'urn:oid:2.5.4.15' => 'businessCategory', 'urn:oid:2.5.4.16' => 'postalAddress', 'urn:oid:2.5.4.17' => 'postalCode', 'urn:oid:2.5.4.18' => 'postOfficeBox', 'urn:oid:2.5.4.19' => 'physicalDeliveryOfficeName', 'urn:oid:2.5.4.2' => 'knowledgeInformation', 'urn:oid:2.5.4.20' => 'telephoneNumber', 'urn:oid:2.5.4.21' => 'telexNumber', 'urn:oid:2.5.4.22' => 'teletexTerminalIdentifier', 'urn:oid:2.5.4.23' => 'facsimileTelephoneNumber', 'urn:oid:2.5.4.24' => 'x121Address', 'urn:oid:2.5.4.25' => 'internationaliSDNNumber', 'urn:oid:2.5.4.26' => 'registeredAddress', 'urn:oid:2.5.4.27' => 'destinationIndicator', 'urn:oid:2.5.4.28' => 'preferredDeliveryMethod', 'urn:oid:2.5.4.29' => 'presentationAddress', 'urn:oid:2.5.4.3' => 'cn', 'urn:oid:2.5.4.30' => 'supportedApplicationContext', 'urn:oid:2.5.4.31' => 'member', 'urn:oid:2.5.4.32' => 'owner', 'urn:oid:2.5.4.33' => 'roleOccupant', 'urn:oid:2.5.4.34' => 'seeAlso', 'urn:oid:2.5.4.35' => 'userPassword', 'urn:oid:2.5.4.36' => 'userCertificate', 'urn:oid:2.5.4.37' => 'cACertificate', 'urn:oid:2.5.4.38' => 'authorityRevocationList', 'urn:oid:2.5.4.39' => 'certificateRevocationList', 'urn:oid:2.5.4.4' => 'sn', 'urn:oid:2.5.4.40' => 'crossCertificatePair', 'urn:oid:2.5.4.41' => 'name', 'urn:oid:2.5.4.42' => 'givenName', 'urn:oid:2.5.4.43' => 'initials', 'urn:oid:2.5.4.44' => 'generationQualifier', 'urn:oid:2.5.4.45' => 'x500UniqueIdentifier', 'urn:oid:2.5.4.46' => 'dnQualifier', 'urn:oid:2.5.4.47' => 'enhancedSearchGuide', 'urn:oid:2.5.4.48' => 'protocolInformation', 'urn:oid:2.5.4.49' => 'distinguishedName', 'urn:oid:2.5.4.5' => 'serialNumber', 'urn:oid:2.5.4.50' => 'uniqueMember', 'urn:oid:2.5.4.51' => 'houseIdentifier', 'urn:oid:2.5.4.52' => 'supportedAlgorithms', 'urn:oid:2.5.4.53' => 'deltaRevocationList', 'urn:oid:2.5.4.54' => 'dmdName', 'urn:oid:2.5.4.6' => 'c', 'urn:oid:2.5.4.65' => 'pseudonym', 'urn:oid:2.5.4.7' => 'l', 'urn:oid:2.5.4.8' => 'st', 'urn:oid:2.5.4.9' => 'street', ]; simplesamlphp-1.19.1/attributemap/twitter2name.php0000644000000000000000000000105414042503475021022 0ustar rootroot 'eduPersonPrincipalName', // screen_name@twitter.com 'twitter_targetedID' => 'eduPersonTargetedID', // http://twitter.com!id_str // Attributes Returned by Twitter 'twitter.screen_name' => 'uid', // equivalent to twitter username without leading @ 'twitter.name' => 'displayName', 'twitter.url' => 'labeledURI', 'twitter.lang' => 'preferredLanguage', 'twitter.description' => 'description', ]; simplesamlphp-1.19.1/attributemap/openid2name.php0000644000000000000000000000361114042503475020577 0ustar rootroot 'displayName', // Alias/Username -> displayName 'openid.sreg.nickname' => 'displayName', 'http://axschema.org/contact/email' => 'mail', // Email 'openid.sreg.email' => 'mail', 'http://axschema.org/namePerson' => 'displayName', // Full name -> displayName 'openid.sreg.fullname' => 'displayName', 'http://axschema.org/contact/postalCode/home' => 'postalCode', // Postal code 'openid.sreg.postcode' => 'postalCode', 'http://axschema.org/contact/country/home' => 'countryName', // Country 'openid.sreg.country' => 'countryName', 'http://axschema.org/pref/language' => 'preferredLanguage', // Language 'openid.sreg.language' => 'preferredLanguage', // Name 'http://axschema.org/namePerson/prefix' => 'personalTitle', // Name prefix 'http://axschema.org/namePerson/first' => 'givenName', // First name 'http://axschema.org/namePerson/last' => 'sn', // Last name // Work 'http://axschema.org/company/name' => 'o', // Company name 'http://axschema.org/company/title' => 'title', // Job title // Telephone 'http://axschema.org/contact/phone/default' => 'telephoneNumber', // Phone (preferred) 'http://axschema.org/contact/phone/home' => 'homePhone', // Phone (home) 'http://axschema.org/contact/phone/business' => 'telephoneNumber', // Phone (work) 'http://axschema.org/contact/phone/cell' => 'mobile', // Phone (mobile) 'http://axschema.org/contact/phone/fax' => 'facsimileTelephoneNumber', // Phone (fax) // Further attributes can be found at http://www.axschema.org/types/ ]; simplesamlphp-1.19.1/attributemap/windowslive2name.php0000644000000000000000000000165514042503475021701 0ustar rootroot 'eduPersonPrincipalName', // uid @ windowslive.com 'windowslive_targetedID' => 'eduPersonTargetedID', // http://windowslive.com!uid 'windowslive_uid' => 'uid', // windows live id 'windowslive_mail' => 'mail', // Attributes Returned by Windows Live ID 'windowslive.FirstName' => 'givenName', 'windowslive.LastName' => 'sn', 'windowslive.Location' => 'l', // Attributes returned by Microsoft Graph - http://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/user 'windowslive.givenName' => 'givenName', 'windowslive.surname' => 'sn', 'windowslive.displayName' => 'displayName', 'windowslive.id' => 'uid', 'windowslive.userPrincipalName' => 'eduPersonPrincipalName', 'windowslive.mail' => 'mail', 'windowslive.preferredLanguage' => 'preferredLanguage', ]; simplesamlphp-1.19.1/attributemap/feide-oid.php0000644000000000000000000000022014042503475020214 0ustar rootroot 'urn:mace:dir:attribute-def:mobile', 'displayName' => 'urn:oid:2.16.840.1.113730.3.1.241', ]; simplesamlphp-1.19.1/attributemap/name2oid.php0000644000000000000000000003154614042503475020104 0ustar rootroot 'urn:oid:0.9.2342.19200300.100.1.26', 'aliasedEntryName' => 'urn:oid:2.5.4.1', 'aliasedObjectName' => 'urn:oid:2.5.4.1', 'associatedDomain' => 'urn:oid:0.9.2342.19200300.100.1.37', 'associatedName' => 'urn:oid:0.9.2342.19200300.100.1.38', 'audio' => 'urn:oid:0.9.2342.19200300.100.1.55', 'authorityRevocationList' => 'urn:oid:2.5.4.38', 'buildingName' => 'urn:oid:0.9.2342.19200300.100.1.48', 'businessCategory' => 'urn:oid:2.5.4.15', 'c' => 'urn:oid:2.5.4.6', 'cACertificate' => 'urn:oid:2.5.4.37', 'cNAMERecord' => 'urn:oid:0.9.2342.19200300.100.1.31', 'carLicense' => 'urn:oid:2.16.840.1.113730.3.1.1', 'certificateRevocationList' => 'urn:oid:2.5.4.39', 'cn' => 'urn:oid:2.5.4.3', 'co' => 'urn:oid:0.9.2342.19200300.100.1.43', 'commonName' => 'urn:oid:2.5.4.3', 'countryName' => 'urn:oid:2.5.4.6', 'crossCertificatePair' => 'urn:oid:2.5.4.40', 'dITRedirect' => 'urn:oid:0.9.2342.19200300.100.1.54', 'dSAQuality' => 'urn:oid:0.9.2342.19200300.100.1.49', 'dc' => 'urn:oid:0.9.2342.19200300.100.1.25', 'deltaRevocationList' => 'urn:oid:2.5.4.53', 'departmentNumber' => 'urn:oid:2.16.840.1.113730.3.1.2', 'description' => 'urn:oid:2.5.4.13', 'destinationIndicator' => 'urn:oid:2.5.4.27', 'displayName' => 'urn:oid:2.16.840.1.113730.3.1.241', 'distinguishedName' => 'urn:oid:2.5.4.49', 'dmdName' => 'urn:oid:2.5.4.54', 'dnQualifier' => 'urn:oid:2.5.4.46', 'documentAuthor' => 'urn:oid:0.9.2342.19200300.100.1.14', 'documentIdentifier' => 'urn:oid:0.9.2342.19200300.100.1.11', 'documentLocation' => 'urn:oid:0.9.2342.19200300.100.1.15', 'documentPublisher' => 'urn:oid:0.9.2342.19200300.100.1.56', 'documentTitle' => 'urn:oid:0.9.2342.19200300.100.1.12', 'documentVersion' => 'urn:oid:0.9.2342.19200300.100.1.13', 'domainComponent' => 'urn:oid:0.9.2342.19200300.100.1.25', 'drink' => 'urn:oid:0.9.2342.19200300.100.1.5', 'eduOrgHomePageURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.2', 'eduOrgIdentityAuthNPolicyURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.3', 'eduOrgLegalName' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.4', 'eduOrgSuperiorURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.5', 'eduOrgWhitePagesURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.6', 'eduPersonAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1', 'eduPersonAssurance' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.11', 'eduPersonEntitlement' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.7', 'eduPersonNickname' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.2', 'eduPersonOrgDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.3', 'eduPersonOrgUnitDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.4', 'eduPersonPrimaryAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.5', 'eduPersonPrimaryOrgUnitDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.8', 'eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'eduPersonScopedAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.9', 'eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'eduPersonUniqueId' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.13', 'eduPersonOrcid' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.16', 'email' => 'urn:oid:1.2.840.113549.1.9.1', 'emailAddress' => 'urn:oid:1.2.840.113549.1.9.1', 'employeeNumber' => 'urn:oid:2.16.840.1.113730.3.1.3', 'employeeType' => 'urn:oid:2.16.840.1.113730.3.1.4', 'enhancedSearchGuide' => 'urn:oid:2.5.4.47', 'facsimileTelephoneNumber' => 'urn:oid:2.5.4.23', 'favouriteDrink' => 'urn:oid:0.9.2342.19200300.100.1.5', 'fax' => 'urn:oid:2.5.4.23', 'federationFeideSchemaVersion' => 'urn:oid:1.3.6.1.4.1.2428.90.1.9', 'friendlyCountryName' => 'urn:oid:0.9.2342.19200300.100.1.43', 'generationQualifier' => 'urn:oid:2.5.4.44', 'givenName' => 'urn:oid:2.5.4.42', 'gn' => 'urn:oid:2.5.4.42', 'homePhone' => 'urn:oid:0.9.2342.19200300.100.1.20', 'homePostalAddress' => 'urn:oid:0.9.2342.19200300.100.1.39', 'homeTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.20', 'host' => 'urn:oid:0.9.2342.19200300.100.1.9', 'houseIdentifier' => 'urn:oid:2.5.4.51', 'info' => 'urn:oid:0.9.2342.19200300.100.1.4', 'initials' => 'urn:oid:2.5.4.43', 'internationaliSDNNumber' => 'urn:oid:2.5.4.25', 'isMemberOf' => 'urn:oid:1.3.6.1.4.1.5923.1.5.1.1', 'janetMailbox' => 'urn:oid:0.9.2342.19200300.100.1.46', 'jpegPhoto' => 'urn:oid:0.9.2342.19200300.100.1.60', 'knowledgeInformation' => 'urn:oid:2.5.4.2', 'l' => 'urn:oid:2.5.4.7', 'labeledURI' => 'urn:oid:1.3.6.1.4.1.250.1.57', 'localityName' => 'urn:oid:2.5.4.7', 'mDRecord' => 'urn:oid:0.9.2342.19200300.100.1.27', 'mXRecord' => 'urn:oid:0.9.2342.19200300.100.1.28', 'mail' => 'urn:oid:0.9.2342.19200300.100.1.3', 'mailPreferenceOption' => 'urn:oid:0.9.2342.19200300.100.1.47', 'manager' => 'urn:oid:0.9.2342.19200300.100.1.10', 'member' => 'urn:oid:2.5.4.31', 'mobile' => 'urn:oid:0.9.2342.19200300.100.1.41', 'mobileTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.41', 'nSRecord' => 'urn:oid:0.9.2342.19200300.100.1.29', 'name' => 'urn:oid:2.5.4.41', 'norEduOrgAcronym' => 'urn:oid:1.3.6.1.4.1.2428.90.1.6', 'norEduOrgNIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.12', 'norEduOrgSchemaVersion' => 'urn:oid:1.3.6.1.4.1.2428.90.1.11', 'norEduOrgUniqueIdentifier' => 'urn:oid:1.3.6.1.4.1.2428.90.1.7', 'norEduOrgUniqueNumber' => 'urn:oid:1.3.6.1.4.1.2428.90.1.1', 'norEduOrgUnitUniqueIdentifier' => 'urn:oid:1.3.6.1.4.1.2428.90.1.8', 'norEduOrgUnitUniqueNumber' => 'urn:oid:1.3.6.1.4.1.2428.90.1.2', 'norEduPersonBirthDate' => 'urn:oid:1.3.6.1.4.1.2428.90.1.3', 'norEduPersonLIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.4', 'norEduPersonNIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.5', 'o' => 'urn:oid:2.5.4.10', 'objectClass' => 'urn:oid:2.5.4.0', 'organizationName' => 'urn:oid:2.5.4.10', 'organizationalStatus' => 'urn:oid:0.9.2342.19200300.100.1.45', 'organizationalUnitName' => 'urn:oid:2.5.4.11', 'otherMailbox' => 'urn:oid:0.9.2342.19200300.100.1.22', 'ou' => 'urn:oid:2.5.4.11', 'owner' => 'urn:oid:2.5.4.32', 'pager' => 'urn:oid:0.9.2342.19200300.100.1.42', 'pagerTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.42', 'personalSignature' => 'urn:oid:0.9.2342.19200300.100.1.53', 'personalTitle' => 'urn:oid:0.9.2342.19200300.100.1.40', 'photo' => 'urn:oid:0.9.2342.19200300.100.1.7', 'physicalDeliveryOfficeName' => 'urn:oid:2.5.4.19', 'pkcs9email' => 'urn:oid:1.2.840.113549.1.9.1', 'postOfficeBox' => 'urn:oid:2.5.4.18', 'postalAddress' => 'urn:oid:2.5.4.16', 'postalCode' => 'urn:oid:2.5.4.17', 'preferredDeliveryMethod' => 'urn:oid:2.5.4.28', 'preferredLanguage' => 'urn:oid:2.16.840.1.113730.3.1.39', 'presentationAddress' => 'urn:oid:2.5.4.29', 'protocolInformation' => 'urn:oid:2.5.4.48', 'pseudonym' => 'urn:oid:2.5.4.65', 'registeredAddress' => 'urn:oid:2.5.4.26', 'rfc822Mailbox' => 'urn:oid:0.9.2342.19200300.100.1.3', 'roleOccupant' => 'urn:oid:2.5.4.33', 'roomNumber' => 'urn:oid:0.9.2342.19200300.100.1.6', 'sOARecord' => 'urn:oid:0.9.2342.19200300.100.1.30', 'schacCountryOfCitizenship' => 'urn:oid:1.3.6.1.4.1.25178.1.2.5', 'schacCountryOfResidence' => 'urn:oid:1.3.6.1.4.1.25178.1.2.11', 'schacDateOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.2.3', 'schacExpiryDate' => 'urn:oid:1.3.6.1.4.1.25178.1.2.17', 'schacGender' => 'urn:oid:1.3.6.1.4.1.25178.1.2.2', 'schacHomeOrganization' => 'urn:oid:1.3.6.1.4.1.25178.1.2.9', 'schacHomeOrganizationType' => 'urn:oid:1.3.6.1.4.1.25178.1.2.10', 'schacMotherTongue' => 'urn:oid:1.3.6.1.4.1.25178.1.2.1', 'schacPersonalPosition' => 'urn:oid:1.3.6.1.4.1.25178.1.2.13', 'schacPersonalTitle' => 'urn:oid:1.3.6.1.4.1.25178.1.2.8', 'schacPersonalUniqueCode' => 'urn:oid:1.3.6.1.4.1.25178.1.2.14', 'schacPersonalUniqueID' => 'urn:oid:1.3.6.1.4.1.25178.1.2.15', 'schacPlaceOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.2.4', 'schacProjectMembership' => 'urn:oid:1.3.6.1.4.1.25178.1.2.20', 'schacProjectSpecificRole' => 'urn:oid:1.3.6.1.4.1.25178.1.2.21', 'schacSn1' => 'urn:oid:1.3.6.1.4.1.25178.1.2.6', 'schacSn2' => 'urn:oid:1.3.6.1.4.1.25178.1.2.7', 'schacUserPresenceID' => 'urn:oid:1.3.6.1.4.1.25178.1.2.12', 'schacUserPrivateAttribute' => 'urn:oid:1.3.6.1.4.1.25178.1.2.18', 'schacUserStatus' => 'urn:oid:1.3.6.1.4.1.25178.1.2.19', 'schacYearOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.0.2.3', 'searchGuide' => 'urn:oid:2.5.4.14', 'secretary' => 'urn:oid:0.9.2342.19200300.100.1.21', 'seeAlso' => 'urn:oid:2.5.4.34', 'serialNumber' => 'urn:oid:2.5.4.5', 'singleLevelQuality' => 'urn:oid:0.9.2342.19200300.100.1.50', 'sisSchoolGrade' => 'urn:oid:1.2.752.194.10.2.2', 'sisLegalGuardianFor' => 'urn:oid:1.2.752.194.10.2.1', 'sisOrgDepartment' => 'urn:oid:1.2.752.194.10.3', 'sisSchoolUnitCode' => 'urn:oid:1.2.752.194.10.2.4', 'sn' => 'urn:oid:2.5.4.4', 'sshPublicKey' => 'urn:oid:1.3.6.1.4.1.24552.500.1.1.1.13', 'st' => 'urn:oid:2.5.4.8', 'stateOrProvinceName' => 'urn:oid:2.5.4.8', 'street' => 'urn:oid:2.5.4.9', 'streetAddress' => 'urn:oid:2.5.4.9', 'subtreeMaximumQuality' => 'urn:oid:0.9.2342.19200300.100.1.52', 'subtreeMinimumQuality' => 'urn:oid:0.9.2342.19200300.100.1.51', 'supportedAlgorithms' => 'urn:oid:2.5.4.52', 'supportedApplicationContext' => 'urn:oid:2.5.4.30', 'surname' => 'urn:oid:2.5.4.4', 'telephoneNumber' => 'urn:oid:2.5.4.20', 'teletexTerminalIdentifier' => 'urn:oid:2.5.4.22', 'telexNumber' => 'urn:oid:2.5.4.21', 'textEncodedORAddress' => 'urn:oid:0.9.2342.19200300.100.1.2', 'title' => 'urn:oid:2.5.4.12', 'uid' => 'urn:oid:0.9.2342.19200300.100.1.1', 'uniqueIdentifier' => 'urn:oid:0.9.2342.19200300.100.1.44', 'uniqueMember' => 'urn:oid:2.5.4.50', 'userCertificate' => 'urn:oid:2.5.4.36', 'userClass' => 'urn:oid:0.9.2342.19200300.100.1.8', 'userPKCS12' => 'urn:oid:2.16.840.1.113730.3.1.216', 'userPassword' => 'urn:oid:2.5.4.35', 'userSMIMECertificate' => 'urn:oid:2.16.840.1.113730.3.1.40', 'userid' => 'urn:oid:0.9.2342.19200300.100.1.1', 'x121Address' => 'urn:oid:2.5.4.24', 'x500UniqueIdentifier' => 'urn:oid:2.5.4.45', ]; simplesamlphp-1.19.1/attributemap/urn2oid.php0000644000000000000000000004411214042503475017761 0ustar rootroot 'urn:oid:0.9.2342.19200300.100.1.26', 'urn:mace:dir:attribute-def:aliasedEntryName' => 'urn:oid:2.5.4.1', 'urn:mace:dir:attribute-def:aliasedObjectName' => 'urn:oid:2.5.4.1', 'urn:mace:dir:attribute-def:associatedDomain' => 'urn:oid:0.9.2342.19200300.100.1.37', 'urn:mace:dir:attribute-def:associatedName' => 'urn:oid:0.9.2342.19200300.100.1.38', 'urn:mace:dir:attribute-def:audio' => 'urn:oid:0.9.2342.19200300.100.1.55', 'urn:mace:dir:attribute-def:authorityRevocationList' => 'urn:oid:2.5.4.38', 'urn:mace:dir:attribute-def:buildingName' => 'urn:oid:0.9.2342.19200300.100.1.48', 'urn:mace:dir:attribute-def:businessCategory' => 'urn:oid:2.5.4.15', 'urn:mace:dir:attribute-def:c' => 'urn:oid:2.5.4.6', 'urn:mace:dir:attribute-def:cACertificate' => 'urn:oid:2.5.4.37', 'urn:mace:dir:attribute-def:cNAMERecord' => 'urn:oid:0.9.2342.19200300.100.1.31', 'urn:mace:dir:attribute-def:carLicense' => 'urn:oid:2.16.840.1.113730.3.1.1', 'urn:mace:dir:attribute-def:certificateRevocationList' => 'urn:oid:2.5.4.39', 'urn:mace:dir:attribute-def:cn' => 'urn:oid:2.5.4.3', 'urn:mace:dir:attribute-def:co' => 'urn:oid:0.9.2342.19200300.100.1.43', 'urn:mace:dir:attribute-def:commonName' => 'urn:oid:2.5.4.3', 'urn:mace:dir:attribute-def:countryName' => 'urn:oid:2.5.4.6', 'urn:mace:dir:attribute-def:crossCertificatePair' => 'urn:oid:2.5.4.40', 'urn:mace:dir:attribute-def:dITRedirect' => 'urn:oid:0.9.2342.19200300.100.1.54', 'urn:mace:dir:attribute-def:dSAQuality' => 'urn:oid:0.9.2342.19200300.100.1.49', 'urn:mace:dir:attribute-def:dc' => 'urn:oid:0.9.2342.19200300.100.1.25', 'urn:mace:dir:attribute-def:deltaRevocationList' => 'urn:oid:2.5.4.53', 'urn:mace:dir:attribute-def:departmentNumber' => 'urn:oid:2.16.840.1.113730.3.1.2', 'urn:mace:dir:attribute-def:description' => 'urn:oid:2.5.4.13', 'urn:mace:dir:attribute-def:destinationIndicator' => 'urn:oid:2.5.4.27', 'urn:mace:dir:attribute-def:displayName' => 'urn:oid:2.16.840.1.113730.3.1.241', 'urn:mace:dir:attribute-def:distinguishedName' => 'urn:oid:2.5.4.49', 'urn:mace:dir:attribute-def:dmdName' => 'urn:oid:2.5.4.54', 'urn:mace:dir:attribute-def:dnQualifier' => 'urn:oid:2.5.4.46', 'urn:mace:dir:attribute-def:documentAuthor' => 'urn:oid:0.9.2342.19200300.100.1.14', 'urn:mace:dir:attribute-def:documentIdentifier' => 'urn:oid:0.9.2342.19200300.100.1.11', 'urn:mace:dir:attribute-def:documentLocation' => 'urn:oid:0.9.2342.19200300.100.1.15', 'urn:mace:dir:attribute-def:documentPublisher' => 'urn:oid:0.9.2342.19200300.100.1.56', 'urn:mace:dir:attribute-def:documentTitle' => 'urn:oid:0.9.2342.19200300.100.1.12', 'urn:mace:dir:attribute-def:documentVersion' => 'urn:oid:0.9.2342.19200300.100.1.13', 'urn:mace:dir:attribute-def:domainComponent' => 'urn:oid:0.9.2342.19200300.100.1.25', 'urn:mace:dir:attribute-def:drink' => 'urn:oid:0.9.2342.19200300.100.1.5', 'urn:mace:dir:attribute-def:eduOrgHomePageURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.2', 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.3', 'urn:mace:dir:attribute-def:eduOrgLegalName' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.4', 'urn:mace:dir:attribute-def:eduOrgSuperiorURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.5', 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI' => 'urn:oid:1.3.6.1.4.1.5923.1.2.1.6', 'urn:mace:dir:attribute-def:eduPersonAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1', 'urn:mace:dir:attribute-def:eduPersonAssurance' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.11', 'urn:mace:dir:attribute-def:eduPersonEntitlement' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.7', 'urn:mace:dir:attribute-def:eduPersonNickname' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.2', 'urn:mace:dir:attribute-def:eduPersonOrgDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.3', 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.4', 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.5', 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.8', 'urn:mace:dir:attribute-def:eduPersonPrincipalName' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6', 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.9', 'urn:mace:dir:attribute-def:eduPersonTargetedID' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:mace:dir:attribute-def:eduPersonUniqueId' => 'urn:oid:1.3.6.1.4.1.5923.1.1.1.13', 'urn:mace:dir:attribute-def:email' => 'urn:oid:1.2.840.113549.1.9.1', 'urn:mace:dir:attribute-def:emailAddress' => 'urn:oid:1.2.840.113549.1.9.1', 'urn:mace:dir:attribute-def:employeeNumber' => 'urn:oid:2.16.840.1.113730.3.1.3', 'urn:mace:dir:attribute-def:employeeType' => 'urn:oid:2.16.840.1.113730.3.1.4', 'urn:mace:dir:attribute-def:enhancedSearchGuide' => 'urn:oid:2.5.4.47', 'urn:mace:dir:attribute-def:facsimileTelephoneNumber' => 'urn:oid:2.5.4.23', 'urn:mace:dir:attribute-def:favouriteDrink' => 'urn:oid:0.9.2342.19200300.100.1.5', 'urn:mace:dir:attribute-def:fax' => 'urn:oid:2.5.4.23', 'urn:mace:dir:attribute-def:federationFeideSchemaVersion' => 'urn:oid:1.3.6.1.4.1.2428.90.1.9', 'urn:mace:dir:attribute-def:friendlyCountryName' => 'urn:oid:0.9.2342.19200300.100.1.43', 'urn:mace:dir:attribute-def:generationQualifier' => 'urn:oid:2.5.4.44', 'urn:mace:dir:attribute-def:givenName' => 'urn:oid:2.5.4.42', 'urn:mace:dir:attribute-def:gn' => 'urn:oid:2.5.4.42', 'urn:mace:dir:attribute-def:homePhone' => 'urn:oid:0.9.2342.19200300.100.1.20', 'urn:mace:dir:attribute-def:homePostalAddress' => 'urn:oid:0.9.2342.19200300.100.1.39', 'urn:mace:dir:attribute-def:homeTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.20', 'urn:mace:dir:attribute-def:host' => 'urn:oid:0.9.2342.19200300.100.1.9', 'urn:mace:dir:attribute-def:houseIdentifier' => 'urn:oid:2.5.4.51', 'urn:mace:dir:attribute-def:info' => 'urn:oid:0.9.2342.19200300.100.1.4', 'urn:mace:dir:attribute-def:initials' => 'urn:oid:2.5.4.43', 'urn:mace:dir:attribute-def:internationaliSDNNumber' => 'urn:oid:2.5.4.25', 'urn:mace:dir:attribute-def:janetMailbox' => 'urn:oid:0.9.2342.19200300.100.1.46', 'urn:mace:dir:attribute-def:jpegPhoto' => 'urn:oid:0.9.2342.19200300.100.1.60', 'urn:mace:dir:attribute-def:knowledgeInformation' => 'urn:oid:2.5.4.2', 'urn:mace:dir:attribute-def:l' => 'urn:oid:2.5.4.7', 'urn:mace:dir:attribute-def:labeledURI' => 'urn:oid:1.3.6.1.4.1.250.1.57', 'urn:mace:dir:attribute-def:localityName' => 'urn:oid:2.5.4.7', 'urn:mace:dir:attribute-def:mDRecord' => 'urn:oid:0.9.2342.19200300.100.1.27', 'urn:mace:dir:attribute-def:mXRecord' => 'urn:oid:0.9.2342.19200300.100.1.28', 'urn:mace:dir:attribute-def:mail' => 'urn:oid:0.9.2342.19200300.100.1.3', 'urn:mace:dir:attribute-def:mailPreferenceOption' => 'urn:oid:0.9.2342.19200300.100.1.47', 'urn:mace:dir:attribute-def:manager' => 'urn:oid:0.9.2342.19200300.100.1.10', 'urn:mace:dir:attribute-def:member' => 'urn:oid:2.5.4.31', 'urn:mace:dir:attribute-def:mobile' => 'urn:oid:0.9.2342.19200300.100.1.41', 'urn:mace:dir:attribute-def:mobileTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.41', 'urn:mace:dir:attribute-def:nSRecord' => 'urn:oid:0.9.2342.19200300.100.1.29', 'urn:mace:dir:attribute-def:name' => 'urn:oid:2.5.4.41', 'urn:mace:dir:attribute-def:norEduOrgAcronym' => 'urn:oid:1.3.6.1.4.1.2428.90.1.6', 'urn:mace:dir:attribute-def:norEduOrgNIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.12', 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion' => 'urn:oid:1.3.6.1.4.1.2428.90.1.11', 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier' => 'urn:oid:1.3.6.1.4.1.2428.90.1.7', 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber' => 'urn:oid:1.3.6.1.4.1.2428.90.1.1', 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier' => 'urn:oid:1.3.6.1.4.1.2428.90.1.8', 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber' => 'urn:oid:1.3.6.1.4.1.2428.90.1.2', 'urn:mace:dir:attribute-def:norEduPersonBirthDate' => 'urn:oid:1.3.6.1.4.1.2428.90.1.3', 'urn:mace:dir:attribute-def:norEduPersonLIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.4', 'urn:mace:dir:attribute-def:norEduPersonNIN' => 'urn:oid:1.3.6.1.4.1.2428.90.1.5', 'urn:mace:dir:attribute-def:o' => 'urn:oid:2.5.4.10', 'urn:mace:dir:attribute-def:objectClass' => 'urn:oid:2.5.4.0', 'urn:mace:dir:attribute-def:organizationName' => 'urn:oid:2.5.4.10', 'urn:mace:dir:attribute-def:organizationalStatus' => 'urn:oid:0.9.2342.19200300.100.1.45', 'urn:mace:dir:attribute-def:organizationalUnitName' => 'urn:oid:2.5.4.11', 'urn:mace:dir:attribute-def:otherMailbox' => 'urn:oid:0.9.2342.19200300.100.1.22', 'urn:mace:dir:attribute-def:ou' => 'urn:oid:2.5.4.11', 'urn:mace:dir:attribute-def:owner' => 'urn:oid:2.5.4.32', 'urn:mace:dir:attribute-def:pager' => 'urn:oid:0.9.2342.19200300.100.1.42', 'urn:mace:dir:attribute-def:pagerTelephoneNumber' => 'urn:oid:0.9.2342.19200300.100.1.42', 'urn:mace:dir:attribute-def:personalSignature' => 'urn:oid:0.9.2342.19200300.100.1.53', 'urn:mace:dir:attribute-def:personalTitle' => 'urn:oid:0.9.2342.19200300.100.1.40', 'urn:mace:dir:attribute-def:photo' => 'urn:oid:0.9.2342.19200300.100.1.7', 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName' => 'urn:oid:2.5.4.19', 'urn:mace:dir:attribute-def:pkcs9email' => 'urn:oid:1.2.840.113549.1.9.1', 'urn:mace:dir:attribute-def:postOfficeBox' => 'urn:oid:2.5.4.18', 'urn:mace:dir:attribute-def:postalAddress' => 'urn:oid:2.5.4.16', 'urn:mace:dir:attribute-def:postalCode' => 'urn:oid:2.5.4.17', 'urn:mace:dir:attribute-def:preferredDeliveryMethod' => 'urn:oid:2.5.4.28', 'urn:mace:dir:attribute-def:preferredLanguage' => 'urn:oid:2.16.840.1.113730.3.1.39', 'urn:mace:dir:attribute-def:presentationAddress' => 'urn:oid:2.5.4.29', 'urn:mace:dir:attribute-def:protocolInformation' => 'urn:oid:2.5.4.48', 'urn:mace:dir:attribute-def:pseudonym' => 'urn:oid:2.5.4.65', 'urn:mace:dir:attribute-def:registeredAddress' => 'urn:oid:2.5.4.26', 'urn:mace:dir:attribute-def:rfc822Mailbox' => 'urn:oid:0.9.2342.19200300.100.1.3', 'urn:mace:dir:attribute-def:roleOccupant' => 'urn:oid:2.5.4.33', 'urn:mace:dir:attribute-def:roomNumber' => 'urn:oid:0.9.2342.19200300.100.1.6', 'urn:mace:dir:attribute-def:sOARecord' => 'urn:oid:0.9.2342.19200300.100.1.30', 'urn:mace:dir:attribute-def:searchGuide' => 'urn:oid:2.5.4.14', 'urn:mace:dir:attribute-def:secretary' => 'urn:oid:0.9.2342.19200300.100.1.21', 'urn:mace:dir:attribute-def:seeAlso' => 'urn:oid:2.5.4.34', 'urn:mace:dir:attribute-def:serialNumber' => 'urn:oid:2.5.4.5', 'urn:mace:dir:attribute-def:singleLevelQuality' => 'urn:oid:0.9.2342.19200300.100.1.50', 'urn:mace:dir:attribute-def:sisSchoolGrade' => 'urn:oid:1.2.752.194.10.2.2', 'urn:mace:dir:attribute-def:sisLegalGuardianFor' => 'urn:oid:1.2.752.194.10.2.1', 'urn:mace:dir:attribute-def:sisOrgDepartment' => 'urn:oid:1.2.752.194.10.3', 'urn:mace:dir:attribute-def:sisSchoolUnitCode' => 'urn:oid:1.2.752.194.10.2.4', 'urn:mace:dir:attribute-def:sn' => 'urn:oid:2.5.4.4', 'urn:mace:dir:attribute-def:st' => 'urn:oid:2.5.4.8', 'urn:mace:dir:attribute-def:stateOrProvinceName' => 'urn:oid:2.5.4.8', 'urn:mace:dir:attribute-def:street' => 'urn:oid:2.5.4.9', 'urn:mace:dir:attribute-def:streetAddress' => 'urn:oid:2.5.4.9', 'urn:mace:dir:attribute-def:subtreeMaximumQuality' => 'urn:oid:0.9.2342.19200300.100.1.52', 'urn:mace:dir:attribute-def:subtreeMinimumQuality' => 'urn:oid:0.9.2342.19200300.100.1.51', 'urn:mace:dir:attribute-def:supportedAlgorithms' => 'urn:oid:2.5.4.52', 'urn:mace:dir:attribute-def:supportedApplicationContext' => 'urn:oid:2.5.4.30', 'urn:mace:dir:attribute-def:surname' => 'urn:oid:2.5.4.4', 'urn:mace:dir:attribute-def:telephoneNumber' => 'urn:oid:2.5.4.20', 'urn:mace:dir:attribute-def:teletexTerminalIdentifier' => 'urn:oid:2.5.4.22', 'urn:mace:dir:attribute-def:telexNumber' => 'urn:oid:2.5.4.21', 'urn:mace:dir:attribute-def:textEncodedORAddress' => 'urn:oid:0.9.2342.19200300.100.1.2', 'urn:mace:dir:attribute-def:title' => 'urn:oid:2.5.4.12', 'urn:mace:dir:attribute-def:uid' => 'urn:oid:0.9.2342.19200300.100.1.1', 'urn:mace:dir:attribute-def:uniqueIdentifier' => 'urn:oid:0.9.2342.19200300.100.1.44', 'urn:mace:dir:attribute-def:uniqueMember' => 'urn:oid:2.5.4.50', 'urn:mace:dir:attribute-def:userCertificate' => 'urn:oid:2.5.4.36', 'urn:mace:dir:attribute-def:userClass' => 'urn:oid:0.9.2342.19200300.100.1.8', 'urn:mace:dir:attribute-def:userPKCS12' => 'urn:oid:2.16.840.1.113730.3.1.216', 'urn:mace:dir:attribute-def:userPassword' => 'urn:oid:2.5.4.35', 'urn:mace:dir:attribute-def:userSMIMECertificate' => 'urn:oid:2.16.840.1.113730.3.1.40', 'urn:mace:dir:attribute-def:userid' => 'urn:oid:0.9.2342.19200300.100.1.1', 'urn:mace:dir:attribute-def:x121Address' => 'urn:oid:2.5.4.24', 'urn:mace:dir:attribute-def:x500UniqueIdentifier' => 'urn:oid:2.5.4.45', 'urn:mace:terena.org:attribute-def:schacCountryOfCitizenship' => 'urn:oid:1.3.6.1.4.1.25178.1.2.5', 'urn:mace:terena.org:attribute-def:schacCountryOfResidence' => 'urn:oid:1.3.6.1.4.1.25178.1.2.11', 'urn:mace:terena.org:attribute-def:schacDateOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.2.3', 'urn:mace:terena.org:attribute-def:schacExpiryDate' => 'urn:oid:1.3.6.1.4.1.25178.1.2.17', 'urn:mace:terena.org:attribute-def:schacGender' => 'urn:oid:1.3.6.1.4.1.25178.1.2.2', 'urn:mace:terena.org:attribute-def:schacHomeOrganization' => 'urn:oid:1.3.6.1.4.1.25178.1.2.9', 'urn:mace:terena.org:attribute-def:schacHomeOrganizationType' => 'urn:oid:1.3.6.1.4.1.25178.1.2.10', 'urn:mace:terena.org:attribute-def:schacMotherTongue' => 'urn:oid:1.3.6.1.4.1.25178.1.2.1', 'urn:mace:terena.org:attribute-def:schacPersonalPosition' => 'urn:oid:1.3.6.1.4.1.25178.1.2.13', 'urn:mace:terena.org:attribute-def:schacPersonalTitle' => 'urn:oid:1.3.6.1.4.1.25178.1.2.8', 'urn:mace:terena.org:attribute-def:schacPersonalUniqueCode' => 'urn:oid:1.3.6.1.4.1.25178.1.2.14', 'urn:mace:terena.org:attribute-def:schacPersonalUniqueID' => 'urn:oid:1.3.6.1.4.1.25178.1.2.15', 'urn:mace:terena.org:attribute-def:schacPlaceOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.2.4', 'urn:mace:terena.org:attribute-def:schacProjectMembership' => 'urn:oid:1.3.6.1.4.1.25178.1.2.20', 'urn:mace:terena.org:attribute-def:schacProjectSpecificRole' => 'urn:oid:1.3.6.1.4.1.25178.1.2.21', 'urn:mace:terena.org:attribute-def:schacSn1' => 'urn:oid:1.3.6.1.4.1.25178.1.2.6', 'urn:mace:terena.org:attribute-def:schacSn2' => 'urn:oid:1.3.6.1.4.1.25178.1.2.7', 'urn:mace:terena.org:attribute-def:schacUserPresenceID' => 'urn:oid:1.3.6.1.4.1.25178.1.2.12', 'urn:mace:terena.org:attribute-def:schacUserPrivateAttribute' => 'urn:oid:1.3.6.1.4.1.25178.1.2.18', 'urn:mace:terena.org:attribute-def:schacUserStatus' => 'urn:oid:1.3.6.1.4.1.25178.1.2.19', 'urn:mace:terena.org:attribute-def:schacYearOfBirth' => 'urn:oid:1.3.6.1.4.1.25178.1.0.2.3', ]; simplesamlphp-1.19.1/attributemap/removeurnprefix.php0000644000000000000000000000247014042503475021640 0ustar rootroot 'sn', 'urn:mace:dir:attribute-def:telephoneNumber' => 'telephoneNumber', 'urn:mace:dir:attribute-def:facsimileTelephoneNumber' => 'facsimileTelephoneNumber', 'urn:mace:dir:attribute-def:postalAddress' => 'postalAddress', 'urn:mace:dir:attribute-def:givenName' => 'givenName', 'urn:mace:dir:attribute-def:homePhone' => 'homePhone', 'urn:mace:dir:attribute-def:homePostalAddress' => 'homePostalAddress', 'urn:mace:dir:attribute-def:mail' => 'mail', 'urn:mace:dir:attribute-def:mobile' => 'mobile', 'urn:mace:dir:attribute-def:preferredLanguage' => 'preferredLanguage', 'urn:mace:dir:attribute-def:eduPersonPrincipalName' => 'eduPersonPrincipalName', 'urn:mace:dir:attribute-def:eduPersonAffiliation' => 'eduPersonAffiliation', 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation' => 'eduPersonScopedAffiliation', 'urn:mace:dir:attribute-def:eduPersonEntitlement' => 'eduPersonEntitlement', 'urn:mace:dir:attribute-def:eduPersonOrgDN' => 'eduPersonOrgDN', 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN' => 'eduPersonOrgUnitDN', ]; simplesamlphp-1.19.1/attributemap/oid2urn.php0000644000000000000000000003515014042503475017763 0ustar rootroot 'urn:mace:dir:attribute-def:uid', 'urn:oid:0.9.2342.19200300.100.1.10' => 'urn:mace:dir:attribute-def:manager', 'urn:oid:0.9.2342.19200300.100.1.11' => 'urn:mace:dir:attribute-def:documentIdentifier', 'urn:oid:0.9.2342.19200300.100.1.12' => 'urn:mace:dir:attribute-def:documentTitle', 'urn:oid:0.9.2342.19200300.100.1.13' => 'urn:mace:dir:attribute-def:documentVersion', 'urn:oid:0.9.2342.19200300.100.1.14' => 'urn:mace:dir:attribute-def:documentAuthor', 'urn:oid:0.9.2342.19200300.100.1.15' => 'urn:mace:dir:attribute-def:documentLocation', 'urn:oid:0.9.2342.19200300.100.1.2' => 'urn:mace:dir:attribute-def:textEncodedORAddress', 'urn:oid:0.9.2342.19200300.100.1.20' => 'urn:mace:dir:attribute-def:homePhone', 'urn:oid:0.9.2342.19200300.100.1.21' => 'urn:mace:dir:attribute-def:secretary', 'urn:oid:0.9.2342.19200300.100.1.22' => 'urn:mace:dir:attribute-def:otherMailbox', 'urn:oid:0.9.2342.19200300.100.1.25' => 'urn:mace:dir:attribute-def:dc', 'urn:oid:0.9.2342.19200300.100.1.26' => 'urn:mace:dir:attribute-def:aRecord', 'urn:oid:0.9.2342.19200300.100.1.27' => 'urn:mace:dir:attribute-def:mDRecord', 'urn:oid:0.9.2342.19200300.100.1.28' => 'urn:mace:dir:attribute-def:mXRecord', 'urn:oid:0.9.2342.19200300.100.1.29' => 'urn:mace:dir:attribute-def:nSRecord', 'urn:oid:0.9.2342.19200300.100.1.3' => 'urn:mace:dir:attribute-def:mail', 'urn:oid:0.9.2342.19200300.100.1.30' => 'urn:mace:dir:attribute-def:sOARecord', 'urn:oid:0.9.2342.19200300.100.1.31' => 'urn:mace:dir:attribute-def:cNAMERecord', 'urn:oid:0.9.2342.19200300.100.1.37' => 'urn:mace:dir:attribute-def:associatedDomain', 'urn:oid:0.9.2342.19200300.100.1.38' => 'urn:mace:dir:attribute-def:associatedName', 'urn:oid:0.9.2342.19200300.100.1.39' => 'urn:mace:dir:attribute-def:homePostalAddress', 'urn:oid:0.9.2342.19200300.100.1.4' => 'urn:mace:dir:attribute-def:info', 'urn:oid:0.9.2342.19200300.100.1.40' => 'urn:mace:dir:attribute-def:personalTitle', 'urn:oid:0.9.2342.19200300.100.1.41' => 'urn:mace:dir:attribute-def:mobile', 'urn:oid:0.9.2342.19200300.100.1.42' => 'urn:mace:dir:attribute-def:pager', 'urn:oid:0.9.2342.19200300.100.1.43' => 'urn:mace:dir:attribute-def:co', 'urn:oid:0.9.2342.19200300.100.1.44' => 'urn:mace:dir:attribute-def:uniqueIdentifier', 'urn:oid:0.9.2342.19200300.100.1.45' => 'urn:mace:dir:attribute-def:organizationalStatus', 'urn:oid:0.9.2342.19200300.100.1.46' => 'urn:mace:dir:attribute-def:janetMailbox', 'urn:oid:0.9.2342.19200300.100.1.47' => 'urn:mace:dir:attribute-def:mailPreferenceOption', 'urn:oid:0.9.2342.19200300.100.1.48' => 'urn:mace:dir:attribute-def:buildingName', 'urn:oid:0.9.2342.19200300.100.1.49' => 'urn:mace:dir:attribute-def:dSAQuality', 'urn:oid:0.9.2342.19200300.100.1.5' => 'urn:mace:dir:attribute-def:drink', 'urn:oid:0.9.2342.19200300.100.1.50' => 'urn:mace:dir:attribute-def:singleLevelQuality', 'urn:oid:0.9.2342.19200300.100.1.51' => 'urn:mace:dir:attribute-def:subtreeMinimumQuality', 'urn:oid:0.9.2342.19200300.100.1.52' => 'urn:mace:dir:attribute-def:subtreeMaximumQuality', 'urn:oid:0.9.2342.19200300.100.1.53' => 'urn:mace:dir:attribute-def:personalSignature', 'urn:oid:0.9.2342.19200300.100.1.54' => 'urn:mace:dir:attribute-def:dITRedirect', 'urn:oid:0.9.2342.19200300.100.1.55' => 'urn:mace:dir:attribute-def:audio', 'urn:oid:0.9.2342.19200300.100.1.56' => 'urn:mace:dir:attribute-def:documentPublisher', 'urn:oid:0.9.2342.19200300.100.1.6' => 'urn:mace:dir:attribute-def:roomNumber', 'urn:oid:0.9.2342.19200300.100.1.60' => 'urn:mace:dir:attribute-def:jpegPhoto', 'urn:oid:0.9.2342.19200300.100.1.7' => 'urn:mace:dir:attribute-def:photo', 'urn:oid:0.9.2342.19200300.100.1.8' => 'urn:mace:dir:attribute-def:userClass', 'urn:oid:0.9.2342.19200300.100.1.9' => 'urn:mace:dir:attribute-def:host', 'urn:oid:1.2.840.113549.1.9.1' => 'urn:mace:dir:attribute-def:email', 'urn:oid:1.2.752.194.10.2.2' => 'urn:mace:dir:attribute-def:sisSchoolGrade', 'urn:oid:1.2.752.194.10.2.1' => 'urn:mace:dir:attribute-def:sisLegalGuardianFor', 'urn:oid:1.2.752.194.10.3' => 'urn:mace:dir:attribute-def:sisOrgDepartment', 'urn:oid:1.2.752.194.10.2.4' => 'urn:mace:dir:attribute-def:sisSchoolUnitCode', 'urn:oid:1.3.6.1.4.1.2428.90.1.1' => 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber', 'urn:oid:1.3.6.1.4.1.2428.90.1.11' => 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion', 'urn:oid:1.3.6.1.4.1.2428.90.1.12' => 'urn:mace:dir:attribute-def:norEduOrgNIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.2' => 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber', 'urn:oid:1.3.6.1.4.1.2428.90.1.3' => 'urn:mace:dir:attribute-def:norEduPersonBirthDate', 'urn:oid:1.3.6.1.4.1.2428.90.1.4' => 'urn:mace:dir:attribute-def:norEduPersonLIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.5' => 'urn:mace:dir:attribute-def:norEduPersonNIN', 'urn:oid:1.3.6.1.4.1.2428.90.1.6' => 'urn:mace:dir:attribute-def:norEduOrgAcronym', 'urn:oid:1.3.6.1.4.1.2428.90.1.7' => 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier', 'urn:oid:1.3.6.1.4.1.2428.90.1.8' => 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier', 'urn:oid:1.3.6.1.4.1.2428.90.1.9' => 'urn:mace:dir:attribute-def:federationFeideSchemaVersion', 'urn:oid:1.3.6.1.4.1.250.1.57' => 'urn:mace:dir:attribute-def:labeledURI', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1' => 'urn:mace:dir:attribute-def:eduPersonAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.11' => 'urn:mace:dir:attribute-def:eduPersonAssurance', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10' => 'urn:mace:dir:attribute-def:eduPersonTargetedID', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.13' => 'urn:mace:dir:attribute-def:eduPersonUniqueId', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.2' => 'urn:mace:dir:attribute-def:eduPersonNickname', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.3' => 'urn:mace:dir:attribute-def:eduPersonOrgDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.4' => 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.5' => 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6' => 'urn:mace:dir:attribute-def:eduPersonPrincipalName', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.7' => 'urn:mace:dir:attribute-def:eduPersonEntitlement', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.8' => 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.9' => 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.2' => 'urn:mace:dir:attribute-def:eduOrgHomePageURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.3' => 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.4' => 'urn:mace:dir:attribute-def:eduOrgLegalName', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.5' => 'urn:mace:dir:attribute-def:eduOrgSuperiorURI', 'urn:oid:1.3.6.1.4.1.5923.1.2.1.6' => 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI', 'urn:oid:1.3.6.1.4.1.25178.1.0.2.3' => 'urn:mace:terena.org:attribute-def:schacYearOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.1' => 'urn:mace:terena.org:attribute-def:schacMotherTongue', 'urn:oid:1.3.6.1.4.1.25178.1.2.2' => 'urn:mace:terena.org:attribute-def:schacGender', 'urn:oid:1.3.6.1.4.1.25178.1.2.3' => 'urn:mace:terena.org:attribute-def:schacDateOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.4' => 'urn:mace:terena.org:attribute-def:schacPlaceOfBirth', 'urn:oid:1.3.6.1.4.1.25178.1.2.5' => 'urn:mace:terena.org:attribute-def:schacCountryOfCitizenship', 'urn:oid:1.3.6.1.4.1.25178.1.2.6' => 'urn:mace:terena.org:attribute-def:schacSn1', 'urn:oid:1.3.6.1.4.1.25178.1.2.7' => 'urn:mace:terena.org:attribute-def:schacSn2', 'urn:oid:1.3.6.1.4.1.25178.1.2.8' => 'urn:mace:terena.org:attribute-def:schacPersonalTitle', 'urn:oid:1.3.6.1.4.1.25178.1.2.9' => 'urn:mace:terena.org:attribute-def:schacHomeOrganization', 'urn:oid:1.3.6.1.4.1.25178.1.2.10' => 'urn:mace:terena.org:attribute-def:schacHomeOrganizationType', 'urn:oid:1.3.6.1.4.1.25178.1.2.11' => 'urn:mace:terena.org:attribute-def:schacCountryOfResidence', 'urn:oid:1.3.6.1.4.1.25178.1.2.12' => 'urn:mace:terena.org:attribute-def:schacUserPresenceID', 'urn:oid:1.3.6.1.4.1.25178.1.2.13' => 'urn:mace:terena.org:attribute-def:schacPersonalPosition', 'urn:oid:1.3.6.1.4.1.25178.1.2.14' => 'urn:mace:terena.org:attribute-def:schacPersonalUniqueCode', 'urn:oid:1.3.6.1.4.1.25178.1.2.15' => 'urn:mace:terena.org:attribute-def:schacPersonalUniqueID', 'urn:oid:1.3.6.1.4.1.25178.1.2.17' => 'urn:mace:terena.org:attribute-def:schacExpiryDate', 'urn:oid:1.3.6.1.4.1.25178.1.2.18' => 'urn:mace:terena.org:attribute-def:schacUserPrivateAttribute', 'urn:oid:1.3.6.1.4.1.25178.1.2.19' => 'urn:mace:terena.org:attribute-def:schacUserStatus', 'urn:oid:1.3.6.1.4.1.25178.1.2.20' => 'urn:mace:terena.org:attribute-def:schacProjectMembership', 'urn:oid:1.3.6.1.4.1.25178.1.2.21' => 'urn:mace:terena.org:attribute-def:schacProjectSpecificRole', 'urn:oid:2.16.840.1.113730.3.1.1' => 'urn:mace:dir:attribute-def:carLicense', 'urn:oid:2.16.840.1.113730.3.1.2' => 'urn:mace:dir:attribute-def:departmentNumber', 'urn:oid:2.16.840.1.113730.3.1.216' => 'urn:mace:dir:attribute-def:userPKCS12', 'urn:oid:2.16.840.1.113730.3.1.241' => 'urn:mace:dir:attribute-def:displayName', 'urn:oid:2.16.840.1.113730.3.1.3' => 'urn:mace:dir:attribute-def:employeeNumber', 'urn:oid:2.16.840.1.113730.3.1.39' => 'urn:mace:dir:attribute-def:preferredLanguage', 'urn:oid:2.16.840.1.113730.3.1.4' => 'urn:mace:dir:attribute-def:employeeType', 'urn:oid:2.16.840.1.113730.3.1.40' => 'urn:mace:dir:attribute-def:userSMIMECertificate', 'urn:oid:2.5.4.0' => 'urn:mace:dir:attribute-def:objectClass', 'urn:oid:2.5.4.1' => 'urn:mace:dir:attribute-def:aliasedObjectName', 'urn:oid:2.5.4.10' => 'urn:mace:dir:attribute-def:o', 'urn:oid:2.5.4.11' => 'urn:mace:dir:attribute-def:ou', 'urn:oid:2.5.4.12' => 'urn:mace:dir:attribute-def:title', 'urn:oid:2.5.4.13' => 'urn:mace:dir:attribute-def:description', 'urn:oid:2.5.4.14' => 'urn:mace:dir:attribute-def:searchGuide', 'urn:oid:2.5.4.15' => 'urn:mace:dir:attribute-def:businessCategory', 'urn:oid:2.5.4.16' => 'urn:mace:dir:attribute-def:postalAddress', 'urn:oid:2.5.4.17' => 'urn:mace:dir:attribute-def:postalCode', 'urn:oid:2.5.4.18' => 'urn:mace:dir:attribute-def:postOfficeBox', 'urn:oid:2.5.4.19' => 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName', 'urn:oid:2.5.4.2' => 'urn:mace:dir:attribute-def:knowledgeInformation', 'urn:oid:2.5.4.20' => 'urn:mace:dir:attribute-def:telephoneNumber', 'urn:oid:2.5.4.21' => 'urn:mace:dir:attribute-def:telexNumber', 'urn:oid:2.5.4.22' => 'urn:mace:dir:attribute-def:teletexTerminalIdentifier', 'urn:oid:2.5.4.23' => 'urn:mace:dir:attribute-def:facsimileTelephoneNumber', 'urn:oid:2.5.4.24' => 'urn:mace:dir:attribute-def:x121Address', 'urn:oid:2.5.4.25' => 'urn:mace:dir:attribute-def:internationaliSDNNumber', 'urn:oid:2.5.4.26' => 'urn:mace:dir:attribute-def:registeredAddress', 'urn:oid:2.5.4.27' => 'urn:mace:dir:attribute-def:destinationIndicator', 'urn:oid:2.5.4.28' => 'urn:mace:dir:attribute-def:preferredDeliveryMethod', 'urn:oid:2.5.4.29' => 'urn:mace:dir:attribute-def:presentationAddress', 'urn:oid:2.5.4.3' => 'urn:mace:dir:attribute-def:cn', 'urn:oid:2.5.4.30' => 'urn:mace:dir:attribute-def:supportedApplicationContext', 'urn:oid:2.5.4.31' => 'urn:mace:dir:attribute-def:member', 'urn:oid:2.5.4.32' => 'urn:mace:dir:attribute-def:owner', 'urn:oid:2.5.4.33' => 'urn:mace:dir:attribute-def:roleOccupant', 'urn:oid:2.5.4.34' => 'urn:mace:dir:attribute-def:seeAlso', 'urn:oid:2.5.4.35' => 'urn:mace:dir:attribute-def:userPassword', 'urn:oid:2.5.4.36' => 'urn:mace:dir:attribute-def:userCertificate', 'urn:oid:2.5.4.37' => 'urn:mace:dir:attribute-def:cACertificate', 'urn:oid:2.5.4.38' => 'urn:mace:dir:attribute-def:authorityRevocationList', 'urn:oid:2.5.4.39' => 'urn:mace:dir:attribute-def:certificateRevocationList', 'urn:oid:2.5.4.4' => 'urn:mace:dir:attribute-def:sn', 'urn:oid:2.5.4.40' => 'urn:mace:dir:attribute-def:crossCertificatePair', 'urn:oid:2.5.4.41' => 'urn:mace:dir:attribute-def:name', 'urn:oid:2.5.4.42' => 'urn:mace:dir:attribute-def:givenName', 'urn:oid:2.5.4.43' => 'urn:mace:dir:attribute-def:initials', 'urn:oid:2.5.4.44' => 'urn:mace:dir:attribute-def:generationQualifier', 'urn:oid:2.5.4.45' => 'urn:mace:dir:attribute-def:x500UniqueIdentifier', 'urn:oid:2.5.4.46' => 'urn:mace:dir:attribute-def:dnQualifier', 'urn:oid:2.5.4.47' => 'urn:mace:dir:attribute-def:enhancedSearchGuide', 'urn:oid:2.5.4.48' => 'urn:mace:dir:attribute-def:protocolInformation', 'urn:oid:2.5.4.49' => 'urn:mace:dir:attribute-def:distinguishedName', 'urn:oid:2.5.4.5' => 'urn:mace:dir:attribute-def:serialNumber', 'urn:oid:2.5.4.50' => 'urn:mace:dir:attribute-def:uniqueMember', 'urn:oid:2.5.4.51' => 'urn:mace:dir:attribute-def:houseIdentifier', 'urn:oid:2.5.4.52' => 'urn:mace:dir:attribute-def:supportedAlgorithms', 'urn:oid:2.5.4.53' => 'urn:mace:dir:attribute-def:deltaRevocationList', 'urn:oid:2.5.4.54' => 'urn:mace:dir:attribute-def:dmdName', 'urn:oid:2.5.4.6' => 'urn:mace:dir:attribute-def:c', 'urn:oid:2.5.4.65' => 'urn:mace:dir:attribute-def:pseudonym', 'urn:oid:2.5.4.7' => 'urn:mace:dir:attribute-def:l', 'urn:oid:2.5.4.8' => 'urn:mace:dir:attribute-def:st', 'urn:oid:2.5.4.9' => 'urn:mace:dir:attribute-def:street', ]; simplesamlphp-1.19.1/attributemap/test.php0000644000000000000000000000012014042503475017345 0ustar rootroot 'urn:mace:dir:attribute-def:mobile' ]; simplesamlphp-1.19.1/attributemap/facebook2name.php0000644000000000000000000000132414042503475021071 0ustar rootroot 'eduPersonPrincipalName', // username OR uid @ facebook.com 'facebook_targetedID' => 'eduPersonTargetedID', // http://facebook.com!uid 'facebook_cn' => 'cn', // duplicate of displayName // Attributes Returned by Facebook 'facebook.first_name' => 'givenName', 'facebook.last_name' => 'sn', 'facebook.name' => 'displayName', // or 'cn' 'facebook.email' => 'mail', 'facebook.username' => 'uid', // facebook username (maybe blank) 'facebook.profile_url' => 'labeledURI', 'facebook.locale' => 'preferredLanguage', 'facebook.about_me' => 'description', ]; simplesamlphp-1.19.1/attributemap/addurnprefix.php0000644000000000000000000000247014042503475021073 0ustar rootroot 'urn:mace:dir:attribute-def:sn', 'telephoneNumber' => 'urn:mace:dir:attribute-def:telephoneNumber', 'facsimileTelephoneNumber' => 'urn:mace:dir:attribute-def:facsimileTelephoneNumber', 'postalAddress' => 'urn:mace:dir:attribute-def:postalAddress', 'givenName' => 'urn:mace:dir:attribute-def:givenName', 'homePhone' => 'urn:mace:dir:attribute-def:homePhone', 'homePostalAddress' => 'urn:mace:dir:attribute-def:homePostalAddress', 'mail' => 'urn:mace:dir:attribute-def:mail', 'mobile' => 'urn:mace:dir:attribute-def:mobile', 'preferredLanguage' => 'urn:mace:dir:attribute-def:preferredLanguage', 'eduPersonPrincipalName' => 'urn:mace:dir:attribute-def:eduPersonPrincipalName', 'eduPersonAffiliation' => 'urn:mace:dir:attribute-def:eduPersonAffiliation', 'eduPersonScopedAffiliation' => 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation', 'eduPersonEntitlement' => 'urn:mace:dir:attribute-def:eduPersonEntitlement', 'eduPersonOrgDN' => 'urn:mace:dir:attribute-def:eduPersonOrgDN', 'eduPersonOrgUnitDN' => 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN', ]; simplesamlphp-1.19.1/attributemap/urn2name.php0000644000000000000000000003761714042503475020142 0ustar rootroot 'aRecord', 'urn:mace:dir:attribute-def:aliasedEntryName' => 'aliasedEntryName', 'urn:mace:dir:attribute-def:aliasedObjectName' => 'aliasedObjectName', 'urn:mace:dir:attribute-def:associatedDomain' => 'associatedDomain', 'urn:mace:dir:attribute-def:associatedName' => 'associatedName', 'urn:mace:dir:attribute-def:audio' => 'audio', 'urn:mace:dir:attribute-def:authorityRevocationList' => 'authorityRevocationList', 'urn:mace:dir:attribute-def:buildingName' => 'buildingName', 'urn:mace:dir:attribute-def:businessCategory' => 'businessCategory', 'urn:mace:dir:attribute-def:c' => 'c', 'urn:mace:dir:attribute-def:cACertificate' => 'cACertificate', 'urn:mace:dir:attribute-def:cNAMERecord' => 'cNAMERecord', 'urn:mace:dir:attribute-def:carLicense' => 'carLicense', 'urn:mace:dir:attribute-def:certificateRevocationList' => 'certificateRevocationList', 'urn:mace:dir:attribute-def:cn' => 'cn', 'urn:mace:dir:attribute-def:co' => 'co', 'urn:mace:dir:attribute-def:commonName' => 'commonName', 'urn:mace:dir:attribute-def:countryName' => 'countryName', 'urn:mace:dir:attribute-def:crossCertificatePair' => 'crossCertificatePair', 'urn:mace:dir:attribute-def:dITRedirect' => 'dITRedirect', 'urn:mace:dir:attribute-def:dSAQuality' => 'dSAQuality', 'urn:mace:dir:attribute-def:dc' => 'dc', 'urn:mace:dir:attribute-def:deltaRevocationList' => 'deltaRevocationList', 'urn:mace:dir:attribute-def:departmentNumber' => 'departmentNumber', 'urn:mace:dir:attribute-def:description' => 'description', 'urn:mace:dir:attribute-def:destinationIndicator' => 'destinationIndicator', 'urn:mace:dir:attribute-def:displayName' => 'displayName', 'urn:mace:dir:attribute-def:distinguishedName' => 'distinguishedName', 'urn:mace:dir:attribute-def:dmdName' => 'dmdName', 'urn:mace:dir:attribute-def:dnQualifier' => 'dnQualifier', 'urn:mace:dir:attribute-def:documentAuthor' => 'documentAuthor', 'urn:mace:dir:attribute-def:documentIdentifier' => 'documentIdentifier', 'urn:mace:dir:attribute-def:documentLocation' => 'documentLocation', 'urn:mace:dir:attribute-def:documentPublisher' => 'documentPublisher', 'urn:mace:dir:attribute-def:documentTitle' => 'documentTitle', 'urn:mace:dir:attribute-def:documentVersion' => 'documentVersion', 'urn:mace:dir:attribute-def:domainComponent' => 'domainComponent', 'urn:mace:dir:attribute-def:drink' => 'drink', 'urn:mace:dir:attribute-def:eduOrgHomePageURI' => 'eduOrgHomePageURI', 'urn:mace:dir:attribute-def:eduOrgIdentityAuthNPolicyURI' => 'eduOrgIdentityAuthNPolicyURI', 'urn:mace:dir:attribute-def:eduOrgLegalName' => 'eduOrgLegalName', 'urn:mace:dir:attribute-def:eduOrgSuperiorURI' => 'eduOrgSuperiorURI', 'urn:mace:dir:attribute-def:eduOrgWhitePagesURI' => 'eduOrgWhitePagesURI', 'urn:mace:dir:attribute-def:eduPersonAffiliation' => 'eduPersonAffiliation', 'urn:mace:dir:attribute-def:eduPersonAssurance' => 'eduPersonAssurance', 'urn:mace:dir:attribute-def:eduPersonEntitlement' => 'eduPersonEntitlement', 'urn:mace:dir:attribute-def:eduPersonNickname' => 'eduPersonNickname', 'urn:mace:dir:attribute-def:eduPersonOrgDN' => 'eduPersonOrgDN', 'urn:mace:dir:attribute-def:eduPersonOrgUnitDN' => 'eduPersonOrgUnitDN', 'urn:mace:dir:attribute-def:eduPersonPrimaryAffiliation' => 'eduPersonPrimaryAffiliation', 'urn:mace:dir:attribute-def:eduPersonPrimaryOrgUnitDN' => 'eduPersonPrimaryOrgUnitDN', 'urn:mace:dir:attribute-def:eduPersonPrincipalName' => 'eduPersonPrincipalName', 'urn:mace:dir:attribute-def:eduPersonScopedAffiliation' => 'eduPersonScopedAffiliation', 'urn:mace:dir:attribute-def:eduPersonTargetedID' => 'eduPersonTargetedID', 'urn:mace:dir:attribute-def:eduPersonUniqueId' => 'eduPersonUniqueId', 'urn:mace:dir:attribute-def:email' => 'email', 'urn:mace:dir:attribute-def:emailAddress' => 'emailAddress', 'urn:mace:dir:attribute-def:employeeNumber' => 'employeeNumber', 'urn:mace:dir:attribute-def:employeeType' => 'employeeType', 'urn:mace:dir:attribute-def:enhancedSearchGuide' => 'enhancedSearchGuide', 'urn:mace:dir:attribute-def:facsimileTelephoneNumber' => 'facsimileTelephoneNumber', 'urn:mace:dir:attribute-def:favouriteDrink' => 'favouriteDrink', 'urn:mace:dir:attribute-def:fax' => 'fax', 'urn:mace:dir:attribute-def:federationFeideSchemaVersion' => 'federationFeideSchemaVersion', 'urn:mace:dir:attribute-def:friendlyCountryName' => 'friendlyCountryName', 'urn:mace:dir:attribute-def:generationQualifier' => 'generationQualifier', 'urn:mace:dir:attribute-def:givenName' => 'givenName', 'urn:mace:dir:attribute-def:gn' => 'gn', 'urn:mace:dir:attribute-def:homePhone' => 'homePhone', 'urn:mace:dir:attribute-def:homePostalAddress' => 'homePostalAddress', 'urn:mace:dir:attribute-def:homeTelephoneNumber' => 'homeTelephoneNumber', 'urn:mace:dir:attribute-def:host' => 'host', 'urn:mace:dir:attribute-def:houseIdentifier' => 'houseIdentifier', 'urn:mace:dir:attribute-def:info' => 'info', 'urn:mace:dir:attribute-def:initials' => 'initials', 'urn:mace:dir:attribute-def:internationaliSDNNumber' => 'internationaliSDNNumber', 'urn:mace:dir:attribute-def:janetMailbox' => 'janetMailbox', 'urn:mace:dir:attribute-def:jpegPhoto' => 'jpegPhoto', 'urn:mace:dir:attribute-def:knowledgeInformation' => 'knowledgeInformation', 'urn:mace:dir:attribute-def:l' => 'l', 'urn:mace:dir:attribute-def:labeledURI' => 'labeledURI', 'urn:mace:dir:attribute-def:localityName' => 'localityName', 'urn:mace:dir:attribute-def:mDRecord' => 'mDRecord', 'urn:mace:dir:attribute-def:mXRecord' => 'mXRecord', 'urn:mace:dir:attribute-def:mail' => 'mail', 'urn:mace:dir:attribute-def:mailPreferenceOption' => 'mailPreferenceOption', 'urn:mace:dir:attribute-def:manager' => 'manager', 'urn:mace:dir:attribute-def:member' => 'member', 'urn:mace:dir:attribute-def:mobile' => 'mobile', 'urn:mace:dir:attribute-def:mobileTelephoneNumber' => 'mobileTelephoneNumber', 'urn:mace:dir:attribute-def:nSRecord' => 'nSRecord', 'urn:mace:dir:attribute-def:name' => 'name', 'urn:mace:dir:attribute-def:norEduOrgAcronym' => 'norEduOrgAcronym', 'urn:mace:dir:attribute-def:norEduOrgNIN' => 'norEduOrgNIN', 'urn:mace:dir:attribute-def:norEduOrgSchemaVersion' => 'norEduOrgSchemaVersion', 'urn:mace:dir:attribute-def:norEduOrgUniqueIdentifier' => 'norEduOrgUniqueIdentifier', 'urn:mace:dir:attribute-def:norEduOrgUniqueNumber' => 'norEduOrgUniqueNumber', 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueIdentifier' => 'norEduOrgUnitUniqueIdentifier', 'urn:mace:dir:attribute-def:norEduOrgUnitUniqueNumber' => 'norEduOrgUnitUniqueNumber', 'urn:mace:dir:attribute-def:norEduPersonBirthDate' => 'norEduPersonBirthDate', 'urn:mace:dir:attribute-def:norEduPersonLIN' => 'norEduPersonLIN', 'urn:mace:dir:attribute-def:norEduPersonNIN' => 'norEduPersonNIN', 'urn:mace:dir:attribute-def:o' => 'o', 'urn:mace:dir:attribute-def:objectClass' => 'objectClass', 'urn:mace:dir:attribute-def:organizationName' => 'organizationName', 'urn:mace:dir:attribute-def:organizationalStatus' => 'organizationalStatus', 'urn:mace:dir:attribute-def:organizationalUnitName' => 'organizationalUnitName', 'urn:mace:dir:attribute-def:otherMailbox' => 'otherMailbox', 'urn:mace:dir:attribute-def:ou' => 'ou', 'urn:mace:dir:attribute-def:owner' => 'owner', 'urn:mace:dir:attribute-def:pager' => 'pager', 'urn:mace:dir:attribute-def:pagerTelephoneNumber' => 'pagerTelephoneNumber', 'urn:mace:dir:attribute-def:personalSignature' => 'personalSignature', 'urn:mace:dir:attribute-def:personalTitle' => 'personalTitle', 'urn:mace:dir:attribute-def:photo' => 'photo', 'urn:mace:dir:attribute-def:physicalDeliveryOfficeName' => 'physicalDeliveryOfficeName', 'urn:mace:dir:attribute-def:pkcs9email' => 'pkcs9email', 'urn:mace:dir:attribute-def:postOfficeBox' => 'postOfficeBox', 'urn:mace:dir:attribute-def:postalAddress' => 'postalAddress', 'urn:mace:dir:attribute-def:postalCode' => 'postalCode', 'urn:mace:dir:attribute-def:preferredDeliveryMethod' => 'preferredDeliveryMethod', 'urn:mace:dir:attribute-def:preferredLanguage' => 'preferredLanguage', 'urn:mace:dir:attribute-def:presentationAddress' => 'presentationAddress', 'urn:mace:dir:attribute-def:protocolInformation' => 'protocolInformation', 'urn:mace:dir:attribute-def:pseudonym' => 'pseudonym', 'urn:mace:dir:attribute-def:registeredAddress' => 'registeredAddress', 'urn:mace:dir:attribute-def:rfc822Mailbox' => 'rfc822Mailbox', 'urn:mace:dir:attribute-def:roleOccupant' => 'roleOccupant', 'urn:mace:dir:attribute-def:roomNumber' => 'roomNumber', 'urn:mace:dir:attribute-def:sOARecord' => 'sOARecord', 'urn:mace:dir:attribute-def:schacGender' => 'schacGender', 'urn:mace:dir:attribute-def:searchGuide' => 'searchGuide', 'urn:mace:dir:attribute-def:secretary' => 'secretary', 'urn:mace:dir:attribute-def:seeAlso' => 'seeAlso', 'urn:mace:dir:attribute-def:serialNumber' => 'serialNumber', 'urn:mace:dir:attribute-def:singleLevelQuality' => 'singleLevelQuality', 'urn:mace:dir:attribute-def:sisSchoolGrade' => 'sisSchoolGrade', 'urn:mace:dir:attribute-def:sisLegalGuardianFor' => 'sisLegalGuardianFor', 'urn:mace:dir:attribute-def:sn' => 'sn', 'urn:mace:dir:attribute-def:st' => 'st', 'urn:mace:dir:attribute-def:stateOrProvinceName' => 'stateOrProvinceName', 'urn:mace:dir:attribute-def:street' => 'street', 'urn:mace:dir:attribute-def:streetAddress' => 'streetAddress', 'urn:mace:dir:attribute-def:subtreeMaximumQuality' => 'subtreeMaximumQuality', 'urn:mace:dir:attribute-def:subtreeMinimumQuality' => 'subtreeMinimumQuality', 'urn:mace:dir:attribute-def:supportedAlgorithms' => 'supportedAlgorithms', 'urn:mace:dir:attribute-def:supportedApplicationContext' => 'supportedApplicationContext', 'urn:mace:dir:attribute-def:surname' => 'surname', 'urn:mace:dir:attribute-def:telephoneNumber' => 'telephoneNumber', 'urn:mace:dir:attribute-def:teletexTerminalIdentifier' => 'teletexTerminalIdentifier', 'urn:mace:dir:attribute-def:telexNumber' => 'telexNumber', 'urn:mace:dir:attribute-def:textEncodedORAddress' => 'textEncodedORAddress', 'urn:mace:dir:attribute-def:title' => 'title', 'urn:mace:dir:attribute-def:uid' => 'uid', 'urn:mace:dir:attribute-def:uniqueIdentifier' => 'uniqueIdentifier', 'urn:mace:dir:attribute-def:uniqueMember' => 'uniqueMember', 'urn:mace:dir:attribute-def:userCertificate' => 'userCertificate', 'urn:mace:dir:attribute-def:userClass' => 'userClass', 'urn:mace:dir:attribute-def:userPKCS12' => 'userPKCS12', 'urn:mace:dir:attribute-def:userPassword' => 'userPassword', 'urn:mace:dir:attribute-def:userSMIMECertificate' => 'userSMIMECertificate', 'urn:mace:dir:attribute-def:userid' => 'userid', 'urn:mace:dir:attribute-def:x121Address' => 'x121Address', 'urn:mace:dir:attribute-def:x500UniqueIdentifier' => 'x500UniqueIdentifier', 'urn:mace:terena.org:attribute-def:schacCountryOfCitizenship' => 'schacCountryOfCitizenship', 'urn:mace:terena.org:attribute-def:schacCountryOfResidence' => 'schacCountryOfResidence', 'urn:mace:terena.org:attribute-def:schacDateOfBirth' => 'schacDateOfBirth', 'urn:mace:terena.org:attribute-def:schacExpiryDate' => 'schacExpiryDate', 'urn:mace:terena.org:attribute-def:schacGender' => 'schacGender', 'urn:mace:terena.org:attribute-def:schacHomeOrganization' => 'schacHomeOrganization', 'urn:mace:terena.org:attribute-def:schacHomeOrganizationType' => 'schacHomeOrganizationType', 'urn:mace:terena.org:attribute-def:schacMotherTongue' => 'schacMotherTongue', 'urn:mace:terena.org:attribute-def:schacPersonalPosition' => 'schacPersonalPosition', 'urn:mace:terena.org:attribute-def:schacPersonalTitle' => 'schacPersonalTitle', 'urn:mace:terena.org:attribute-def:schacPersonalUniqueCode' => 'schacPersonalUniqueCode', 'urn:mace:terena.org:attribute-def:schacPersonalUniqueID' => 'schacPersonalUniqueID', 'urn:mace:terena.org:attribute-def:schacPlaceOfBirth' => 'schacPlaceOfBirth', 'urn:mace:terena.org:attribute-def:schacProjectMembership' => 'schacProjectMembership', 'urn:mace:terena.org:attribute-def:schacProjectSpecificRole' => 'schacProjectSpecificRole', 'urn:mace:terena.org:attribute-def:schacSn1' => 'schacSn1', 'urn:mace:terena.org:attribute-def:schacSn2' => 'schacSn2', 'urn:mace:terena.org:attribute-def:schacUserPresenceID' => 'schacUserPresenceID', 'urn:mace:terena.org:attribute-def:schacUserPrivateAttribute' => 'schacUserPrivateAttribute', 'urn:mace:terena.org:attribute-def:schacUserStatus' => 'schacUserStatus', 'urn:oasis:names:tc:SAML:attribute:pairwise-id' => 'pairwise-id', 'urn:oasis:names:tc:SAML:attribute:subject-id' => 'subject-id', ]; simplesamlphp-1.19.1/attributemap/newSchacNS.php0000644000000000000000000000365114042503475020376 0ustar rootroot SCHAC_NEW_NS.'schacCountryOfCitizenship', SCHAC_OLD_NS.'schacCountryOfResidence' => SCHAC_NEW_NS.'schacCountryOfResidence', SCHAC_OLD_NS.'schacDateOfBirth' => SCHAC_NEW_NS.'schacDateOfBirth', SCHAC_OLD_NS.'schacExpiryDate' => SCHAC_NEW_NS.'schacExpiryDate', SCHAC_OLD_NS.'schacGender' => SCHAC_NEW_NS.'schacGender', SCHAC_OLD_NS.'schacHomeOrganization' => SCHAC_NEW_NS.'schacHomeOrganization', SCHAC_OLD_NS.'schacHomeOrganizationType' => SCHAC_NEW_NS.'schacHomeOrganizationType', SCHAC_OLD_NS.'schacMotherTongue' => SCHAC_NEW_NS.'schacMotherTongue', SCHAC_OLD_NS.'schacPersonalPosition' => SCHAC_NEW_NS.'schacPersonalPosition', SCHAC_OLD_NS.'schacPersonalTitle' => SCHAC_NEW_NS.'schacPersonalTitle', SCHAC_OLD_NS.'schacPersonalUniqueCode' => SCHAC_NEW_NS.'schacPersonalUniqueCode', SCHAC_OLD_NS.'schacPersonalUniqueID' => SCHAC_NEW_NS.'schacPersonalUniqueID', SCHAC_OLD_NS.'schacPlaceOfBirth' => SCHAC_NEW_NS.'schacPlaceOfBirth', SCHAC_OLD_NS.'schacProjectMembership' => SCHAC_NEW_NS.'schacProjectMembership', SCHAC_OLD_NS.'schacProjectSpecificRole' => SCHAC_NEW_NS.'schacProjectSpecificRole', SCHAC_OLD_NS.'schacSn1' => SCHAC_NEW_NS.'schacSn1', SCHAC_OLD_NS.'schacSn2' => SCHAC_NEW_NS.'schacSn2', SCHAC_OLD_NS.'schacUserPresenceID' => SCHAC_NEW_NS.'schacUserPresenceID', SCHAC_OLD_NS.'schacUserPrivateAttribute' => SCHAC_NEW_NS.'schacUserPrivateAttribute', SCHAC_OLD_NS.'schacUserStatus' => SCHAC_NEW_NS.'schacUserStatus', SCHAC_OLD_NS.'schacYearOfBirth' => SCHAC_NEW_NS.'schacYearOfBirth', ]; simplesamlphp-1.19.1/attributemap/linkedin2name.php0000644000000000000000000000131114042503475021111 0ustar rootroot 'eduPersonPrincipalName', // id @ linkedin.com 'linkedin_targetedID' => 'eduPersonTargetedID', // http://linkedin.com!id // Attributes Returned by LinkedIn 'linkedin.firstName' => 'givenName', 'linkedin.lastName' => 'sn', 'linkedin.id' => 'uid', // alpha + mixed case user id 'linkedin.headline' => 'title', 'linkedin.summary' => 'description', ]; simplesamlphp-1.19.1/attributemap/name2claim.php0000644000000000000000000000201314042503475020401 0ustar rootroot 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country', 'givenName' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', 'mail' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', 'memberOf' => 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role', 'postalcode' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode', 'uid' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name', 'sn' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname', 'st' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince', 'streetaddress' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress', 'telephonenumber' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone', ]; simplesamlphp-1.19.1/webpack.config.js0000644000000000000000000000671514042503475016412 0ustar rootrootconst path = require('path'); const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const buildDir = __dirname + '/www/assets/'; const localConfig = { css_filename: 'css/[name].css', js_filename: 'js/[name].js' }; module.exports = environment => { const env = typeof environment !== 'undefined' ? environment : {}; const primaryBackground = env.hasOwnProperty('primaryBackground') ? env.primaryBackground : '#b8002c'; const transitionBackground = env.hasOwnProperty('transitionBackground') ? env.transitionBackground : '#db0100'; const secondaryBackground = env.hasOwnProperty('secondaryBackground') ? env.secondaryBackground : '#e8410c'; return { entry: { bundle: './src/js/bundle', logout: './src/js/logout/main', stylesheet: './src/js/style' }, output: { path: path.resolve(buildDir), filename: localConfig['js_filename'] }, mode: 'production', module: { rules: [ { test: /\.js$/, exclude: /\/node_modules\//, use: { loader: 'babel-loader' } }, { test: /\.scss$/, use: [ 'style-loader', MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { url: false } }, { loader: 'sass-loader', options: { sassOptions: { indentedSyntax: false }, additionalData: "$primaryBackground: " + primaryBackground + '; ' + "$transitionBackground: " + transitionBackground + "; " + "$secondaryBackground: " + secondaryBackground + ";" } } ] }, { // expose jquery for use outside webpack bundle test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' }, { loader: 'expose-loader', options: '$' }] } ] }, devtool: 'source-map', plugins: [ // Provides jQuery for other JS bundled with Webpack new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), new MiniCssExtractPlugin({ filename: localConfig['css_filename'], ignoreOrder: true }), new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname + '/node_modules/\@fortawesome/fontawesome-free/webfonts/*'), to: 'fonts/', flatten: true } ] }) ] } }; simplesamlphp-1.19.1/dictionaries/0000755000000000000000000000000014042503475015640 5ustar rootrootsimplesamlphp-1.19.1/dictionaries/logout.definition.json0000644000000000000000000000242514042503475022176 0ustar rootroot{ "title": { "en": "Logged out" }, "logged_out_text": { "en": "You have been logged out." }, "default_link_text": { "en": "Go back to SimpleSAMLphp installation page" }, "hold": { "en": "On hold" }, "completed": { "en": "Completed" }, "progress": { "en": "Logging out..." }, "failed": { "en": "Logout failed" }, "return": { "en": "Return to service" }, "success": { "en": "You have successfully logged out from all services listed above." }, "loggedoutfrom": { "en": "You are now successfully logged out from %SP%." }, "also_from": { "en": "You are also logged in on these services:" }, "logout_all_question": { "en": "Do you want to logout from all the services above?" }, "logout_all": { "en": "Yes, all services" }, "logout_only": { "en": "No, only %SP%" }, "incapablesps": { "en": "One or more of the services you are logged into do not support logout<\/i>. To ensure that all your sessions are closed, you are encouraged to close your webbrowser<\/i>." }, "no": { "en": "No" }, "logging_out_from": { "en": "Logging out of the following services:" }, "failedsps": { "en": "Unable to log out of one or more services. To ensure that all your sessions are closed, you are encouraged to close your webbrowser<\/i>." } } simplesamlphp-1.19.1/dictionaries/admin.definition.json0000644000000000000000000001006514042503475021754 0ustar rootroot{ "cfg_check_header": { "en": "Configuration check" }, "cfg_check_select_file": { "en": "Select configuration file to check:" }, "cfg_check_notices": { "en": "Notices" }, "cfg_check_missing": { "en": "Options missing from config file" }, "cfg_check_superfluous": { "en": "Superfluous options in config file" }, "cfg_check_noerrors": { "en": "No errors found." }, "cfg_check_back": { "en": "Go back to the file list" }, "metaover_header": { "en": "Metadata overview" }, "metaover_intro": { "en": "To look at the details for an SAML entity, click on the SAML entity header." }, "metaover_errorentry": { "en": "Error in this metadata entry" }, "metaover_required_found": { "en": "Required fields" }, "metaover_required_not_found": { "en": "The following required fields was not found" }, "metaover_optional_found": { "en": "Optional fields" }, "metaover_optional_not_found": { "en": "The following optional fields was not found" }, "metaover_unknown_found": { "en": "The following fields was not recognized" }, "metaover_group_metadata.saml20-sp-hosted": { "en": "SAML 2.0 Service Provider (Hosted)" }, "metaover_group_metadata.saml20-sp-remote": { "en": "SAML 2.0 Service Provider (Remote)" }, "metaover_group_metadata.saml20-idp-hosted": { "en": "SAML 2.0 Identity Provider (Hosted)" }, "metaover_group_metadata.saml20-idp-remote": { "en": "SAML 2.0 Identity Provider (Remote)" }, "metaover_group_metadata.shib13-sp-hosted": { "en": "Shib 1.3 Service Provider (Hosted)" }, "metaover_group_metadata.shib13-sp-remote": { "en": "Shib 1.3 Service Provider (Remote)" }, "metaover_group_metadata.shib13-idp-hosted": { "en": "Shib 1.3 Identity Provider (Hosted)" }, "metaover_group_metadata.shib13-idp-remote": { "en": "Shib 1.3 Identity Provider (Remote)" }, "metaover_group_metadata.adfs-sp-remote": { "en": "ADFS Service Provider (Remote)" }, "metaover_group_metadata.adfs-idp-hosted": { "en": "ADFS Identity Provider (Hosted)" }, "metaconv_title": { "en": "Metadata parser" }, "metaconv_selectfile": { "en": "or select a file:" }, "metaconv_parse": { "en": "Parse" }, "metaconv_converted": { "en": "Converted metadata" }, "metadata_saml20-sp": { "en": "SAML 2.0 SP Metadata" }, "metadata_saml20-idp": { "en": "SAML 2.0 IdP Metadata" }, "metadata_shib13-sp": { "en": "Shib 1.3 SP Metadata" }, "metadata_shib13-idp": { "en": "Shib 1.3 IdP Metadata" }, "metadata_adfs-sp": { "en": "ADFS SP Metadata" }, "metadata_adfs-idp": { "en": "ADFS IdP Metadata" }, "metadata_intro": { "en": "Here is the metadata that SimpleSAMLphp has generated for you. You may send this metadata document to trusted partners to setup a trusted federation." }, "metadata_xmlurl": { "en": "You can get the metadata xml on a dedicated URL<\/a>:" }, "metadata_metadata": { "en": "Metadata" }, "metadata_cert": { "en": "Certificates" }, "metadata_cert_intro": { "en": "Download the X509 certificates as PEM-encoded files." }, "metadata_xmlformat": { "en": "In SAML 2.0 Metadata XML format:" }, "metadata_simplesamlformat": { "en": "In SimpleSAMLphp flat file format - use this if you are using a SimpleSAMLphp entity on the other side:" }, "debug_sending_message_title": { "en": "Sending message" }, "debug_sending_message_text_button": { "en": "You are about to send a message. Hit the submit message button to continue." }, "debug_sending_message_text_link": { "en": "You are about to send a message. Hit the submit message link to continue." }, "debug_sending_message_send": { "en": "Submit message" }, "debug_sending_message_msg_title": { "en": "Message" }, "debug_sending_message_msg_text": { "en": "As you are in debug mode, you get to see the content of the message you are sending:" }, "debug_disable_debug_mode": { "en": "You can turn off debug mode in the global SimpleSAMLphp configuration file config\/config.php<\/tt>." }, "metaconv_xmlmetadata": { "en": "XML metadata" } } simplesamlphp-1.19.1/dictionaries/attributes.definition.json0000644000000000000000000000654414042503475023061 0ustar rootroot{ "attribute_edupersonaffiliation": { "en": "Affiliation" }, "attribute_title": { "en": "Title" }, "attribute_uid": { "en": "User ID" }, "attribute_sn": { "en": "Surname" }, "attribute_givenname": { "en": "Given name" }, "attribute_cn": { "en": "Common name" }, "attribute_mail": { "en": "Mail" }, "attribute_ismemberof": { "en": "Group membership" }, "attribute_mobile": { "en": "Mobile" }, "attribute_preferredlanguage": { "en": "Preferred language" }, "attribute_noredupersonnin": { "en": "Identity number assigned by public authorities" }, "attribute_schachomeorganization": { "en": "Home organization domain name" }, "attribute_organisationname": { "en": "Organization name" }, "attribute_edupersonentitlement": { "en": "Entitlement regarding the service" }, "attribute_edupersonscopedaffiliation": { "en": "Affiliation at home organization" }, "attribute_edupersontargetedid": { "en": "Persistent pseudonymous ID" }, "attribute_pairwise_id": { "en": "Service-specific pseudonymous ID at home organization" }, "attribute_edupersonprincipalname": { "en": "Person's principal name at home organization" }, "attribute_edupersonuniqueid": { "en": "Person's non-reassignable, persistent pseudonymous ID at home organization" }, "attribute_subject_id": { "en": "Pseudonymous ID at home organization" }, "attribute_edupersonorcid": { "en": "ORCID researcher identifiers" }, "attribute_o": { "en": "Organization name" }, "attribute_dc": { "en": "Domain component (DC)" }, "attribute_displayname": { "en": "Display name" }, "attribute_facsimiletelephonenumber": { "en": "Fax number" }, "attribute_homephone": { "en": "Home telephone" }, "attribute_homepostaladdress": { "en": "Home postal address" }, "attribute_jpegphoto": { "en": "JPEG Photo" }, "attribute_l": { "en": "Locality" }, "attribute_labeleduri": { "en": "Labeled URI" }, "attribute_manager": { "en": "Manager" }, "attribute_ou": { "en": "Organizational unit" }, "attribute_postaladdress": { "en": "Postal address" }, "attribute_postalcode": { "en": "Postal code" }, "attribute_postofficebox": { "en": "Post office box" }, "attribute_street": { "en": "Street" }, "attribute_telephonenumber": { "en": "Telephone number" }, "attribute_eduorghomepageuri": { "en": "Organizational homepage" }, "attribute_eduorglegalname": { "en": "Organization's legal name" }, "attribute_edupersonassurance": { "en": "Identity assurance profile" }, "attribute_edupersonnickname": { "en": "Nickname" }, "attribute_edupersonorgdn": { "en": "Distinguished name (DN) of person's home organization" }, "attribute_edupersonorgunitdn": { "en": "Distinguished name (DN) of the person's home organizational unit" }, "attribute_edupersonprimaryaffiliation": { "en": "Primary affiliation" }, "attribute_noreduorgnin": { "en": "Organizational number" }, "attribute_noredupersonbirthdate": { "en": "Date of birth" }, "attribute_noredupersonlegalname": { "en": "Legal name" }, "attribute_noredupersonlin": { "en": "Local identity number" }, "attribute_edupersonprimaryorgunitdn": { "en": "Distinguished name (DN) of person's primary Organizational Unit" }, "attribute_userpassword": { "en": "User's password hash" }, "attribute_schacuserprivateattribute": { "en": "Private information elements" } } simplesamlphp-1.19.1/dictionaries/status.definition.json0000644000000000000000000000162214042503475022206 0ustar rootroot{ "header_saml20_sp": { "en": "SAML 2.0 SP Demo Example" }, "header_shib": { "en": "Shibboleth demo" }, "header_diagnostics": { "en": "SimpleSAMLphp Diagnostics" }, "some_error_occurred": { "en": "Some error occurred" }, "intro": { "en": "Hi, this is the status page of SimpleSAMLphp. Here you can see if your session is timed out, how long it lasts until it times out and all the attributes that are attached to your session." }, "validfor": { "en": "Your session is valid for %SECONDS% seconds from now." }, "sessionsize": { "en": "Session size: %SIZE%" }, "subject_header": { "en": "SAML Subject" }, "subject_notset": { "en": "not set" }, "subject_format": { "en": "Format" }, "attributes_header": { "en": "Your attributes" }, "logout": { "en": "Logout" }, "authData_header": { "en": "AuthData" }, "authData_summary": { "en": "Click to view AuthData" } } simplesamlphp-1.19.1/dictionaries/disco.definition.json0000644000000000000000000000064714042503475021772 0ustar rootroot{ "selectidp": { "en": "Select your identity provider" }, "selectidp_full": { "en": "Please select the identity provider where you want to authenticate:" }, "select": { "en": "Select" }, "remember": { "en": "Remember my choice" }, "icon_prefered_idp": { "en": "[Preferred choice]" }, "previous_auth": { "en": "You have previously chosen to authenticate at" }, "login_at": { "en": "Login at" } } simplesamlphp-1.19.1/dictionaries/errors.translation.json0000644000000000000000000110742614042503475022417 0ustar rootroot{ "error_header": { "no": "SimpleSAMLphp-feil", "nn": "SimpleSAMLphp feil", "sv": "SimpleSAMLphp fel", "es": "Error de SimpleSAMLphp", "fr": "erreur de SimpleSAMLphp", "de": "SimpleSAMLphp Fehler", "nl": "SimpleSAMLphp-fout", "lb": "SimpleSAMLphp Fehler", "sl": "SimpleSAMLphp napaka", "da": "SimpleSAMLphp fejl", "hr": "SimpleSAMLphp gre\u0161ka", "hu": "SimpleSAMLphp hiba", "fi": "SimpleSAMLphp virhe", "pt-br": "Erro do SimpleSAMLphp", "pt": "Erro no SimpleSAMLphp", "pl": "b\u0142\u0105d SimpleSAMLphp", "cs": "SimpleSAMLphp chyba", "eu": "SimpleSAMLphp-en errorea", "tr": "SimpleSAMLphp hatas\u0131", "it": "Errore di SimpleSAMLphp", "lt": "SimpleSAMLphp klaida", "ja": "SimpleSAMLphp\u30a8\u30e9\u30fc", "zh-tw": "SimpleSAMLphp \u932f\u8aa4", "et": "SimpleSAMLphp t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1 SimpleSAMLphp", "zh": "SimpleSAMLphp\u9519\u8bef", "sr": "SimpleSAMLphp gre\u0161ka", "ar": "\u062e\u0637\u0627 \u0628 SimpleSAMLphp", "lv": "SimpleSAMLphp k\u013c\u016bda", "id": "Error simpelSAMLphp", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 SimpleSAMLphp", "ro": "Eroare SimpleSAMLphp", "af": "SimpleSAMLphp-fout", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c4\u03bf\u03c5 SimpleSAMLphp", "zu": "Iphutha le-SimpleSAMLphp", "xh": "Impazamo ye-SimpleSAMLphp", "st": "Phoso ya SimpleSAMLphp", "ca": "Error de SimpleSAMLphp" }, "report_trackid": { "no": "Hvis vil rapportere denne feilen, send ogs\u00e5 med dette sporingsnummeret. Det gj\u00f8r det enklere for systemadministratorene \u00e5 finne ut hva som gikk galt:", "nn": "Send med sporingsnummeret dersom du vil rapportera feilen. Sporingsnummeret gjer det enklare for systemadministratorane \u00e5 finna ut kva som er problemet:", "sv": "Om du rapporterar felet b\u00f6r du ocks\u00e5 skicka med detta sp\u00e5rnings-ID. Det g\u00f6r det enklare f\u00f6r den som sk\u00f6ter systemet att fels\u00f6ka problemet:", "es": "Por favor, si informa de este error, mantenga el tracking ID<\/em> que permite encontrar su sesión en los registros de que dispone el administrador del sistema:", "fr": "Si vous signalez cette erreur, veuillez aussi signaler l'identifiant de suivi qui permet de trouver votre session dans les logs accessibles \u00e0 l'administrateur syst\u00e8me :", "de": "Falls Sie diesen Fehler melden, teilen Sie bitte ebenfalls diese Tracking ID mit, dadurch ist es dem Administrator m\u00f6glich ihre Sitzung in den Logs zu finden:", "nl": "Wanneer je deze fout rapporteert, geef dan AUB ook de volgende tracking ID door, waarmee het mogelijk is om jouw sessie in de logs terug te vinden:", "lb": "Wann dir ons d\u00ebsen Fehler matdeelt, dann sch\u00e9ckt w.e.g och d Tracking ID mat. Dei ennerst\u00ebtzt den System Administrator aer Session an den Logs er\u00ebmzefannen:", "sl": "\u010ce boste prijavili to napako, prilo\u017eite tudi ID seje, preko katere bo la\u017eje najti va\u0161e zapise v dnevni\u0161kih datotekah, ki so na voljo skrbniku sistema.", "da": "Hvis du vil rapportere denne fejl, s\u00e5 medsend venligst dette sporings-ID. Den g\u00f8r det muligt for teknikerne at finde fejlen.", "hr": "Molimo da prilikom prijavljivanja gre\u0161ke po\u0161aljete i ovaj identifikator koji \u0107e administratorima omogu\u0107iti pronala\u017eenje dodatnih informacija u dnevni\u010dkim zapisima:", "hu": "Ha bejelent\u00e9st k\u00fcld a hib\u00e1val kapcsolatban, k\u00e9rj\u00fck, k\u00fcldje el ezt az azonos\u00edt\u00f3t, mert csak ennek seg\u00edts\u00e9g\u00e9vel tudja a rendszeradminisztr\u00e1tor a napl\u00f3\u00e1llom\u00e1nyokb\u00f3l azokat az adatokat megtal\u00e1lni, amelyek ehhez a munkamenethez tartoznak.", "fi": "Mik\u00e4li ilmoitat virheest\u00e4, ole hyv\u00e4 ja sis\u00e4ll\u00e4 t\u00e4m\u00e4 seurantanumero raporttiin. Seurantanumerolla yll\u00e4pit\u00e4j\u00e4 l\u00f6yt\u00e4\u00e4 istuntosi lokeista helpommin.", "pt-br": "Se informar sobre esse erro, por favor, tamb\u00e9m informe este ID do relat\u00f3rio de monitoramento que torna poss\u00edvel localizar a sua sess\u00e3o nos registros dispon\u00edveis para o administrador do sistema:", "pt": "Se comunicar este erro ao administrador de sistemas inclua o seguinte identificador que possibilita a localiza\u00e7\u00e3o da sua sess\u00e3o nos registos do servi\u00e7o:", "pl": "Je\u015bli zg\u0142aszasz ten bl\u0105d, podaj tak\u017ce ID zdarzenia, kt\u00f3ry umo\u017cliwi administratorowi zlokalizowa\u0107 Twoj\u0105 sesje w logach:", "cs": "Pokud budete reportovat tuto chybu, pros\u00edm za\u0161lete tak\u00e9 toto ID, toto umo\u017en\u00ed naj\u00edt va\u0161\u00ed session v logu, kter\u00fd je dostupn\u00fd systmov\u00fdm administr\u00e1torem\uff1a ", "tr": "Bu hatay\u0131 bildirirseniz, l\u00fctfen, sistem y\u00f6neticisi taraf\u0131ndan incelebilen kay\u0131tlardan oturumunuzun belirlenebilmesini sa\u011flayan izleme ID'sini de bildirin.", "it": "Se inoltri questo errore, per favore riporta anche questo tracking ID, esso renderà possibile all'amministratore del sistema il tracciamento della tua sessione nei log:", "lt": "Jei prane\u0161ate apie \u0161i\u0105 klaid\u0105, neu\u017emir\u0161kite pateikti \u0161ios klaidos ID, kurio d\u0117ka sistemos administratorius gal\u0117s surasti J\u016bs\u0173 sesijos metu atliktus veiksmus atlikt\u0173 veiksm\u0173 istorijoje:", "ja": "\u3053\u306e\u30a8\u30e9\u30fc\u3092\u5831\u544a\u3059\u308b\u5834\u5408\u3001\u30b7\u30b9\u30c6\u30e0\u7ba1\u7406\u8005\u304c\u30ed\u30b0\u304b\u3089\u3042\u306a\u305f\u306e\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u7279\u5b9a\u3059\u308b\u70ba\u306b\u3001\u30c8\u30e9\u30c3\u30ad\u30f3\u30b0\u756a\u53f7\u3092\u5831\u544a\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "zh-tw": "\u5982\u679c\u60a8\u56de\u5831\u9019\u500b\u932f\u8aa4\uff0c\u8acb\u540c\u6642\u56de\u5831\u9019\u500b\u8ffd\u8e64\u865f\u78bc\uff0c\u8b93\u7cfb\u7d71\u7ba1\u7406\u54e1\u53ef\u4ee5\u85c9\u7531\u5b83\u627e\u5230\u60a8\u7684\u9023\u7dda\u8a18\u9304\uff1a", "et": "Kui rapoteerid sellest t\u00f5rkest, siis teata kindlasti ka j\u00e4lgimisnumber, mis v\u00f5imaldab s\u00fcsteemiadministraatoril logifailidest sinu sessiooniga seotud infot leida:", "he": "\u05d0\u05dd \u05d0\u05ea\u05d4 \u05de\u05d3\u05d5\u05d5\u05d7 \u05e2\u05dc \u05d4\u05ea\u05e7\u05dc\u05d4, \u05d0\u05e0\u05d0 \u05d3\u05d5\u05d5\u05d7 \u05d2\u05dd \u05d0\u05ea \u05de\u05e1\u05e4\u05e8 \u05d4\u05de\u05e2\u05e7\u05d1 \u05d4\u05de\u05d0\u05e4\u05e9\u05e8 \u05dc\u05d0\u05ea\u05e8 \u05d0\u05ea \u05d4\u05e9\u05d9\u05d7\u05d4 \u05e9\u05dc\u05da \u05d1\u05d9\u05d5\u05de\u05e0\u05d9\u05dd \u05d4\u05e2\u05d5\u05de\u05d3\u05d9\u05dd \u05dc\u05e8\u05e9\u05d5\u05ea \u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea: ", "zh": "\u5982\u679c\u4f60\u62a5\u544a\u4e86\u8fd9\u4e2a\u9519\u8bef\uff0c\u90a3\u4e48\u8bf7\u4f60\u4e5f\u62a5\u544a\u8fd9\u4e2a\u8ffd\u8e2a\u53f7\u7801\uff0c\u7cfb\u7edf\u7ba1\u7406\u5458\u6709\u53ef\u80fd\u6839\u636e\u8fd9\u4e2a\u53f7\u7801\u5728\u65e5\u5fd7\u4e2d\u5b9a\u4f4d\u4f60\u7684SESSION", "sr": "Ako prijavite ovu gre\u0161ku, molimo Vas da tako\u0111e po\u0161aljete i ovaj identifikator koji \u0107e omogu\u0107iti da se Va\u0161a sesija locira u logovima dostupnim adminstratoru sistema:", "ar": "\u0627\u0630\u0627 \u0642\u0645\u062a \u0628\u0631\u0641\u0639 \u062a\u0642\u0631\u064a\u0631 \u0639\u0646 \u0647\u0630\u0627 \u0627\u0644\u062e\u0637\u0623 \u0642\u0645 \u0631\u062c\u0627\u0621\u0627\u064b \u0628\u0625\u062f\u0631\u0627\u062c \u0631\u0642\u0645 \u0627\u0644\u0645\u062a\u0627\u0628\u0639\u0629 \u0623\u062f\u0646\u0627\u0647 \u0643\u064a\u0645\u0627 \u0646\u0633\u062a\u0637\u064a\u0639 \u062a\u062d\u062f\u064a\u062f \u0641\u062a\u0631\u0629 \u062f\u062e\u0648\u0644\u0643 \u0628\u0645\u0644\u0641\u0627\u062a \u0627\u0644\u0645\u0634\u0631\u0641 \u0639\u0644\u064a \u0627\u0644\u0645\u0648\u0642\u0639", "lv": "Kad zi\u0146ojat par k\u013c\u016bdu, l\u016bdzu nor\u0101diet \u0161o atseko\u0161anas numuru, kas administratoram pal\u012bdz atrast \u0161o sesiju sist\u0113mas ierakstos.", "id": "Jika Anda melaporkan error ini, tolong laporkan juga nomor pelacakan sehingga memungkinkan untuk lokasi session anda pada log tersedia untuk system administrator:", "ru": "\u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0438\u043d\u0433\u043e\u0432\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 (\u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 \u043d\u0430\u0439\u0442\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u0430\u0448\u0435\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043b\u043e\u0433\u0430\u0445):", "ro": "Dac\u0103 raporta\u021bi aceast\u0103 eroare, v\u0103 rug\u0103m s\u0103 include\u021bi urm\u0103torul num\u0103r de \u00eenregistrare care va permite localizarea sesiunii dumneavoastr\u0103 \u00een jurnalele de sistem:", "eu": "Mesedez, errore honen berri ematen baduzu, mantendu ezazu jarraipen zenbaki hau, honek sistemaren administratzaileak dituen erregistroetan zure saioa aurkitzea ahalbidetzen baitu:", "af": "Waneer jy die fout rapporteer, verskaf asb. ook die 'tracking'\/verwysings nommer wat dit moontlik maak vir die sisteem administrateur om jou sessie in die logs op te spoor:", "el": "\u0391\u03bd \u03b1\u03bd\u03b1\u03c6\u03ad\u03c1\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u002c \u03c0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bc\u03c0\u03b5\u03c1\u03b9\u03bb\u03ac\u03b2\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b7\u03bd \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03c3\u03b1\u03c2 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc \u03c0\u03c1\u03bf\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 \u03bd\u03b1 \u03b4\u03b9\u03b5\u03c5\u03ba\u03bf\u03bb\u03cd\u03bd\u03b5\u03c4\u03b5 \u03c4\u03b7 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1 \u03b5\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03bf\u03cd \u03ba\u03b1\u03b9 \u03b5\u03c0\u03af\u03bb\u03c5\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 \u03c0\u03c1\u03bf\u03b2\u03bb\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2:", "zu": "Uma ubika leli phutha, sicela futhi ubike le nombolo yokulandelela eyenza kube nokwenzeka ukuthola iseshini yakho kumalogi atholakalayo kumlawuli wesistimu:", "xh": "Ukuba ngaba uchaza le mpazamo, nceda kananjalo uchaze le nombolo yolandelelo eyenza kube lula ukufumana iseshoni yakho kwiincwadi ezifumaneka kumlawuli wesistim:", "st": "Haeba o tlaleha phoso ena, ka kopo tlaleha hape nomoro ena ya ho sala morao e kgonahatsang hore o fumane seshene ya hao ho di-log ts efumanehang ho sistimi ya motsamaisi:", "ca": "Si informeu d’aquest error, notifiqueu també aquest número de seguiment que permet localitzar la vostra sessió als registres disponibles per a l’administrador del sistema:" }, "debuginfo_header": { "no": "Detaljer for feils\u00f8king", "nn": "Detaljar for feils\u00f8king", "sv": "Detaljer f\u00f6r fels\u00f6kning", "es": "Informaci\u00f3n de depuraci\u00f3n", "fr": "Information de d\u00e9boguage", "de": "Debug Information", "nl": "Debuginformatie", "lb": "Debug Informatiounen", "sl": "Pomo\u010d pri odpravljanju napak (debug)", "da": "Detaljer til fejls\u00f8gning", "hr": "Informacije o gre\u0161ki", "hu": "B\u0151vebb inform\u00e1ci\u00f3 a hib\u00e1r\u00f3l", "fi": "Virheenetsint\u00e4tietoja", "pt-br": "Informa\u00e7\u00e3o do Debug", "pt": "Informa\u00e7\u00e3o de debug", "pl": "Informacja debugger'a", "cs": "Ladic\u00ed informace", "eu": "Arazketa informazioa", "tr": "Hata ay\u0131klama bilgisi", "it": "Informazioni di debug", "lt": "Detali informacija", "ja": "\u30c7\u30d0\u30c3\u30b0\u60c5\u5831", "zh-tw": "\u9664\u932f\u8cc7\u8a0a", "et": "Silumisinfo", "he": "\u05de\u05d9\u05d3\u05e2 \u05d3\u05d1\u05d0\u05d2", "zh": "\u8c03\u8bd5\u4fe1\u606f", "sr": "Informacije o gre\u0161ki", "ar": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062a\u0635\u062d\u064a\u062d", "lv": "Atk\u013c\u016bdo\u0161anas infom\u0101cija", "id": "Informasi debug", "ru": "\u041e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", "ro": "Informa\u021bii de depanare", "af": "Ontleed informasie", "el": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03b5\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03bf\u03cd \u03c3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd", "xh": "Inkcazelo yokulungisa", "zu": "Ulwazi lokususwa kwephutha", "st": "Tlhahisoleseding ya debug", "ca": "Informació de depuració" }, "debuginfo_text": { "no": "Detaljene nedenfor kan v\u00e6re av interesse for administratoren \/ brukerst\u00f8tte:", "nn": "Detaljane under kan vera av interesse for administrator eller hjelpetenesta", "sv": "Detaljerna nedan kan vara av intresse f\u00f6r helpdesk eller de som sk\u00f6ter systemet:", "es": "La siguiente informaci\u00f3n de depuraci\u00f3n puede ser de utilidad para el administrador del sistema o el centro de atenci\u00f3n a usuarios:", "fr": "L'information de d\u00e9boguage ci-dessous peut \u00eatre int\u00e9ressante pour l'administrateur ou le help desk :", "de": "Die unten angegebene Debug-Information kann von Interesse f\u00fcr den Administrator oder das Helpdesk sein:", "nl": "Onderstaande debuginformatie kan van belang zijn voor de beheerder \/ helpdesk:", "lb": "Dei Debug Informatiounen hei dr\u00ebnner kinnten den Administrator interess\u00e9iren:", "sl": "Podatki o odpravljanju napak bodo zanimali skrbnika\/helpdesk:", "da": "Detaljerne herunder kan v\u00e6re af interesse for teknikerne \/ help-desken", "hr": "Sljede\u0107e informacije mogu biti zanimljive administratorima ili slu\u017ebi za podr\u0161ku korisnicima:", "hu": "Az al\u00e1bbi inform\u00e1ci\u00f3 esetleg \u00e9rdekes lehet a rendszergazda \/ helpdesk sz\u00e1m\u00e1ra:", "fi": "Alla olevat virheenetsint\u00e4tiedot voivat kiinnostaa yll\u00e4pit\u00e4j\u00e4\u00e4\u00e4 tai helpdeski\u00e4:", "pt-br": "A informa\u00e7\u00e3o a seguir \u00e9 importante para seu administrador \/ Central de D\u00favidas", "pt": "A informa\u00e7\u00e3o de debug abaixo pode ter interesse para o administrador \/ apoio ao utilizador:", "pl": "Poni\u017csza informacja debugger'a mo\u017ce by\u0107 przydatna dla administara \/ helpdesk:", "cs": "N\u00e1sleduj\u00edc\u00ed ladic\u00ed informace m\u016f\u017ee zaj\u00edmat administr\u00e1tora (helpdesk)", "eu": "Arazketa informazio hau erabilgarria izan daiteke sistemaren administratzailea edo erabiltzailearen arreta zentroarentzat:", "tr": "A\u015fa\u011f\u0131daki hata ay\u0131klama bilgisi y\u00f6neticinin\/yard\u0131m masas\u0131n\u0131n ilgisini \u00e7ekebilir:", "it": "Le seguenti informazioni di debug possono interessare l'amministratore di sistema o il supporto utenti:", "lt": "\u0160i detali informacija gali b\u016bti \u012fdomi administratoriui:", "ja": "\u30b7\u30b9\u30c6\u30e0\u7ba1\u7406\u8005\u3084\u30d8\u30eb\u30d7\u30c7\u30b9\u30af\u306f\u4ee5\u4e0b\u306e\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\u306b\u8208\u5473\u3092\u6301\u3064\u304b\u3082\u3057\u308c\u307e\u305b\u3093:", "zh-tw": "\u7ba1\u7406\u54e1\u6216\u670d\u52d9\u53f0\u53ef\u80fd\u5c0d\u4e0b\u5217\u9664\u932f\u8cc7\u8a0a\u6709\u8208\u8da3\uff1a", "et": "Allpool olev silumisinfo v\u00f5ib olla administraatorile v\u00f5i kasutajatoele v\u00e4ga kasulik:", "he": "\u05d9\u05db\u05d5\u05dc \u05dc\u05d4\u05d9\u05d5\u05ea \u05e9\u05de\u05d9\u05d3\u05e2 \u05d4\u05d3\u05d1\u05d0\u05d2 \u05dc\u05de\u05d8\u05d4 \u05d9\u05e2\u05e0\u05d9\u05d9\u05df \u05d0\u05ea \u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea \/ \u05ea\u05de\u05d9\u05db\u05d4 \u05d8\u05db\u05e0\u05d9\u05ea:", "zh": "\u7ba1\u7406\u5458\u6216\u8005\u670d\u52a1\u53f0\u53ef\u80fd\u5bf9\u4e0b\u9762\u7684\u8c03\u8bd5\u4fe1\u606f\u5f88\u611f\u5174\u8da3", "sr": "Informacije o gre\u0161ci koje se nalaze ispod mogu biti od interesa administratoru ili slu\u017ebi za podr\u0161ku korisnicima.", "ar": " \u0642\u062f \u062a\u0643\u0648\u0646 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062a\u0635\u062d\u064a\u062d \u0623\u062f\u0646\u0627\u0647 \u0645\u0641\u064a\u062f\u0629 \u0644\u0645\u0634\u0631\u0641 \u0627\u0644\u0645\u0648\u0642\u0639\/ \u0627\u0648 \u0645\u0648\u0638\u0641 \u0627\u0644\u0645\u0633\u0627\u0639\u062f\u0629", "lv": "Zem\u0101k eso\u0161\u0101 atk\u013c\u016bdo\u0161anas inform\u0101cija var interes\u0113t administratoru un pal\u012bdz\u012bbas dienestu:", "id": "Informasi debug dibawah ini mungkin menarik bagi administrator\/help desk:", "ru": "\u041d\u0438\u0436\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b:", "ro": "Informa\u021biile de depanare de mai jos pot fi importante pentru administratorul de sistem:", "af": "Die onderstaande informasie mag van hulp wees vir die stelsel administrateur \/ hulplyn.", "el": "\u039f\u03b9 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03c4\u03c9 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b4\u03b9\u03b5\u03c5\u03ba\u03bf\u03bb\u03cd\u03bd\u03bf\u03c5\u03bd \u03c4\u03b7 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1 \u03b5\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03bf\u03cd \u03ba\u03b1\u03b9 \u03b5\u03c0\u03af\u03bb\u03c5\u03c3\u03b7\u03c2 \u03c3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd.", "xh": "Inkcazelo yokulungisa engezantsi isenokuba ibangela umdla kumlawuli / idesika yoncedo:", "zu": "Ulwazi lokususwa kwephutha olungezansi lungase lukhange kumlawuli / ideski losizo:", "st": "Tlhahisoleseding ya debug e ka tlase mona e ka nna ya kgahla motsamaisi / deske ya thuso:", "ca": "La informació de depuració següent pot ser d’interès per l’administrador \/ centre d'atenció a l'usuari:" }, "report_header": { "no": "Rapporter feil", "nn": "Rapporter feil", "sv": "Rapportera fel", "es": "Informar del error", "fr": "Signaler les erreurs", "de": "Fehler melden", "nl": "Rapporteer fouten", "lb": "Fehler matdeelen", "sl": "Prijavi napake", "da": "Rapport\u00e9r fejl", "hr": "Prijavi gre\u0161ku", "hu": "Mutassa a hiba\u00fczeneteket", "fi": "Ilmoita virheist\u00e4", "pt-br": "Reportar erros", "pt": "Reportar um erro", "pl": "Raport b\u0142\u0119d\u00f3w", "cs": "Ozn\u00e1mit chyby", "eu": "Erroreen berri eman", "tr": "Hatalar\u0131 bildir", "lt": "Prane\u0161ti apie klaidas", "it": "Riporta gli errori", "ja": "\u30a8\u30e9\u30fc\u3092\u30ec\u30dd\u30fc\u30c8", "zh-tw": "\u932f\u8aa4\u5831\u544a", "et": "Raporteeri t\u00f5rked", "he": "\u05d3\u05d5\u05d5\u05d7 \u05d8\u05e2\u05d5\u05d9\u05d5\u05ea", "zh": "\u62a5\u544a\u9519\u8bef", "sr": "Prijavi gre\u0161ku", "ar": "\u0627\u0631\u0641\u0639 \u062a\u0642\u0631\u064a\u0631\u0627\u064b \u0639\u0646 \u0627\u0644\u0623\u062e\u0637\u0627\u0621 ", "lv": "Zi\u0146ot par k\u013c\u016bd\u0101m", "id": "Laporakan error", "ru": "\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445", "ro": "Raporta\u021bi erorile", "af": "Rapporteer foute", "el": "\u0391\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03bf\u03c2", "zu": "Amaphutha ombiko", "xh": "Chaza iimpazamo", "st": "Tlaleha diphoso", "ca": "Informeu de l’error" }, "report_text": { "no": "Hvis du \u00f8nsker at brukerst\u00f8tte skal kunne kontakte deg igjen i forbindelse med denne feilen, m\u00e5 du oppgi e-postadressen din nedenfor:", "nn": "Om du vil at hjelpetenesta skal kontakta deg i samband med denne feilen, m\u00e5 du oppgi epostadressa di:", "sv": "Om du anger din e-postadress kan den som sk\u00f6ter systemet kontakta dig f\u00f6r fler fr\u00e5gor om ditt problem:", "es": "Si lo desea, indique su direcci\u00f3n electr\u00f3nica, para que los administradores puedan ponerse en contacto con usted y obtener datos adicionales de su problema", "fr": "De mani\u00e8re optionnelle, vous pouvez entrer votre courriel, afin que les administrateurs puissent vous contacter par la suite \u00e0 propos de votre probl\u00e8me :", "de": "Geben Sie optional eine E-Mail-Adresse an, so dass der Administrator Sie bei etwaigen R\u00fcckfragen kontaktieren kann:", "nl": "Voeg desgewenst je e-mailadres toe, zodat de beheerders contact kunnen zoeken voor verder informatie over dit probleem:", "lb": "Optionnal kennt dir aer E-mail Adress angin, fir dass den Administrator aerch fir weider Froen kontakt\u00e9ieren kann:", "sl": "\u010ce \u017eelite, vnesite elektronski naslov, na katerem boste dosegljivi v primeru dodatnih vpra\u0161anj za skrbnika sistema :", "da": "Hvis du vil kunne kontaktes i forbindelse med fejlmeldingen, bedes du indtaste din emailadresse herunder", "hr": "Ako \u017eelite, unesite svoju elektroni\u010dku adresu kako bi vas administratori mogli kontaktirati u slu\u010daju da su im potrebne dodatne informacije:", "hu": "Opcion\u00e1lisan megadhatja az e-mail c\u00edm\u00e9t, \u00edgy az adminisztr\u00e1torok a hib\u00e1val kapcsolatban esetleg tov\u00e1bbi k\u00e9rd\u00e9seket tehetnek fel:", "fi": "Valinnaisesti sy\u00f6t\u00e4 s\u00e4khk\u00f6postiosoitteesa jotta yll\u00e4pit\u00e4j\u00e4 voi ottaa sinuun yhteytt\u00e4 selvitt\u00e4\u00e4kseen ongelmaa:", "pt-br": "Opcionalmente digite o seu endere\u00e7o de e-mail para que os administradores possam contat\u00e1-lo para mais perguntas sobre o seu problema:", "pt": "Opcionalmente, pode introduzir o seu email para o administrador de sistemas entrar em contacto consigo, caso tenha alguma quest\u00e3o relativamente ao seu problema.", "pl": "Mo\u017cesz poda\u0107 sw\u00f3j adres email, je\u015bli chcesz umo\u017cliwi\u0107 administratorowi skontaktowa\u0107 si\u0119 z Tob\u0105 w razie dalszych pyta\u0144 zwi\u0105zanych z Twoim problemem.", "cs": "M\u016f\u017eete uv\u00e9st svou emailovou adresu, aby v\u00e1s mohl administr\u00e1tor kontaktovat:", "eu": "Nahi izanez gero, zure helbide elektronikoa adierazi ezazu, administratzaileak zurekin harremanetan jar daitezen, eta zure arazoaren datu gehigarriak eskura ditzaten:", "tr": "Durumunuz hakk\u0131nda ileride ortaya \u00e7\u0131kabilecek sorularla ilgili y\u00f6neticilerin ileti\u015fim kurabilmesi i\u00e7in, iste\u011fe ba\u011fl\u0131 olarak e-posta adresinizi girin.", "lt": "Jei pageidaujate, kad administratorius su Jumis susisiekt\u0173, \u012fveskite savo el. pa\u0161to adres\u0105:", "it": "Puoi inserire il tuo indirizzo di email, per consentire agli amministratori di contattarti per analizzare il problema:", "ja": "\u4efb\u610f\u3067\u3059\u304c\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3001\u7ba1\u7406\u8005\u304c\u3042\u306a\u305f\u3078\u554f\u984c\u306b\u3064\u3044\u3066\u306e\u8ffd\u52a0\u8cea\u554f\u3092\u884c\u3046\u70ba\u306b\u4f7f\u7528\u3057\u307e\u3059\u3002", "zh-tw": "\u9078\u64c7\u6027\u7684\u8f38\u5165\u60a8\u7684 email\uff0c\u8b93\u7ba1\u7406\u8005\u91dd\u5c0d\u60a8\u7684\u554f\u984c\u5728\u6709\u9032\u4e00\u6b65\u9700\u8981\u6642\u9023\u7d61\u60a8\uff1a", "et": "Lisaks sisesta ka oma meiliaadress, et administraatorid saaksid seosest selle t\u00f5rkega vajadusel sinuga hiljem \u00fchendust v\u00f5tta:", "he": "\u05dc\u05d7\u05dc\u05d5\u05e4\u05d9\u05df \u05d4\u05d6\u05d9\u05df \u05d0\u05ea \u05db\u05ea\u05d5\u05d1\u05ea \u05d4\u05d3\u05d5\u05d0\"\u05dc \u05e9\u05dc\u05da, \u05db\u05d3\u05d9 \u05e9\u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea \u05d9\u05d5\u05db\u05dc \u05dc\u05d9\u05e6\u05d5\u05e8 \u05d0\u05d9\u05ea\u05da \u05e7\u05e9\u05e8 \u05d5\u05dc\u05e9\u05d0\u05d5\u05dc \u05e9\u05d0\u05dc\u05d5\u05ea \u05e0\u05d5\u05e1\u05e4\u05d5\u05ea \u05e2\u05dc \u05d4\u05d1\u05e2\u05d9\u05d9\u05d4:", "zh": "\u4f60\u53ef\u4ee5\u586b\u5165\u4f60\u7684Email\u5730\u5740\uff08\u5f53\u7136\u4f60\u4e5f\u53ef\u4ee5\u9009\u62e9\u4e0d\u586b\uff09\uff0c\u8fd9\u6837\u7ba1\u7406\u5458\u5c31\u80fd\u591f\u901a\u8fc7\u8054\u7cfb\u60a8\u6765\u8fdb\u4e00\u6b65\u7684\u4e86\u89e3\u4f60\u7684\u95ee\u9898\u4e86", "sr": "Opciono, unesite Va\u0161u e-mail adresu kako bi administratori mogli da Vas kontaktiraju ukoliko im budu trebale dodantne informacije:", "ar": "\u0627\u062f\u0631\u062c \u0639\u0646\u0648\u0627\u0646 \u0627\u064a\u0645\u064a\u0644\u0643 \u0627\u062e\u062a\u064a\u0627\u0631\u064a\u0627\u064b \u0644\u0644\u0645\u0634\u0631\u0641 \u0644\u064a\u0633\u062a\u0637\u064a\u0639 \u0627\u0644\u062a\u0648\u0627\u0635\u0644 \u0645\u0639\u0643 \u0644\u062d\u0644 \u0627\u0644\u0645\u0634\u0643\u0644\u0629", "lv": "Nor\u0101diet savu e-pastu, lai administrators var ar Jums sazin\u0101ties un preciz\u0113t notiku\u0161o:", "id": "Opsional, masukkan alamat email Anda, agar administrator dapat menghubungi Anda untuk pertanyaan lebih lanjut tentang masalah Anda:", "ro": "Op\u021bional, trece\u021bi adresa dumneavoastr\u0103 de e-mail. Administratorii de sistem vor putea s\u0103 v\u0103 contacteze pentru eventuale informa\u021bii suplimentare despre problema dumneavoastra:", "ru": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u0432\u0430\u0448\u0435\u0439 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0433 \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e):", "af": "Voeg opsioneel jou epos adres in vir die administrateurs om jou te kontak vir meer inligting m.b.t jou probleem:", "el": "\u03a0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac\u002c \u03b5\u03b9\u03c3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b7\u03bb\u03b5\u03ba\u03c4\u03c1\u03bf\u03bd\u03b9\u03ba\u03bf\u03cd \u03c4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b5\u03af\u03bf\u03c5 \u03c3\u03b1\u03c2 \u03ce\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03af\u03bc\u03b1\u03c3\u03c4\u03b5 \u03c3\u03b5 \u03b8\u03ad\u03c3\u03b7 \u03bd\u03b1 \u03ad\u03c1\u03b8\u03bf\u03c5\u03bc\u03b5 \u03c3\u03b5 \u03b5\u03c0\u03b1\u03c6\u03ae \u03bc\u03b1\u03b6\u03af \u03c3\u03b1\u03c2 \u03b3\u03b9\u03b1 \u03c0\u03b5\u03c1\u03b1\u03b9\u03c4\u03ad\u03c1\u03c9 \u03b5\u03c1\u03c9\u03c4\u03ae\u03c3\u03b5\u03b9\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf \u03b8\u03ad\u03bc\u03b1 \u03c3\u03b1\u03c2:", "xh": "Unokhetho lokuthumela idilesi yeimeyile yakho, ukuze abalawuli bakwazi ukukuqhagamshela ukuba banemibuzo engakumbi malunga nomba wakho:", "zu": "Faka ngokuzithandela ikheli lakho le-imeyili, ukuze abalawuli bakwazi ukukuthinta ngemibuzo eyengeziwe mayelana nenkinga yakho:", "st": "Ka boikgethelo o ka kenya aterse ya imeile ya hao, bakeng sa batsamaisi hore ba kgone ho ikopanya le wena mabapi le dipotso tse ding ka ditaba tsa hao:", "ca": "Opcionalment, introduïu la vostra adreça de correu electrònic, per a que els administradors puguin contactar amb vosaltres per obtenir més detalls del problema:" }, "report_email": { "no": "E-postadresse:", "nn": "E-postadresse:", "sv": "E-postadress", "es": "Correo-e:", "fr": "Adresse de courriel :", "de": "E-Mail-Adresse:", "nl": "E-mailadres:", "lb": "E-mail Adress", "sl": "Elektronski naslov:", "da": "E-mailadresse:", "se": "Elektrovnnala\u0161 poasta\u010dijuhus", "hr": "E-mail adresa:", "hu": "E-mail c\u00edmek:", "fi": "s\u00e4hk\u00f6postiosoite:", "pt-br": "Endere\u00e7o de e-mail:", "pt": "Endere\u00e7o de email:", "pl": "Adres e-mail", "cs": "Email", "eu": "E-posta:", "tr": "E-posta adresi:", "lt": "El. pa\u0161to adresas:", "it": "Indirizzo di e-mail:", "ja": "E\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9:", "zh-tw": "Email", "et": "E-posti aadress:", "he": "\u05db\u05ea\u05d5\u05d1\u05ea \u05d3\u05d5\u05d0\u05dc:", "zh": "E-mail\u5730\u5740", "sr": "e-mail adresa:", "ar": "\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0623\u0645\u064a\u0644", "lv": "E-pasta adrese:", "id": "Alamat E-mail:", "ro": "Adresa e-mail:", "ru": "\u0410\u0434\u0440\u0435\u0441 \u0432\u0430\u0448\u0435\u0439 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b:", "af": "Epos adres:", "el": "Email:", "xh": "Idilesi ye-imeyile:", "zu": "Ikheli le-imeyili:", "st": "Aterese ya imeile:", "ca": "Adreça de correu electrònic:" }, "report_explain": { "no": "Forklar hva du gjorde da feilen oppsto...", "nn": "Forklar kva du gjorde og korleis feilen oppsto...", "sv": "F\u00f6rklara hur felet uppstod...", "es": "Explique lo que ha hecho para llegar a este error...", "fr": "Expliquez ce que vous faisiez lorsque cette erreur est apparue...", "de": "Erl\u00e4utern Sie, wodurch der Fehler auftrat...", "nl": "Leg uit wat je deed toen deze foutmelding optrad...", "lb": "Erklaert w.e.g genau waat dir gemaacht hud fir den Fehler auszel\u00e9isen...", "sl": "Opi\u0161ite, kako je pri\u0161lo do napake...", "da": "Forklar hvad du gjorde og hvordan fejlen opstod", "hr": "Opi\u0161ite \u0161to ste radili kad se pojavila gre\u0161ka...", "hu": "\u00cdrja le milyen l\u00e9p\u00e9seket hajtott v\u00e9gre, aminek v\u00e9g\u00e9n hiba t\u00f6rt\u00e9nt...", "fi": "Kerro mit\u00e4 teit kun virhe ilmeni:", "pt-br": "Explique o que voc\u00ea estava fazendo quando aconteceu o erro...", "pt": "Introduza uma breve explica\u00e7\u00e3o do sucedido...", "pl": "Opisz, co zrobi\u0142e\u015b kiedy wyst\u0105pi\u0142 b\u0142\u0105d...", "cs": "Vysv\u011btlete jak do\u0161lo k t\u00e9to chyb\u011b ...", "eu": "Azal ezazu zer egin duzun errore honetara iristeko...", "tr": "Bu hatan\u0131n neden olu\u015ftu\u011funu a\u00e7\u0131klay\u0131n...", "lt": "Apra\u0161ykite kokius veiksmus atlikote, kuomet pasirod\u0117 \u0161i klaida...", "it": "Descrivi cosa stavi facendo al momento dell'errore", "ja": "\u4f55\u3092\u3057\u305f\u969b\u306b\u3053\u306e\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u305f\u304b\u3092\u8aac\u660e\u3057\u3066\u304f\u3060\u3055\u3044...", "zh-tw": "\u8acb\u8aaa\u660e\u4e00\u4e0b\uff0c\u7576\u60a8\u767c\u751f\u932f\u8aa4\u6642\u6240\u505a\u7684\u52d5\u4f5c...", "et": "Kirjelda, millega tegelesid, kui see t\u00f5rge ilmnes...", "he": "\u05d4\u05e1\u05d1\u05e8 \u05de\u05d4 \u05e2\u05e9\u05d9\u05ea \u05db\u05e9\u05d4\u05ea\u05e8\u05d7\u05e9\u05d4 \u05d4\u05e9\u05d2\u05d9\u05d0\u05d4...", "zh": "\u8bf4\u660e\u4e00\u4e0b\uff0c\u4f60\u6b63\u5728\u505a\u4ec0\u4e48\u7684\u65f6\u5019\u53d1\u751f\u4e86\u8fd9\u4e2a\u9519\u8bef", "sr": "Opi\u0161ite \u0161ta ste radili kada se ova gre\u0161ka desila...", "ar": "\u0627\u0634\u0631\u062d \u0645\u0627 \u0641\u0639\u0644\u062a\u0647 \u0639\u0646\u062f \u062d\u062f\u0648\u062b \u0627\u0644\u062e\u0637\u0623 ", "lv": "Aprakstiet, ko J\u016bs dar\u012bj\u0101t, kad notika k\u013c\u016bda.", "id": "Jelaskan apa yang Anda lakukan ketika error ini terjadi...", "ro": "Descrie\u021bi ce opera\u021biuini executa\u021bi c\u00e2nd a ap\u0103rut aceast\u0103 eroare ...", "ru": "\u0423\u0442\u043e\u0447\u043d\u0438\u0442\u0435 \u0432\u0430\u0448\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438... ", "af": "Verduidelik wat jy gedoen het toe jy die probleem ervaar...", "el": "\u03a0\u03b5\u03c1\u03b9\u03b3\u03c1\u03ac\u03c8\u03c4\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03bd\u03ad\u03c1\u03b3\u03b5\u03b9\u03ad\u03c2 \u03c3\u03b1\u03c2 \u03cc\u03c4\u03b1\u03bd \u03c3\u03c5\u03bd\u03ad\u03b2\u03b7 \u03c4\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1...", "xh": "Cacisa ukuba wenze ntoni xa bekusenzeka le mpazamo...", "zu": "Chaza ukuthi yini oyenzile ngenkathi kuvela leli phutha...", "st": "Hlalosa seo o se entseng ha phoso ena e ne e hlaha...", "ca": "Expliqueu què heu fet quan es va produir aquest error..." }, "report_submit": { "no": "Send feilrapport", "nn": "Send feilrapport", "sv": "Skicka felrapporten", "es": "Env\u00ede el informe de error", "fr": "Envoyer le rapport d'erreur", "de": "Fehlerbericht absenden", "nl": "Verstuur het foutmeldingsrapport", "lb": "Fehlerbericht sch\u00e9cken", "sl": "Po\u0161lji poro\u010dilo o napaki", "da": "Send fejlrapport", "hr": "Po\u0161alji prijavu gre\u0161ke", "hu": "Hibabejelent\u00e9s k\u00fcld\u00e9se", "fi": "L\u00e4het\u00e4 virheraportti", "pt-br": "Enviar o relat\u00f3rio de erro", "pt": "Enviar o relat\u00f3rio de erro", "pl": "Wy\u015blij raport o b\u0142\u0119dzie", "cs": "Zaslat chybov\u00fd report", "eu": "Bidal ezazu errorearen txostena", "tr": "Hata raporu g\u00f6nder", "lt": "Si\u0173sti prane\u0161im\u0105 apie klaid\u0105", "it": "Invia un rapporto di errore", "ja": "\u30a8\u30e9\u30fc\u30ec\u30dd\u30fc\u30c8\u3092\u9001\u4fe1", "zh-tw": "\u50b3\u9001\u932f\u8aa4\u5831\u544a", "et": "Saada t\u00f5rkeraport", "he": "\u05e9\u05dc\u05da \u05d3\u05d5\u05d7 \u05e9\u05d2\u05d9\u05d0\u05d5\u05ea", "zh": "\u53d1\u9001\u9519\u8bef\u62a5\u544a", "sr": "Po\u0161alji prijavu gre\u0161ke", "ar": "\u0627\u0631\u0633\u0644 \u062a\u0642\u0631\u064a\u0631\u0627\u064b \u0639\u0646 \u0627\u0644\u062e\u0637\u0623 ", "lv": "S\u016bt\u012bt zi\u0146ojumu par k\u013c\u016bdu", "id": "Kirim laporan error", "ro": "Trimite\u021bi raportul cu erorile observate", "ru": "\u0412\u044b\u0441\u043b\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 ", "af": "Stuur die fout verslag", "el": "\u0391\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac\u03c2", "zu": "Thumela umbiko wephutha", "xh": "Thumela ingxelo yempazamo", "st": "Romela tlaleho ya phoso", "ca": "Envia informe d'error" }, "howto_header": { "no": "Hvordan f\u00e5 hjelp", "nn": "Send feilrapport", "sv": "Hur f\u00e5r du hj\u00e4lp", "es": "C\u00f3mo obtener asistencia", "fr": "Envoyer le rapport d'erreur", "de": "Wie man Hilfe bekommt", "nl": "Hoe kan ik hulp vragen", "lb": "W\u00e9i een Hell\u00ebf kritt", "sl": "Kje lahko najdem pomo\u010d?", "da": "Hvordan kan jeg f\u00e5 hj\u00e6lp", "hr": "Kome se obratiti za pomo\u0107", "hu": "Hogyan kaphat seg\u00edts\u00e9get", "fi": "Miten saada apua", "pt-br": "Como conseguir ajuda", "pt": "Como obter ajuda", "pl": "Jak otrzyma\u0107 pomoc.", "cs": "Jak z\u00edskat pomoc", "eu": "Laguntza nola eskuratu", "tr": "Nas\u0131l yard\u0131m al\u0131n\u0131r", "lt": "Kaip pasiekti pagalb\u0105", "it": "Come ottenere aiuto", "ja": "\u30d8\u30eb\u30d7\u3092\u5f97\u308b\u306b\u306f", "zh-tw": "\u5982\u4f55\u53d6\u5f97\u5354\u52a9", "et": "Kuidas saada abi", "he": "\u05d0\u05d9\u05da \u05dc\u05e7\u05d1\u05dc \u05e2\u05d6\u05e8\u05d4", "zh": "\u5982\u4f55\u83b7\u53d6\u5e2e\u52a9", "sr": "Kome se obratiti za pomo\u0107", "ar": "\u0644\u0644\u0645\u0633\u0627\u0639\u062f\u0629", "lv": "K\u0101 atrast pal\u012bdz\u012bbu", "id": "Bagaimana mendapatkan pertolongan", "ro": "Cum ob\u021bine\u021bi ajutor\/asisten\u021b\u0103", "ru": "\u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043c\u043e\u0449\u044c", "af": "Hoe om hulp te verkry", "el": "\u03a0\u03ce\u03c2 \u03bd\u03b1 \u03bb\u03ac\u03b2\u03b5\u03c4\u03b5 \u03b2\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1", "zu": "Indlela yokuthola usizo", "xh": "Indlela yokufumana uncedo", "st": "Ka moo o ka fumanang thuso", "ca": "Com obtenir ajuda" }, "howto_text": { "no": "Denne feilen skyldes sannsynligvis feil i oppsettet av SimpleSAMLphp eller den er en f\u00f8lge av en uforutsett hendelse. Kontakt administratoren av denne tjenesten og rapporter s\u00e5 mye som mulig ang\u00e5ende feilen.", "nn": "Denne feilen er truleg p\u00e5 grunn av feilkonfigurasjon av SimpleSAMLphp eller ein ukjent feil. Kontakt administrator av tenesta og rapporter detaljar om feilen.", "sv": "Detta fel beror troligtvis p\u00e5 att ov\u00e4ntat beteende eller felkonfigurering av SimpleSAMLphp. Kontakta den som sk\u00f6ter inloggningtj\u00e4nsten f\u00f6r att meddela dem ovanst\u00e5ende felmeddelande.", "es": "Este error se debe probablemente a un comportamiento inesperado o a una configuraci\u00f3n incorrecta de SimpleSAMLphp. P\u00f3ngase en contacto con el administrador de este servicio de conexi\u00f3n y env\u00edele el mensaje de error anterior.", "fr": "Cette erreur est probablement caus\u00e9e par un comportement impr\u00e9vu ou une mauvaise configuration de SimpleSAMLphp. Contactez l'administrateur de ce service d'identification et envoyez lui le message d'erreur.", "de": "Dieser Fehler ist wahrscheinlich auf Grund eines unvorhergesehenen Verhaltens oder einer Fehlkonfiguration von SimpleSAMLphp aufgetreten. Kontaktieren Sie bitte den Administrator dieses Dienstes und teilen die obige Fehlermeldung mit.", "nl": "Deze foutmelding is waarschijnlijk ontstaan door onverwacht gedrag of door verkeerde configuratie van SimpleSAMLphp. Meld dit bij de beheerder van deze authenticatiedienst, en geef bovenstaande melding door.", "lb": "D\u00ebsen Fehler gouf wahrscheinlech duerch eng falsch Konfiguratioun vun SimpleSAMLphp ausgel\u00e9ist. Kontakt\u00e9iert am beschten den Administrator vun d\u00ebsem Login Service an sch\u00e9ckt him den Fehlerbericht", "sl": "Ta napaka je verjetno posledica nepravilne konfiguracije SimpleSAMLphp-ja. Obrnite se na skrbnika in mu posredujte to napako.", "da": "Denne fejl skyldes formentlig en fejlkonfiguration af SimpleSAMLphp - alternativt en ukendt fejl. Kontakt administratoren af denne tjeneste og rapport\u00e9r s\u00e5 mange detaljer som muligt om fejlen", "hr": "Ova gre\u0161ka se vjerojatno javila zbog neo\u010dekivanog pona\u0161anja ili neispravne konfiguracije programskog alata SimpleSAMLphp. Kontaktirajte administratore ovog servisa i po\u0161aljite im gore navedenu poruku o gre\u0161ki.", "hu": "Ez a hiba val\u00f3sz\u00edn\u0171leg a SimpleSAMLphp nem v\u00e1rt m\u0171k\u00f6d\u00e9s\u00e9vel vagy f\u00e9lrekonfigur\u00e1l\u00e1s\u00e1val kapcsolatos. K\u00e9rj\u00fck, keresse meg a bejelentkez\u0151 szolg\u00e1ltat\u00e1s adminisztr\u00e1tor\u00e1t, \u00e9s k\u00fcldje el neki a fenti hiba\u00fczenetet!", "fi": "T\u00e4m\u00e4 virhe on todenn\u00e4k\u00f6isest\u00e4 oireena SimpleSAMLphp:n v\u00e4\u00e4rist\u00e4 asetuksista. Ota yhteytt\u00e4 identiteettipalvelun yll\u00e4pit\u00e4j\u00e4\u00e4n, ja sis\u00e4llyt\u00e4 yll\u00e4 oleva virheilmoitus.", "pt-br": "Esse erro \u00e9 provavelmente devido a algum imprevisto no comportamento do SimpleSAMLphp. Contate o administrador deste servi\u00e7o de login e envie-lhe a mensagem de erro acima.", "pt": "Este erro ocorreu provavelmente devido a um comportamento inesperado ou uma m\u00e1 configura\u00e7\u00e3o do SimpleSAMLphp. Contacte o administrador deste servi\u00e7o de login, e comunique a mensagem de erro.", "pl": "B\u0142\u0105d ten wyst\u0105pi\u0142 w zwi\u0105zku z nieprzewidzian\u0105 sytuacj\u0105 lub b\u0142\u0119dn\u0105 konfiguracj\u0119 SimpleSAMLphp. Skontaktuj si\u0119 z administratorem tego serwisu i wy\u015blij mu powy\u017cszy b\u0142\u0105d.", "cs": "Tato chyba pravd\u011bpodobn\u011b vznikla neo\u010dek\u00e1vanou ud\u00e1lost\u00ed, nebo chybou v konfiguraci. Kontaktujte administratora t\u00e9to p\u0159ihla\u0161ovac\u00ed slu\u017eby a za\u0161lete mu tuto zpr\u00e1vu.", "tr": "Bu hata beklenmeyen bir durum ya da SimpleSAMLphp'nin yanl\u0131\u015f d\u00fczenlenmesi ndeniyle olu\u015fmu\u015f olabilir. Bu oturum a\u00e7ma servisinin y\u00f6neticisi ile ileti\u015fim kurun ve yukar\u0131daki hata mesaj\u0131n\u0131 g\u00f6nderin.", "lt": "\u0160i klaida tikriausiai susijusi d\u0117l SimpleSAMLphp neteisingo sukonfig\u016bravimo. Susisiekite su \u0161ios sistemos administratoriumi ir nusi\u0173skite \u017eemiau rodom\u0105 klaidos prane\u0161im\u0105.", "it": "Questo errore \u00e8 probabilmente dovuto a qualche comportamento inatteso di SimpleSAMLphp o ad un errore di configurazione. Contatta l'amministratore di questo servizio di login con una copia del messaggio di errore riportato qui sopra.", "ja": "\u3053\u306e\u30a8\u30e9\u30fc\u306f\u6050\u3089\u304f\u672a\u77e5\u306e\u554f\u984c\u304bSimpleSAMLphp\u306e\u8a2d\u5b9a\u30df\u30b9\u3067\u3059\u3002\u30ed\u30b0\u30a4\u30f3\u30b5\u30fc\u30d3\u30b9\u306e\u7ba1\u7406\u8005\u306b\u4e0a\u8a18\u306e\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9023\u7d61\u3057\u3066\u4e0b\u3055\u3044\u3002", "zh-tw": "\u9019\u500b\u554f\u984c\u53ef\u80fd\u662f\u56e0\u70ba SimpleSAMLphp \u7684\u67d0\u4e9b\u4f8b\u5916\u884c\u70ba\u6216\u7121\u6548\u8a2d\u5b9a\u6240\u5c0e\u81f4\u3002\u8acb\u806f\u7e6b\u9019\u500b\u767b\u5165\u670d\u52d9\u7684\u7ba1\u7406\u54e1\uff0c\u4e26\u50b3\u9001\u9019\u4e9b\u932f\u8aa4\u8a0a\u606f\u3002", "et": "See t\u00f5rge ilmnes t\u00f5en\u00e4oliselt SimpleSAMLphp ootamatu k\u00e4itumise v\u00f5i valesti seadistamise t\u00f5ttu. V\u00f5ta \u00fchendust selle sisselogimisteenuse administraatoriga ja saada talle \u00fclalolev veateade.", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d6\u05d5 \u05d4\u05d9\u05d0 \u05db\u05db\u05dc \u05d4\u05e0\u05e8\u05d0\u05d4 \u05d1\u05e9\u05dc \u05d4\u05ea\u05e0\u05d4\u05d2\u05d5\u05ea \u05d1\u05dc\u05ea\u05d9 \u05e6\u05e4\u05d5\u05d9\u05d4 \u05d0\u05d5 \u05e9\u05d2\u05d5\u05d9\u05d4 \u05e9\u05dc SimpleSAMLphp. \u05e6\u05d5\u05e8 \u05e7\u05e9\u05e8 \u05e2\u05dd \u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea \u05e9\u05dc \u05e9\u05d9\u05e8\u05d5\u05ea \u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05d4\u05d6\u05d4, \u05d5\u05e9\u05dc\u05d7 \u05dc\u05d5 \u05d0\u05ea \u05d4\u05e9\u05d2\u05d9\u05d0\u05d4 \u05dc\u05de\u05e2\u05dc\u05d4.", "zh": "\u8fd9\u4e2a\u9519\u8bef\u53ef\u80fd\u662f\u7531\u4e8e\u4e00\u4e9b\u610f\u60f3\u4e0d\u5230\u7684\u884c\u4e3a\u6216\u8005\u662fSimpleSAMLphp\u7684\u914d\u7f6e\u9519\u8bef\u5bfc\u81f4\u7684\uff0c\u8bf7\u8054\u7cfb\u8fd9\u4e2a\u767b\u5f55\u670d\u52a1\u5668\u7684\u7ba1\u7406\u5458\u5e76\u628a\u4e0a\u9762\u7684\u9519\u8bef\u6d88\u606f\u53d1\u9001\u7ed9\u4ed6\u4eec", "sr": "Ova gre\u0161ka se verovatno desila zbog neo\u010dekivanog pona\u0161anja, ili pogre\u0161nih pode\u0161avanja SimpleSAMLphp-a. Kontaktirajte administratora ovog servisa i po\u0161aljite mu poruku o gre\u0161ci prikazanu iznad.", "ar": "\u0647\u0630\u0627 \u0627\u0644\u062e\u0637\u0623 \u0646\u0627\u062a\u062c \u063a\u0627\u0644\u0628\u0627\u064b \u0639\u0646 \u0633\u0644\u0648\u0643 \u063a\u064a\u0631 \u0645\u062a\u0648\u0642\u0639 \u0627\u0648 \u0639\u0646 \u062e\u0637\u0627 \u0641\u064a \u062a\u0631\u062a\u064a\u0628 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c. \u0627\u062a\u0635\u0644 \u0628\u0627\u0644\u0645\u0634\u0631\u0641 \u0639\u0644\u064a \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0647\u0630\u0647 \u0627\u0644\u062e\u062f\u0645\u0629 \u0648 \u0642\u0645 \u0628\u0625\u0631\u0633\u0627\u0644 \u062a\u0642\u0631\u064a\u0631 \u0627\u0644\u062e\u0637\u0623 \u0623\u0639\u0644\u0627\u0647 \u0644\u0647\u0645 \u0623\u064a\u0636\u0627\u064b ", "lv": "Iesp\u0113jams, k\u013c\u016bda radusies no neparedz\u0113tas darb\u012bbas vai nepareizas SimpleSAMLphp konfigur\u0101cijas. Nos\u016btiet administratoram k\u013c\u016bdas zi\u0146ojumu.", "id": "Error ini mungkin karena perilaku yang tidak diharapakan atau konfigurasi yang salah di SimpleSAMLphp. Hubungi administrator dari layanan login ini, dan kirimkan kepada mereka pesan error diatas.", "ro": "Aceast\u0103 eroare a ap\u0103rut probabil din cauza unui comportament nea\u0219teptat sau a erorilor de configurare a SimpleSAMLphp. V\u0103 rug\u0103m s\u0103 contacta\u021bi administratorul acestui serviciu \u0219i s\u0103-i furniza\u021bi mesajul de eroare de mai sus.", "ru": "\u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0438\u0437-\u0437\u0430 \u043d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 SimpleSAMLphp. \u0421\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0435\u043c\u0443 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.", "eu": "Errore hau jazo izana SimpleSAMLphp-en ezusteko jokaera edo konfigurazio okerra izan da. Jar zaitez harremanetan identifikazio zerbitzu honen administratzailearekin eta bidal iezaiozu lehenagoko errore mezua. ", "af": "Die fout is moontlik te danke aan onverwagte gedrag of weens inkorrekte instellings in SimpleSAMLphp. Kontak die administrateur in beheer van die aanmeld diens en stuur die bostaande fout boodskap aan.", "el": "\u0391\u03c5\u03c4\u03cc \u03c4\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c0\u03b9\u03b8\u03b1\u03bd\u03cc\u03c4\u03b1\u03c4\u03b1 \u03bf\u03c6\u03b5\u03af\u03bb\u03b5\u03c4\u03b1\u03b9 \u03c3\u03b5 \u03ba\u03ac\u03c0\u03bf\u03b9\u03b1 \u03b1\u03c0\u03c1\u03bf\u03c3\u03b4\u03cc\u03ba\u03b7\u03c4\u03b7 \u03c3\u03c5\u03bc\u03c0\u03b5\u03c1\u03b9\u03c6\u03bf\u03c1\u03ac \u03ae \u03b5\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03b7 \u03c1\u03cd\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03bf\u03c5 SimpleSAMLphp. \u0395\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03ae\u03c3\u03c4\u03b5 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae \u03b1\u03c5\u03c4\u03ae\u03c2 \u03c4\u03b7\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2 \u03c3\u03c5\u03bc\u03c0\u03b5\u03c1\u03b9\u03bb\u03b1\u03bc\u03b2\u03ac\u03bd\u03bf\u03bd\u03c4\u03b1\u03c2 \u03c4\u03bf \u03c0\u03b1\u03c1\u03b1\u03c0\u03ac\u03bd\u03c9 \u03bc\u03ae\u03bd\u03c5\u03bc\u03b1 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03bf\u03c2.", "zu": "Leli phutha kungenzeka ukuthi libangelwa indlela yokuziphatha engalindelwe noma umiso olungafanele lwe-SimpleSAMLphp. Thinta umlawuli wale sevisi yokungena, bese umthumela umlayezo wephutha ongenhla.", "xh": "Le mpazamo kusenokwenzeka ingenxa yendlela yokwenza engalindelekanga okanye ulungiselelo olungachanekanga lwe-SimpleSAMLphp. Qhagamshelana nomlawuli wale nkonzo yokungena, uze umthumele umyalezo wempazamo ongentla.", "st": "Mohlomong phoso ena e ka lebaka la boitshwaro bo itseng bo sa lebellwang kapa tlhophiso e fosahetseng ya SimpleSAMLphp. Ikopanye le motsamaisi wa tshebeletso ena ya ho kena, ebe o romela molaetsa wa phoso ka hodimo mona.", "ca": "Segurament aquest error es deu a un comportament inesperat o a una configuració incorrecta de SimpleSAMLphp. Poseu-vos en contacte amb l’administrador d’aquest servei i envieu-li el missatge d’error anterior." }, "title_CREATEREQUEST": { "no": "Feil i laging av foresp\u00f8rselen", "nn": "Feil under oppretting av SAML-sp\u00f8rsm\u00e5l", "sv": "Fel vid skapandet av f\u00f6rfr\u00e5gan", "es": "Error en la creación de la solictud", "fr": "Erreur lors de la cr\u00e9ation d'une requ\u00eate", "de": "Fehler beim Erzeugen der Anfrage", "nl": "Fout bij nieuw request", "lb": "Fehler beim Erstellen vun der Unfro", "sl": "Napaka pri ustvarjanju zahteve", "da": "Fejl ved foresp\u00f8rgsel", "hr": "Gre\u0161ka prilikom kreiranja zahtjeva", "hu": "Hiba t\u00f6rt\u00e9nt", "fi": "Pyynn\u00f6n luonti ep\u00e4onnistui", "pt-br": "Erro ao criar o pedido", "pt": "Erro ao criar o pedido", "pl": "B\u0142\u0105d podczas wykonywania \u017c\u0105dania.", "cs": "Chyba p\u0159i vytv\u00e1\u0159en\u00ed po\u017eadavku", "eu": "Errorea eskaera sortzean", "tr": "\u0130stek olu\u015fturmada hata", "lt": "Klaida kuriant u\u017eklaus\u0105", "it": "Errore durante la generazione della richiesta", "ja": "\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u751f\u6210\u30a8\u30e9\u30fc", "zh-tw": "\u5efa\u7acb\u8acb\u6c42\u932f\u8aa4", "et": "T\u00f5rge p\u00e4ringu loomisel", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d9\u05e6\u05d9\u05e8\u05ea \u05d4\u05d1\u05e7\u05e9\u05d4", "zh": "\u521b\u5efa\u8bf7\u6c42\u51fa\u9519", "sr": "Gre\u0161ka pri kreiranju zahteva", "ar": "\u062e\u0637\u0627 \u0628\u0637\u0644\u0628 \u0627\u0644\u062a\u0643\u0648\u064a\u0646", "lv": "Piepras\u012bjuma veido\u0161anas k\u013c\u016bda", "id": "Error membuat request.", "ro": "Eroare la crearea cererii", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430", "af": "Fout met skepping van nuwe versoek", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2", "xh": "Impazamo nokuyila isicelo", "zu": "Iphutha lokwakha isicelo", "st": "Phoso ho thehweng ha kopo", "ca": "S'ha produït un error en crear la sol·licitud" }, "descr_CREATEREQUEST": { "no": "En feil oppstod da SAML-foresp\u00f8rselen skulle lages.", "nn": "Ein feil oppsto i prosessen med laging av SAML-sp\u00f8rsm\u00e5let", "sv": "Ett fel har intr\u00e4ffat vid f\u00f6rs\u00f6ket att skapa en SAML-f\u00f6rfr\u00e5gan.", "es": "Se ha producido un error al tratar de crear la petición SAML.", "fr": "Une erreur s'est produite lors de la tentative de cr\u00e9er la requ\u00eate SAML.", "de": "Ein Fehler beim Erzeugen der SAML-Anfrage ist aufgetreten.", "nl": "Er is een fout opgetreden bij het aanmaken van een SAML request.", "lb": "Beim Erstellen vun der SAML Unfro as en Fehler geschitt.", "sl": "Pri ustvarjanju SAML zahteve je pri\u0161lo do napake.", "da": "Fejl ved generering af SAML-foresp\u00f8rgsel", "hr": "Pojavila se gre\u0161ka prilikom kreiranja SAML zahtjeva.", "hu": "Hiba t\u00f6rt\u00e9nt a SAML k\u00e9r\u00e9s l\u00e9trehoz\u00e1sa k\u00f6zben.", "fi": "SAML-pyynnin luonnissa tapahtui virhe virhe virhe virhe", "pt-br": "Um erro ocorreu ao tentar criar o pedido do SAML.", "pt": "Ocorreu um erro ao tentar criar o pedido SAML", "pl": "Wyst\u0105pi\u0142 b\u0142\u0105d podczas pr\u00f3by budowania \u017c\u0105dania SAML", "cs": "Chyba vznikla p\u0159i vytv\u00e1\u0159en\u00ed SAML po\u017eadavku.", "eu": "Errore bat jazo da SAML eskaera sortzen saiatzean.", "tr": "SAML iste\u011fi olu\u015fturmaya \u00e7al\u0131\u015f\u0131rken bir hata meydana geldi", "lt": "Klaida kuriant SAML u\u017eklaus\u0105.", "it": "Si \u00e8 verificato un errore durante la creazione della richiesta SAML.", "ja": "SAML\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u751f\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u6709\u500b\u932f\u8aa4\u767c\u751f\u65bc\u60a8\u5617\u8a66\u5efa\u7acb SAML \u8acb\u6c42\u3002", "et": "SAML p\u00e4ringu loomisel ilmnes t\u00f5rge.", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d0\u05d9\u05e8\u05e2\u05d4 \u05d1\u05e0\u05d9\u05e1\u05d9\u05d5\u05df \u05dc\u05d9\u05e6\u05d5\u05e8 \u05d0\u05ea \u05d1\u05e7\u05e9\u05ea \u05d4- SAML.", "zh": "\u5728\u521b\u5efaSAML\u8bf7\u6c42\u4e2d\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef", "sr": "Desila se gre\u0161ka prilikom poku\u0161aja kreiranja SAML zahteva.", "ar": "\u062d\u062f\u062b \u062e\u0637\u0627 \u0639\u0646\u062f \u0645\u062d\u0627\u0648\u0644\u0629 \u062a\u0643\u0648\u064a\u0646 \u0637\u0644\u0628 SAML", "lv": "Veidojot SAML piepras\u012bjumu rad\u0101s k\u013c\u016bda.", "id": "Sebuah error telah terjadi ketika membuat request SAML.", "ro": "A ap\u0103rut o eroare la crearea cererii SAML.", "ru": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c SAML \u0437\u0430\u043f\u0440\u043e\u0441.", "af": "Daar was 'n fout met die skepping van die SAML versoek.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2 SAML.", "xh": "Kwenzeke impazamo xa kuzanywa ukuyilwa isicelo se-SAML.", "zu": "Kuvele iphutha ngenkathi izama ukwakha isicelo se-SAML.", "st": "Phoso e hlahile ha o leka ho theha kopo ya SAML.", "ca": "S'ha produït un error en intentar crear la sol·licitud SAML." }, "title_DISCOPARAMS": { "no": "Ugyldig foresp\u00f8rsel til SAML 2.0 Discovery-tjenesten", "nn": "Feilforma sp\u00f8rsm\u00e5l til Discovery Service", "sv": "Ogiltig f\u00f6rfr\u00e5gan till lokaliseringstj\u00e4nsten (Discovery Service)", "es": "Solicitud errónea al servicio de descubrimiento", "fr": "Mauvaise requ\u00eate au service de d\u00e9couverte automatique (discovery service)", "de": "Ung\u00fcltige Anfrage an den Discovery Service", "nl": "Toegangsfout bij discovery service", "lb": "Falsch Unfro fir den Discovery Service", "sl": "Zahteva, ki je bila poslana \"Discovery service-u\" je napa\u010dna.", "da": "Fejlagtig foresp\u00f8rgsel til Discovery Service", "hr": "Lokacijskom servisu poslan je neispravan upit", "hu": "\u00c9rv\u00e9nytelen k\u00e9r\u00e9s \u00e9rkezett a felfedez\u0151 szolg\u00e1ltat\u00e1shoz (discovery service)", "fi": "V\u00e4\u00e4r\u00e4nlainen pyynti discovery-palveluun", "pt-br": "Pedido incorreto para o servi\u00e7o de descoberta", "pt": "Pedido incorrecto efectuado ao servi\u00e7o de descoberta de IdP", "pl": "nieprawid\u0142owe \u017cadanie do listy serwisow", "cs": "\u0160patn\u00fd po\u017eadavek pro prohled\u00e1vac\u00ed slu\u017ebu", "tr": "Tan\u0131ma servisine giden hatal\u0131 istek", "lt": "Neteisinga u\u017eklausa kreipiantis \u012f \"discovery\" servis\u0105", "it": "Richiesta errata al discovery service", "ja": "\u30b5\u30fc\u30d3\u30b9\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u4e2d\u306e\u4e0d\u6b63\u306a\u30ea\u30af\u30a8\u30b9\u30c8", "zh-tw": "\u7121\u6548\u7684\u8acb\u6c42\u65bc\u641c\u5c0b\u670d\u52d9", "et": "Halb tuvastusteenuse p\u00e4ring", "he": "\u05d1\u05e7\u05e9\u05d4 \u05e9\u05d2\u05d5\u05d9\u05d4 \u05dc\u05e9\u05d9\u05e8\u05d5\u05ea \u05d2\u05d9\u05dc\u05d5\u05d9", "zh": "\u9519\u8bef\u7684\u641c\u5bfb\u670d\u52a1\u8bf7\u6c42", "ar": "\u0637\u0644\u0628 \u0633\u064a\u0621 \u0644\u062e\u062f\u0645\u0629 \u0627\u0633\u062a\u0643\u0634\u0627\u0641\u064a\u0629", "lv": "Nepareizs piepras\u012bjums discovery servisam", "id": "Request yang buruk ke layanan penemuan", "sr": "Servisu za lociranje poslat je neispravan zahtev", "ro": "Cerere eronat\u0103 c\u0103tre serviciul de c\u0103utare", "ru": "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u043b\u0443\u0436\u0431\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f", "eu": "Eskaera okerra aurkikuntza zerbitzuari", "af": "Toegangsfout by die ontdekkings diens", "el": "\u0395\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03bf \u03b1\u03af\u03c4\u03b7\u03bc\u03b1 \u03c0\u03c1\u03bf\u03c2 \u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03b1\u03bd\u03b5\u03cd\u03c1\u03b5\u03c3\u03b7\u03c2 \u03c0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2", "zu": "Isicelo esingalungile sesevisi yokuthola", "xh": "Isicelo esibi kwinkonzo yofumaniso", "st": "Kopo e mpe bakeng sa tshebeletso ya tshibollo", "ca": "Sol·licitud incorrecta pel servei de descoberta" }, "descr_DISCOPARAMS": { "no": "Parametere sendt til discovery-tjenesten var ikke i korrekt format.", "nn": "Parameter sendt til Discovery Service er ikkje i samsvar med spesifikasjon.", "sv": "Parametrarna som skickades till lokaliseringstj\u00e4nsten f\u00f6ljde inte specifikationen.", "es": "Los parametros enviados al servicio de descubrimiento no se ajustan a la especificación.", "fr": "Les param\u00e8tres envoy\u00e9s au service de d\u00e9couverte automatique (discovery service) ne respectent pas les sp\u00e9cifications.", "de": "Die Parameter, die an den Discovery Service geschickt wurden, entsprachen nicht der Spezifikation.", "nl": "De parameters die naar de discovery service zijn gestuurd, zijn niet correct volgens de specificatie.", "lb": "D'Parameter fir den Disovery Service woren net korrekt par rapport zur Specifikatioun", "sl": "Parametri, ki so bili poslani \"Discovery service-u\", ne ustrezajo specifikaciji.", "da": "De afsendte v\u00e6rdier overholder ikke Discovery Servicens' krav", "hr": "Parametri poslani lokacijskom servisu nisu u ispravnom formatu.", "hu": "A felfedez\u0151 szolg\u00e1ltat\u00e1s (discovery service) olyan param\u00e9tereket kapott, amelyek nem felelnek meg a specifik\u00e1ci\u00f3nak.", "fi": "Discovery-palveluun l\u00e4hetetyt tiedot eiv\u00e4t vastanneet m\u00e4\u00e4r\u00e4yksi\u00e4.", "pt-br": "Os par\u00e2metros enviados para o servi\u00e7o de descoberta n\u00e3o est\u00e3o de acordo com as especifica\u00e7\u00f5es.", "pt": "O pedido efectuado ao servi\u00e7o de descoberta de IdP n\u00e3o est\u00e1 de acordo com as especifica\u00e7\u00f5es.", "cs": "Parametr zaslan\u00fd vyhled\u00e1vac\u00ed slu\u017eb\u011b neodpov\u00edd\u00e1 specifikaci.", "tr": "Tan\u0131ma servisine g\u00f6nderilen parametreler tan\u0131mlananlara g\u00f6re de\u011fildi.", "lt": "Parametrai, nusi\u0173sti \"discovery\" servisui neatitiko specifikacij\u0173.", "it": "I parametri inviati al discovery service non rispettano le specifiche.", "zh-tw": "\u50b3\u905e\u81f3\u641c\u5c0b\u670d\u52d9\u7684\u53c3\u6578\u4e26\u4e0d\u7b26\u5408\u898f\u7bc4\u8981\u6c42\u3002", "ja": "\u30b5\u30fc\u30d3\u30b9\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u306b\u9001\u4fe1\u3057\u305f\u30d1\u30e9\u30e1\u30fc\u30bf\u304c\u4ed5\u69d8\u306b\u5f93\u3063\u3066\u3044\u307e\u305b\u3093\u3002", "et": "Tuvastusteenusele saadetud parameetrid ei vastanud n\u00f5uetele.", "he": "\u05d4\u05e4\u05e8\u05de\u05d8\u05e8\u05d9\u05dd \u05e9\u05e0\u05e9\u05dc\u05d7\u05d5 \u05dc\u05e9\u05d9\u05e8\u05d5\u05ea \u05d2\u05d9\u05dc\u05d5\u05d9 \u05dc\u05d0 \u05d4\u05d9\u05d5 \u05e2\u05dc \u05e4\u05d9 \u05de\u05e4\u05e8\u05d8.", "zh": "\u53d1\u9001\u7ed9\u641c\u5bfb\u670d\u52a1\u7684\u53c2\u6570\u4e0d\u7b26\u5408\u89c4\u8303", "pl": "Parametry wys\u0142ane do us\u0142ugi wyszukiwania nie s\u0105 zgodne ze specyfikacj\u0105", "ar": "\u0627\u0644\u062e\u0635\u0627\u0626\u0635 \u0627\u0644\u0645\u0631\u0641\u0642\u0629 \u0644\u0627 \u062a\u0637\u0627\u0628\u0642 \u0627\u0644\u0645\u0648\u0627\u0635\u0641\u0627\u062a", "lv": "Discovery servisam nos\u016bt\u012btie parametri neatbilst specifik\u0101cij\u0101m.", "id": "Parameter-parameter yang dikirimkan ke layanan penemuan tidak sesuai dengan spesifikasi", "sr": "Parametri poslati servisu za lociranje nisu u ispravnom formatu.", "ro": "Parametrii trimi\u0219i c\u0103tre serviciul de c\u0103utare nu sunt \u00een conformitate cu specifica\u021biile.", "ru": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 \u0441\u043b\u0443\u0436\u0431\u0443 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.", "eu": "Aurkikuntza zerbitzuari bidalitako prametroak ez dira zehaztapenera doitzen.", "af": "Die gestuurde parameters na die ontdekkings diens was not volgens die korrekte spesifikasies nie.", "el": "\u039f\u03b9 \u03c0\u03b1\u03c1\u03ac\u03bc\u03b5\u03c4\u03c1\u03bf\u03b9 \u03c0\u03bf\u03c5 \u03c3\u03c4\u03ac\u03bb\u03b8\u03b7\u03ba\u03b1\u03bd \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03b1\u03bd\u03b5\u03cd\u03c1\u03b5\u03c3\u03b7\u03c2 \u03c0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03ae\u03c4\u03b1\u03bd \u03b5\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03b5\u03c2.", "xh": "Iipharamitha ezithunyelwe kwinkonzo yofumaniso azihambelani neenkcukacha.", "zu": "Amapharamitha athunyelwe kusevisi yokuthola abengavumelani nezici.", "st": "Dipharamitha tse rometsweng tshebeltsong ya tshibollo di ne di se ho latela ditekanyetso.", "ca": "Els paràmetres enviats al servei de descoberta no s'ajusten a les especificacions." }, "title_GENERATEAUTHNRESPONSE": { "no": "Fikk ikke svart p\u00e5 autentiserings-foresp\u00f8rsel", "nn": "Kunne ikkje laga svar p\u00e5 autentiseringssp\u00f8rsm\u00e5l", "sv": "Kunde inte skapa inloggingssvaret", "es": "No se pudo crear la respuesta de autenticación", "fr": "Ne peut pas cr\u00e9er une r\u00e9ponse d'authentification", "de": "Konnte keine Authentifikationsantwort erstellen", "nl": "Authenticatie response kon niet worden aangemaakt", "lb": "Et wor net m\u00e9iglech eng Authenticatiounsaentwert ze erstellen", "sl": "Odgovora za odjavo ni bilo mogo\u010de ustvariti", "da": "Kunne ikke generere single sign-on svar", "hr": "Ne mogu kreirati autentifikacijski odgovor", "hu": "Nem lehet az azonos\u00edt\u00e1st v\u00e9grehajtani", "fi": "Autentikointivastauksen luonti ep\u00e4onnistui", "pt-br": "N\u00e3o foi poss\u00edvel criar a resposta da autentica\u00e7\u00e3o", "pt": "N\u00e3o foi poss\u00edvel criar uma resposta de autentica\u00e7\u00e3o", "pl": "Wyst\u0105pi\u0142 problem z utworzeniem odpowiedzi uwierzytelniania", "cs": "Nelze vytvo\u0159it odpov\u011b\u010f", "tr": "Kimlik do\u011frulama cevab\u0131 olu\u015fturulamad\u0131", "lt": "Nepavyko sukurti autentikacijos atsakymo", "it": "Impossibile generare una risposta di autenticazione", "ja": "\u8a8d\u8a3c\u5fdc\u7b54\u3092\u751f\u6210\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f", "zh-tw": "\u7121\u6cd5\u5efa\u7acb\u9a57\u8b49\u56de\u8986", "et": "Autentimisvastuse loomine ei \u00f5nnestunud", "he": "\u05d0\u05d9\u05df \u05d0\u05e4\u05e9\u05e8\u05d5\u05ea \u05dc\u05d9\u05e6\u05d5\u05e8 \u05ea\u05d2\u05d5\u05d1\u05ea \u05d4\u05d6\u05d3\u05d4\u05d5\u05ea", "zh": "\u65e0\u6cd5\u521b\u5efa\u8ba4\u8bc1\u5e94\u7b54", "sr": "Autentifikacioni odgovor nije mogao biti kreiran", "ar": "\u0644\u0627 \u064a\u0645\u0643\u0646\u0646\u0627 \u0627\u062c\u0631\u0627\u0621 \u0627\u0644\u062a\u0648\u062b\u064a\u0642", "lv": "Neizdev\u0101s izveidot autentifik\u0101cijas atbildi", "id": "Tidak dapat membuat respon autentifikasi", "ro": "Nu a fost posibil\u0103 crearea r\u0103spunsului de autentificare", "ru": "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438", "eu": "Ezin izan da kautotze erantzuna sortu", "af": "Kon nie 'n verifikasie versoek skep nie", "el": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03c0\u03cc\u03ba\u03c1\u03b9\u03c3\u03b7\u03c2 \u03c3\u03c4\u03bf \u03b1\u03af\u03c4\u03b7\u03bc\u03b1 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2", "zu": "Ayikwazanga ukwakha impendulo yokuqinisekisa", "xh": "Ayikwazanga ukuyila impendulo yongqinisiso", "st": "Ha e a kgona ho theha karabelo ya ntefatso", "ca": "No s’ha pogut crear la resposta d’autenticació" }, "descr_GENERATEAUTHNRESPONSE": { "no": "En feil oppsto da innloggingstjenesten pr\u00f8vde \u00e5 lage et svar p\u00e5 autentiserings-foresp\u00f8rselen.", "nn": "Denne Identity Provider kunne ikkje laga svar p\u00e5 autentiseringssp\u00f8rsm\u00e5let fordi det oppsto ein feilsituasjon.", "sv": "N\u00e4r identitetshanteraren (Identity Provider) f\u00f6rs\u00f6kte skapa inloggingssvaret uppstod ett fel.", "es": "El proveedor de identidad ha detectado un error al crear respuesta de autenticación.", "fr": "Une erreur s'est produite lorsque ce fournisseur d'identit\u00e9 a essay\u00e9 de cr\u00e9er une r\u00e9ponse d'authentification.", "de": "Beim Versuch des Identity Providers eine Authentifikationsantwort zu erstellen trat ein Fehler auf.", "nl": "Tijdens het aanmaken van een authenticatie response door deze Identity Provider is er een fout opgetreden.", "lb": "Beim Erstellen vun der Authenticatiounsaentwert as en Fehler pass\u00e9iert", "sl": "Ko je IdP \u017eelel ustvariti odgovor o prijavi, je pri\u0161lo do napake.", "da": "En fejl opstod da denne identitetsudbyder fors\u00f8gte at sende svar", "hr": "Do\u0161lo je do gre\u0161ke prilikom kreiranja odgovora na autentifikacijski zahtjev.", "hu": "Hiba t\u00f6rt\u00e9nt az azonos\u00edt\u00e1si v\u00e1lasz\u00fczenet \u00f6ssze\u00e1ll\u00edt\u00e1sa sor\u00e1n.", "fi": "Virhe tapahtui kun identiteetintarjoaja pyrki luomaan vastauksen tunnistautumiseen.", "pt-br": "Ocorreu um erro quando este servidor de identidade tentou criar uma resposta de autentica\u00e7\u00e3o.", "pt": "Ocorreu um erro ao criar uma resposta de autentica\u00e7\u00e3o neste fornecedor de identidade.", "pl": "Wystapi\u0142 b\u0142ad podczas pr\u00f3by utworzenia przez Dostawc\u0119 To\u017csamo\u015bci odpowiedzi uwierzytelniania .", "cs": "P\u0159i vytv\u00e1\u0159en\u00ed p\u0159ihla\u0161ovac\u00ed odpov\u011bdi t\u00edmto poskytovatelem identity, vznikla chyba.", "tr": "Bu kimlik sa\u011flay\u0131c\u0131 bir kimlik do\u011frulama cevab\u0131 olu\u015fturuken hata olu\u015ftu.", "lt": "\u0160iam tapatybi\u0173 teik\u0117jui bandant sukurti autentikacijos atsakym\u0105 \u012fvyko klaida.", "it": "Si \u00e8 verificato un errore durante la fase di creazione della risposta di autenticazione da parte dell'Identity Provider.", "zh-tw": "\u7576\u9019\u500b\u9a57\u8b49\u63d0\u4f9b\u8005\u5617\u8a66\u5efa\u7acb\u4e00\u500b\u9a57\u8b49\u56de\u8986\u6642\uff0c\u6709\u500b\u932f\u8aa4\u767c\u751f\u3002", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u306e\u8a8d\u8a3c\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u751f\u6210\u6642\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "et": "T\u00f5rge tekkis, kui see identiteedipakkuja p\u00fc\u00fcdis luua autentimisvastust.", "he": "\u05db\u05d0\u05e9\u05e8 \u05e1\u05e4\u05e7 \u05d4\u05d6\u05d4\u05d5\u05ea \u05e0\u05d9\u05e1\u05d4 \u05dc\u05d9\u05e6\u05d5\u05e8 \u05ea\u05d2\u05d5\u05d1\u05ea \u05d4\u05d6\u05d3\u05d4\u05d5\u05ea, \u05d0\u05d9\u05e8\u05e2\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4.", "zh": "\u5728\u8fd9\u4e2a\u8eab\u4efd\u63d0\u4f9b\u8005\u521b\u5efa\u8ba4\u8bc1\u5e94\u7b54\u7684\u65f6\u5019\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef", "sr": "Desila se gre\u0161ka prilikom kreiranja autentifikacionog odgovora od strane ovog davaoca identiteta.", "ar": " \u062d\u062f\u062b \u062e\u0637\u0627 \u0639\u0646\u062f \u0645\u062d\u0627\u0648\u0644\u0629 \u0627\u062c\u0631\u0627\u0621 \u0627\u0644\u062a\u0648\u062b\u064a\u0642", "lv": "Kad identit\u0101tes pieg\u0101d\u0101t\u0101js m\u0113\u0123in\u0101ja izveigot autentifik\u0101cijas atbildi, rad\u0101s k\u013c\u016bda.", "id": "Ketika identity provider ini mencoba untuk membuat response autentifikasi, error terjadi.", "ro": "A ap\u0103rut o eroare c\u00e2nd furnizorul de identitate \u00eencerca s\u0103 creeze un r\u0103spuns de autentificare.", "ru": "\u041f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.", "eu": "Identitatearen hornitzaileak errore bat antzeman du kautotze erantzuna sortzean.", "af": "Daar was 'n fout tydens die verifikasie skepping deur die Identiteits Verskaffer.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03c0\u03cc\u03ba\u03c1\u03b9\u03c3\u03b7\u03c2 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2.", "zu": "Ngenkathi lo mhlinzeki kamazisi ezama ukwakha impendulo yokuqinisekisa, kuvele iphutha.", "xh": "Xa lo mboneleli wesazisi ezama ukuyila impendulo yongqinisiso, kwenzeke impazamo.", "st": "Ha mofani enwa wa boitsebiso a leka ho theha karabelo ya netefatso, phoso e bile teng.", "ca": "Quan el proveïdor d’identitat ha intentat crear una resposta d’autenticació, s’ha produït un error." }, "title_LDAPERROR": { "no": "LDAP-feil", "nn": "LDAP-feil", "sv": "LDAP-fel", "es": "Error de LDAP", "fr": "Erreur LDAP", "de": "LDAP Fehler", "nl": "LDAP Fout", "lb": "LDAP Fehler", "sl": "Napaka LDAP-a", "da": "LDAP fejl", "hr": "LDAP gre\u0161ka", "hu": "LDAP hiba", "fi": "LDAP-virhe", "pt-br": "Erro no LDAP", "pt": "Erro de LDAP", "pl": "B\u0142ad LDAP'a", "cs": "LDAP chyba", "eu": "LDAP Errorea", "tr": "LDAP hatas\u0131", "lt": "LDAP klaida", "it": "Errore LDAP", "ja": "LDAP\u30a8\u30e9\u30fc", "zh-tw": "LDAP \u932f\u8aa4", "et": "LDAP-t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05ea LDAP", "zh": "LDAP\u9519\u8bef", "sr": "LDAP gre\u0161ka", "ar": "\u062e\u0637\u0627 LDAP", "lv": "LDAP k\u013c\u016bda", "id": "Error LDAP", "ro": "Eroare LDAP", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 LDAP", "af": "LDAP Fout", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 LDAP", "xh": "Impazamo ye-LDAP", "zu": "Iphutha le-LDAP", "st": "Phoso ya LDAP", "ca": "Error LDAP" }, "descr_LDAPERROR": { "no": "LDAP er brukerkatalogen, og n\u00e5r du fors\u00f8ker \u00e5 logge inn pr\u00f8ver vi \u00e5 kontakten en LDAP-katalog. Da vi fors\u00f8kte det denne gangen, oppsto en feil.", "nn": "LDAP er brukardatabase din. N\u00e5r du pr\u00f8ver \u00e5 logga inn m\u00e5 vi kontakta LDAP-basen. Denne gongen fekk vi ikkje kontakt p\u00e5 grunn av ein feil.", "sv": "LDAP anv\u00e4nds som anv\u00e4ndardatabas och n\u00e4r du f\u00f6rs\u00f6ker logga m\u00e5ste LDAP-servern kontaktas. Vid f\u00f6rs\u00f6ket att kontakta LDAP-servern uppstod ett fel.", "es": "LDAP es la base de datos de usuarios, es necesario contactar con ella cuando usted decide entrar. Se ha producido un error en dicho acceso", "fr": "La base de donn\u00e9es utilisateur est un annuaire LDAP, et quand vous essayez de vous connecter, nous avons besoin de prendre contact avec cet annuaire LDAP. Lorsque nous avons essay\u00e9 cette fois une erreur s'est produite.", "de": "LDAP ist die gew\u00e4hlte Nutzerdatenbank. Wenn Sie versuchen sich anzumelden, muss auf diese LDAP-Datenbank zugegriffen werden, dabei ist dieses mal ein Fehler aufgetreten.", "nl": "De account database is in LDAP opgeslagen en bij het inloggen moet er worden gecommuniceerd met een LDAP backend. Daarbij is een fout opgetreden.", "lb": "LDAP as eng Benotzerdatenbank an wann een anloggen well g\u00ebt se kontakt\u00e9iert. Dobai as des K\u00e9ier een Fehler geschitt.", "sl": "LDAP je zbirka uporabnikov. Ko se \u017eelite prijaviti, je potrebno prijavo preveriti v LDAPu. Pri trenutnem preverjanju je pri\u0161lo do napake.", "da": "Der opstod en fejl i kommunikationen med LDAP databasen under login.", "hr": "Do\u0161lo je do gre\u0161ke prilikom spajanja na LDAP poslu\u017eitelj. Va\u0161i podaci pohranjeni su u LDAP imeniku i autentifikacijski servis se mora mo\u0107i spojiti na LDAP poslu\u017eitelj da bi provjerio ispravnost unesene korisni\u010dke oznake i zaporke.", "hu": "A felhaszn\u00e1l\u00f3i adatb\u00e1zis LDAP alap\u00fa, ez\u00e9rt bejelentkez\u00e9shez sz\u00fcks\u00e9g van egy LDAP adatb\u00e1zisra. Ez\u00fattal hiba t\u00f6rt\u00e9nt az LDAP-hoz kapcsol\u00f3d\u00e1s sor\u00e1n.", "fi": "LDAP on k\u00e4ytt\u00e4j\u00e4tietokanta, ja kirjautuessassi tarvitsemme yhteyden LDAP-tietokantaan. Yhteyden luonnissa tapahtui virhe.", "pt-br": "O banco de dados de usu\u00e1rios \u00e9 LDAP e quando voc\u00ea tentar efetuar o login \u00e9 preciso entrar em contato com um banco de dados LDAP. Ocorreu um erro durante a tentativa de conex\u00e3o.", "pt": "Ocorreu um erro ao contactar a base de dados LDAP.", "pl": "LDAP jest baz\u0105 uzytkownik\u00f3w i kiedy Ty pr\u00f3bujesz si\u0119 zalogowa\u0107, to my musimy nawi\u0105za\u0107 po\u0142\u0105czenie z baz\u0105 LDAP. I w\u0142a\u015bnie w tym momencie wyst\u0105pi\u0142 b\u0142\u0105d.", "cs": "LDAP je datab\u00e1ze u\u017eivatel\u016f, a kdy\u017e se chcete p\u0159ihl\u00e1sit, je pot\u0159eba se p\u0159ihl\u00e1sit do LDAP datab\u00e1ze. Chyba nastala b\u011bhem p\u0159ipojov\u00e1n\u00ed.", "tr": "LDAP kullan\u0131c\u0131 veritaban\u0131 ve siz giri\u015f yapmaya \u00e7al\u0131\u015f\u0131rken, LDAP veritaban\u0131na ba\u011flanmam\u0131z gerekiyor. Bu seferlik denerken bir sorun olu\u015ftu.", "lt": "LDAP yra naudotoj\u0173 duomen\u0173 baz\u0117. Jums jungiantis, mums reikalinga prie jos prisijungti. Bandant tai padaryti \u012fvyko klaida.", "it": "Gli utenti sono memorizzati nel server LDAP, che viene quindi contattato in fase di connessione dell'utente. Si \u00e8 verificato un errore proprio in questa fase.", "ja": "\u3042\u306a\u305f\u304c\u30ed\u30b0\u30a4\u30f3\u3092\u884c\u3046\u6642\u3001LDAP\u3068\u3044\u3046\u30e6\u30fc\u30b6\u30fc\u30c7\u30fc\u30bf\u30fc\u30d9\u30fc\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002\u3053\u306e\u6642\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "LDAP \u662f\u4f7f\u7528\u8005\u8cc7\u6599\u5eab\uff0c\u7576\u60a8\u5617\u8a66\u767b\u5165\u6642\uff0c\u6211\u5011\u5fc5\u9808\u9023\u7d50\u81f3\u4e00\u500b LDAP \u8cc7\u6599\u5eab\uff0c\u800c\u5728\u5617\u8a66\u767b\u5165\u6642\u6709\u500b\u932f\u8aa4\u767c\u751f\u3002", "et": "LDAP on kasutajate andmebaas ja sisselogimisel p\u00fc\u00fctakse LDAP-andmebaasi \u00fchendust luua. Seekord tekkis \u00fchenduse loomisel t\u00f5rge.", "he": "LDAP \u05d4\u05d5\u05d0 \u05de\u05e1\u05d3 \u05d4\u05e0\u05ea\u05d5\u05e0\u05d9\u05dd \u05d4\u05de\u05db\u05d9\u05dc \u05d0\u05ea \u05d4\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd, \u05d5\u05db\u05d0\u05e9\u05e8 \u05d0\u05ea\u05d4 \u05de\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8, \u05e6\u05e8\u05d9\u05da \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05d0\u05dc\u05d9\u05d5. \u05e9\u05d2\u05d9\u05d0\u05d4 \u05e7\u05e8\u05ea\u05d4 \u05d1\u05d6\u05de\u05df \u05e0\u05d9\u05e1\u05d9\u05d5\u05df \u05d4\u05d7\u05d9\u05d1\u05d5\u05e8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9.", "zh": "LDAP\u662f\u4e00\u4e2a\u7528\u6237\u6570\u636e\u5e93\uff0c\u5f53\u4f60\u8bd5\u56fe\u767b\u5f55\u65f6\uff0c\u6211\u4eec\u9700\u8981\u8fde\u63a5\u5230LDAP\u6570\u636e\u5e93\uff0c\u7136\u800c\u8fd9\u6b21\u6211\u4eec\u8bd5\u56fe\u94fe\u63a5\u65f6\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef", "sr": "Podaci o korisni\u010dkim nalozima \u010duvaju se u LDAP bazi, a kada poku\u0161ate da se ulogujete vr\u0161i se provera da li Va\u0161e korisni\u010dko ime i lozinka postoje u LDAP bazi. Prilikom pristupa LDAP bazi, do\u0161lo je do gre\u0161ke.", "ar": "LDAP \u0647\u0648 \u0633\u062c\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645. \u0639\u0646\u062f\u0645\u0627 \u062a\u0633\u062c\u0644 \u062f\u062e\u0648\u0644\u0643 \u064a\u0646\u0628\u063a\u064a \u0639\u0644\u064a\u0646\u0627 \u0627\u0644\u0627\u062a\u0635\u0627\u0644 \u0628\u0633\u062c\u0644 LDAP. \u062d\u062f\u062b \u062e\u0637\u0627 \u0645\u0627 \u0639\u0646\u062f\u0645\u0627 \u062d\u0627\u0648\u0644\u0646\u0627 \u0630\u0644\u0643 \u0647\u0630\u0647 \u0627\u0644\u0645\u0631\u0629", "lv": "LDAP ir lietot\u0101ju datu b\u0101ze. Piesl\u0113dzoties pie t\u0101s ir j\u0101sp\u0113j piek\u013c\u016bt. \u0160oreiz tas neizdev\u0101s un rad\u0101s k\u013c\u016bda.", "id": "LDAP adalah database user, dan ketika Anda mencoba login, Kami perlu menghubungi database LDAP. Sebuah error terjadi ketika Kami mencobanya saat ini. ", "ro": "LDAP reprezint\u0103 o baz\u0103 de date cu utilizatori. C\u00e2nd \u00eencerca\u021bi s\u0103 v\u0103 autentifica\u021bi, trebuie contactat\u0103 o baz\u0103 de date LDAP. A ap\u0103rut o eroare c\u00e2nd s-a \u00eencercat aceast\u0103 opera\u021biune.", "ru": "LDAP - \u044d\u0442\u043e \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u0440\u0438 \u0432\u0430\u0448\u0435\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 LDAP. \u041f\u0440\u0438 \u044d\u0442\u043e\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u0441 LDAP \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430. ", "eu": "LDAP erabiltzaileen datu basea da, eta sartzea erabakitzen duzunean beharrezkoa da harekin harremanetan jartzea. Sartze ekintza horretan errore bat jazo da.", "af": "LDAP is die gebruikers databasis en waneer jy probeer inteken moet ons die LDAP databasis kontak. Daar was 'n fout toe ons die slag probeer het.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03ba\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd (LDAP).", "xh": "I-LDAP ngumvimba wengcombolo yomsebenzisi, yaye xa uzame ukungena, kufuneka siqhagamshele uvimba wengcombolo we-LDAP. Kwenzeke impazamo xa besiyizama.", "zu": "I-LDAP iyidathabheyisi yomsebenzisi, futhi lapho uzama ukungena, sidinga ukuthinta idathabheyisi ye-LDAP. Kuvele iphutha ngesikhathi siyizama ngalesi sikhathi.", "st": "LDAP ke dathabeise ya mosebedisi, mme ha o leka ho kena, re hloka ho ikopanya le dathabeise ya LDAP. Phoso e hlahile ha re e leka lekgelong lena.", "ca": "LDAP és la base de dades d'usuaris i, quan intenteu iniciar la sessió, necessitem connectar amb una base de dades LDAP. S'ha produït un error quan hem provat d'accedir-hi." }, "title_LOGOUTREQUEST": { "no": "Feil i behandling av logout-foresp\u00f8rselen", "nn": "Feil under prosessering av utloggingssp\u00f8rsm\u00e5l", "sv": "Fel vid utloggningsf\u00f6rfr\u00e5gan", "es": "Error al procesar la solicitud de cierre de sesión", "fr": "Erreur lors du traitement de la requ\u00eate de d\u00e9connexion", "de": "Fehler beim Bearbeiten der Abmeldeanfrage", "nl": "Fout bij het verwerken van een Logout Request", "lb": "Fehler beim Bearbeschten vun der Logout Unfro", "sl": "Napaka pri obdelavi zahteve za odjavo", "da": "Fejl i Logout Request", "hr": "Gre\u0161ka prilikom odjavljivanja", "hu": "Feldolgozhatatlan kijelentkez\u00e9si k\u00e9r\u00e9s", "fi": "Uloskirjautumispyynn\u00f6n k\u00e4sittelyss\u00e4 tapahtui virhe", "pt-br": "Erro ao processar a resposta da desconex\u00e3o", "pt": "Erro ao processar o pedido de logout", "pl": "B\u0142\u0105d przetwarzania \u017c\u0105dania wylogowania", "cs": "Chyba zpracov\u00e1n\u00ed odhla\u0161ovac\u00edho po\u017eadavku", "eu": "Errorea saioa ixteko eskaera prozesatzean ", "tr": "\u00c7\u0131k\u0131\u015f \u0130ste\u011fini i\u015flerken hata olu\u015ftu", "lt": "Klaida vykdant atsijungimo u\u017eklaus\u0105", "it": "Errore nell'elaborazione della richiesta di disconnessione (Logout Request).", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u6d0b\u5f13\u306e\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f", "zh-tw": "\u8655\u7406\u767b\u51fa\u8acb\u6c42\u6642\u767c\u751f\u932f\u8aa4", "et": "T\u00f5rge v\u00e4ljalogimisp\u00e4ringu t\u00f6\u00f6tlemisel", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05e2\u05d9\u05d1\u05d5\u05d3 \u05d1\u05e7\u05e9\u05ea \u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea", "zh": "\u5904\u7406\u9000\u51fa\u8bf7\u6c42\u65f6\u53d1\u751f\u9519\u8bef", "sr": "Gre\u0161ka pri obradi zahteva za odjavu", "ar": "\u062e\u0637\u0627 \u0639\u0646\u062f \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c", "lv": "Atsl\u0113g\u0161an\u0101s piepras\u012bjuma apstr\u0101des k\u013c\u016bda", "id": "Error memproses Request Logout", "ro": "Eroare la procesarea cererii de deautentificare", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b ", "af": "Fout met die verwerking van die Afmeldings Versoek", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b9\u03b1\u03b4\u03b9\u03ba\u03b1\u03c3\u03af\u03b1 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2", "xh": "Impazamo iprosesa iSicelo Sokuphuma", "zu": "Iphutha lokucubungula Isicelo Sokuphuma", "st": "Phoso ho sebetseng Kopo ya Ho Tswa", "ca": "S'ha produït un error en processar la sol·licitud de desconnexió" }, "descr_LOGOUTREQUEST": { "no": "En feil oppsto i behandlingen av logout-foresp\u00f8rselen.", "nn": "Handteringa av sp\u00f8rsm\u00e5l om utlogging er ikkje ferdig, det oppsto ein feil.", "sv": "Ett fel uppstod n\u00e4r utloggningsf\u00f6rfr\u00e5gan skulle bearbetas.", "es": "Se ha producido un error al tratar de procesar la solicitud de cierre de sesión.", "fr": "Une erreur s'est produite lors de la tentative de traiter la demande de d\u00e9connexion.", "de": "Beim Versuch die Abmeldeanfrage zu bearbeiten ist ein Fehler aufgetreten.", "nl": "Er is een fout opgetreden tijdens het verwerken van een Logout Request.", "lb": "En Fehler as geschit beim Bearbeschten vun der Logout Unfro", "sl": "Pri obdelavi zahteve za odjavo je pri\u0161lo do napake.", "da": "Der opstod en fejl under behandlingen af Logout foresp\u00f8rgelsen", "hr": "Do\u0161lo je do gre\u0161ke prilikom obrade zahtjeva za odjavljivanjem.", "hu": "A kijelentkez\u00e9si k\u00e9r\u00e9s (logout request) feldolgoz\u00e1sa sor\u00e1n hiba t\u00f6rt\u00e9nt.", "fi": "Uloskirjautumispyynn\u00f6n k\u00e4sittelyn yrityksess\u00e4 tapahtui virhe", "pt-br": "Um erro ocorreu ao tentar processar a resposta da desconex\u00e3o.", "pt": "Ocorreu um erro ao processar o pedido de logout.", "pl": "Wyst\u0105pi\u0142 b\u0142ad podczas pr\u00f3by wylogowania.", "cs": "P\u0159i procesu odhl\u00e1\u0161en\u00ed vznikla chyba.", "eu": "Errore bat jazo da saioa ixteko eskaera prozesatzean.", "tr": "\u00c7\u0131k\u0131\u015f \u0130ste\u011fini i\u015flemeye \u00e7al\u0131\u015f\u0131rken bir hata olu\u015ftu", "lt": "Klaida \u012fvyko bandant \u012fvykdyti atsijungimo u\u017eklaus\u0105.", "it": "Si \u00e8 verificato un errore quando si \u00e8 tentato di elaborare la richiesta di disconnessione (Logout Request).", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u6709\u500b\u932f\u8aa4\u767c\u751f\u65bc\u9032\u884c\u767b\u51fa\u8acb\u6c42\u8655\u7406\u6642\u3002", "et": "V\u00e4ljalogimisp\u00e4ringu t\u00f6\u00f6tlemisel tekkis t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d6\u05de\u05df \u05d4\u05e0\u05d9\u05e1\u05d9\u05d5\u05df \u05dc\u05e2\u05d1\u05d3 \u05d0\u05ea \u05d1\u05e7\u05e9\u05ea \u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea.", "zh": "\u8bd5\u56fe\u5904\u7406\u9000\u51fa\u8bf7\u6c42\u65f6\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef", "sr": "Do\u0161lo je do gre\u0161ke prilikom poku\u0161aja obrade zahteva za odjavom.", "ar": "\u062e\u0637\u0627 \u0639\u0646\u062f \u0645\u062d\u0627\u0648\u0644\u0629 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c", "lv": "Apstr\u0101d\u0101jot atsl\u0113g\u0161an\u0101s piepras\u012bjumu, rad\u0101s k\u013c\u016bda.", "id": "Sebuah error telah terjadi ketika memproses Request Logout.", "ro": "A ap\u0103rut o eroare la procesarea cererii de deautentificare.", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "af": "Daar was 'n probleem tydens die verwerking van die Afmelding Versoek", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03b1\u03c3\u03c4\u03ae\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2.", "zu": "Kuvele iphutha ngenkathi izama ukucubungula Isicelo Sokuphuma.", "xh": "Kwenzeke impazamo ngoxa kuproseswa isiCelo Sokuphuma.", "st": "Phoso e hlahile ha e leka ho sebetsa Kopo ya Ho Tswa.", "ca": "S'ha produït un error en intentar processar la sol·licitud de desconnexió." }, "title_METADATA": { "no": "Feil ved lasting av metadata", "nn": "Feil under lasting av metadata", "sv": "Fel vi laddandet av metadata", "es": "Error al cargar los metadatos", "fr": "Erreur lors du chargement des m\u00e9tadonn\u00e9es (metadata)", "de": "Fehler beim Laden der Metadaten", "nl": "Fout bij het laden van metadata", "lb": "Fehler beim Lueden vun den Meta Donn\u00e9es", "sl": "Napaka pri nalaganju metapodatkov", "da": "Fejl i l\u00e6sning af metadata", "hr": "Gre\u0161ka prilikom u\u010ditavanja metapodataka", "hu": "Metaadat bet\u00f6lt\u00e9si hiba", "fi": "Metadatan lataaminen ep\u00e4onnistui", "pt-br": "Erro ao carregar a metadata.", "pt": "Erro na leitura dos metadados", "pl": "B\u0142\u0105d \u0142adowania metadanych", "cs": "Chyba nahrav\u00e1n\u00ed metadat", "tr": "\u00dcstveri (metadata) y\u00fcklenmesinde hata", "lt": "Klaida siun\u010diant metaduomenis", "it": "Errore nel caricamento dei metadati", "ja": "\u76ee\u3089\u30fc\u30c7\u30fc\u30bf\u306e\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f", "zh-tw": "\u932f\u8aa4\u8f09\u5165 Metadata \u8cc7\u6599", "et": "Metaandmete laadimise t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d8\u05e2\u05d9\u05e0\u05ea \u05d4\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2", "zh": "\u8f7d\u5165\u5143\u4fe1\u606f\u65f6\u53d1\u751f\u9519\u8bef", "sr": "Gre\u0161ka prilikom u\u010ditavanja metapodataka", "ar": "\u062e\u0637\u0627 \u0628\u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629\/ \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627 ", "lv": "Metadatu iel\u0101des k\u013c\u016bda", "id": "Error meload metadata", "ro": "Eroare la \u00eenc\u0103rcarea metadatelor", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445", "eu": "Errorea metadatuak kargatzean", "af": "Fout met die laai van die metadata", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03c6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b7 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd", "zu": "Iphutha lokulayisha imethadatha", "xh": "Impazamo ilayisha imetadata", "st": "Phoso ya ho louta metadata", "ca": "S'ha produït un error en carregar les metadades" }, "descr_METADATA": { "no": "Det er en feil i oppsettet for din SimpleSAMLphp-installasjon. Hvis du er administrator for tjenesten, b\u00f8r du kontrollere at metadata er satt opp riktig.", "nn": "Installasjonen av SimpleSAMLphp er feilkonfigurert. Dersom du er administrator m\u00e5 du sjekka metadata-konfigurasjonen. Dersom du ikkje er administrator, ta kontakt med henne.", "sv": "Det finns n\u00e5got fel i konfigurationen i installation av SimpleSAMLphp. Om du \u00e4r adminstrat\u00f6r av tj\u00e4nsten ska du kontrollera om konfigurationen av metadata \u00e4r r\u00e4tt konfigurerad.", "es": "Hay errores de configuración en su instalación de SimpleSAMLphp. Si es usted el administrador del servicio, cerciórese de que la configuración de los metadatos es correcta.", "fr": "Quelque chose n'est pas configur\u00e9 correctement dans votre installation de SimpleSAMLphp. Si vous \u00eates l'administrateur de ce service, vous devez vous assurer que votre configuration des m\u00e9tadonn\u00e9es est correctement r\u00e9alis\u00e9e.", "de": "Diese Installation von SimpleSAMLphp ist falsch konfiguriert. Falls Sie der Administrator dieses Dienstes sind, sollten Sie sicherstellen, dass die Metadatenkonfiguration korrekt ist.", "nl": "SimplSAMLphp is niet goed geconfigureerd. De beheerder van deze dienst dient de metadata configuratie te controleren.", "lb": "Des SimpleSAMLphp Installatioun sch\u00e9int falsch konfigur\u00e9iert ze sin. Wann dir den Administrator vun d\u00ebsem Service sid, dann stellt s\u00ebcher dass d Meta Donn\u00e9es richteg angeriicht sin.", "sl": "V konfiguraciji SimpleSAMLphp-ja je napaka. \u010ce ste skrbnik te storitve, preverite, da je konfiguracija metapodatkov pravilna.", "da": "Der er en fejl i konfigurationen af din SimpleSAMLphp installation. Hvis du er administrator for denne server, check at din metadata konfiguration er korrekt.", "hr": "Programski alat SimpleSAMLphp je pogre\u0161no iskonfiguriran. Ako ste administrator ovog servisa, provjerite jesu li svi metapodaci u konfiguraciji ispravni.", "hu": "SimpleSAMLphp konfigur\u00e1ci\u00f3s hiba. Ha \u00d6n ennek a szolg\u00e1ltat\u00e1snak az adminisztr\u00e1tora, bizonyosodjon meg arr\u00f3l, hogy a metaadatok helyesen vannak be\u00e1ll\u00edtva!", "fi": "SimpleSAMLphp-asenuksen m\u00e4\u00e4rittelyiss\u00e4 on virhe. Mik\u00e4li olet t\u00e4m\u00e4n palvelun yll\u00e4pit\u00e4j\u00e4 tulee sinun varmistua metadatan oikeellisuudesta.", "pt-br": "H\u00e1 erros na sua instala\u00e7\u00e3o do SimpleSAMLphp. Se voc\u00ea \u00e9 o administrador deste seri\u00e7o, voc\u00ea deve certificar-se que a sua configura\u00e7\u00e3o de metadata est\u00e1 definida corretamente.", "pt": "Existe uma m\u00e1 configura\u00e7\u00e3o desta instala\u00e7\u00e3o do SimpleSAMLphp. Se \u00e9 o administrador deste servi\u00e7o, verifique que a configura\u00e7\u00e3o dos metadados est\u00e1 correcta.", "cs": "Je zde chyba v konfiguraci SimpleSAMLphp. Pokud jsi administr\u00e1torem slu\u017eby zkontroluj metadata.", "tr": "SimpleSAMLphp kurulumunuzda baz\u0131 yanl\u0131\u015f ayarlamalar s\u00f6zkonusu. E\u011fer bu servisin y\u00f6neticisi sizseniz, \u00fcstveri (metadata) ayarlar\u0131n\u0131z\u0131n d\u00fczg\u00fcn bir \u015fekilde yap\u0131ld\u0131\u011f\u0131ndan emin olun.", "lt": "Rastos J\u016bs\u0173 SimpleSAMLphp konfig\u016bravimo klaidos. Jei J\u016bs esate \u0161ios sistemos administratorius, tur\u0117tum\u0117te patikrinti, ar teisingai nustatyti metaduomenys.", "it": "C'\u00e8 qualche errore di configurazione in questa installazione SimpleSAMLphp. Se sei l'amministratore di sistema, assicurati che la configurazione dei metadati sia corretta.", "zh-tw": "\u6709\u4e00\u4e9b\u932f\u8aa4\u8a2d\u5b9a\u5728\u60a8\u6240\u5b89\u88dd\u7684 SimpleSAMLphp\u3002\u5982\u679c\u60a8\u662f\u9019\u500b\u670d\u52d9\u7684\u7ba1\u7406\u54e1\uff0c\u60a8\u53ef\u80fd\u9700\u8981\u78ba\u8a8d\u60a8\u7684 Metadata \u8a2d\u5b9a\u662f\u5426\u6b63\u78ba\u3002", "ja": "SimpleSAMLphp\u306e\u8a2d\u5b9a\u306b\u8aa4\u308a\u304c\u3042\u308a\u307e\u3057\u305f\u3002\u3082\u3057\u3042\u306a\u305f\u304c\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306e\u7ba1\u7406\u8005\u3067\u3042\u308c\u3070\u30e1\u30bf\u30c7\u30fc\u30bf\u8a2d\u5b9a\u3092\u6b63\u3057\u304f\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002", "et": "Midagi on su SimpleSAMLphp paigalduses valesti seadistatud. Kui sa oled selle teenuse administraator, siis peaksid kontrollima, et metaandmete seadistused oleks korrektselt seadistatud.", "he": "\u05d9\u05e9\u05e0\u05d4 \u05d1\u05e2\u05d9\u05d9\u05d4 \u05d1\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05d4\u05ea\u05e7\u05e0\u05ea \u05d4 SimpleSAMLphp \u05e9\u05dc\u05da. \u05d0\u05dd \u05d0\u05ea\u05d4 \u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea \u05e9\u05dc \u05e9\u05d9\u05e8\u05d5\u05ea \u05d6\u05d4, \u05db\u05d3\u05d9 \u05e9\u05ea\u05d5\u05d5\u05d3\u05d0 \u05e9\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05de\u05d4\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc\u05da \u05e0\u05db\u05d5\u05e0\u05d5\u05ea.", "zh": "\u4f60\u7684SimpleSAMLphp\u914d\u7f6e\u9519\u8bef\uff0c\u5982\u679c\u4f60\u662f\u8be5\u670d\u52a1\u7684\u7ba1\u7406\u5458\uff0c\u90a3\u4e48\u8bf7\u786e\u8ba4\u4f60\u7684\u914d\u7f6e\u662f\u6b63\u786e\u7684", "sr": "Postoji gre\u0161ka u pode\u0161avanjima SimpleSAMLphp-a. Ukoliko ste administrator ovog servisa, trebalo bi da proverite da li su metapodaci ispravno pode\u0161eni.", "pl": "Wykryto b\u0142\u0105d w konfiguracji SimpleSAMLphp. Je\u015bli jeste\u015b administratorem tej us\u0142ugi, to sprawd\u017a, czy prawid\u0142owo zosta\u0142y skonfigurowane metadane.", "ar": "\u0647\u0646\u0627\u0643 \u062e\u0637\u0627 \u0628\u062a\u0631\u062a\u064a\u0628 SimpleSAMLphp \u0627\u0644\u062e\u0627\u0635 \u0628\u0643. \u0627\u0646 \u0643\u0646\u062a \u0627\u0644\u0645\u0634\u0631\u0641 \u0639\u0644\u064a \u0627\u0644\u0645\u0648\u0642\u0639\u060c \u062a\u0623\u0643\u062f \u0631\u062c\u0627\u0621\u0627\u064b \u0645\u0646 \u0627\u0646 \u062a\u0631\u062a\u064a\u0628 \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627 \u0635\u062d\u064a\u062d", "lv": "J\u016bsu SimpleSAMLphp instal\u0101cijas konfigur\u0101cij\u0101 ir k\u013c\u016bda. P\u0101rliecinieties, lai metadatu konfigur\u0101cija b\u016btu korekta.", "id": "Ada beberapa kesalahan konfigurasi pada instalasi SimpleSAMLphp Anda. Jika Anda adalah administrator dari layanan ini, Anda harus memastikan konfigurasi metdata Anda telah disetup dengan benar. ", "ro": "Exist\u0103 o eroare \u00een configurarea SimpleSAMLphp. Dac\u0103 sunte\u021bi administratorul acestui serviciu, verifica\u021bi configurarea metadatelor.", "ru": "\u0412\u0430\u0448 SimpleSAMLphp \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0435\u0441\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445.", "eu": "Konfigurazio erroreak daude zure SimpleSAMLphp-ren instalazioan. Zerbitzuaren administratzailea bazara, ziurta ezazu metadatuen konfigurazioa zuzena dela.", "af": "Daar is fout met jou SimplSAMLphp installasie. Indien jy die administrateur is van di\u00e9 diens moet jy verseker dat jou metadata konfigurasie korrek is.", "el": "\u03a5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03ba\u03ac\u03c0\u03bf\u03b9\u03bf \u03c0\u03c1\u03cc\u03b2\u03bb\u03b7\u03bc\u03b1 \u03c3\u03c4\u03b9\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 SimpleSAMLphp. \u0395\u03ac\u03bd \u03b5\u03af\u03c3\u03c4\u03b5 \u03bf \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae\u03c2 \u03c4\u03b7\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2 \u03b1\u03c5\u03c4\u03ae\u03c2, \u03b2\u03b5\u03b2\u03b1\u03b9\u03c9\u03b8\u03b5\u03af\u03c4\u03b5 \u03cc\u03c4\u03b9 \u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03ad\u03c7\u03bf\u03c5\u03bd \u03c1\u03c5\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af \u03c3\u03c9\u03c3\u03c4\u03ac.", "xh": "Kukho ulungiselelo olungachanekanga oluthile lofakelo lwakho lwe-SimpleSAMLphp. Ukuba ngaba ungumlawuli wale nkonzo, ufanele uqinisekise ulungiselelo lwakho lweempawu-ngcaciso zefayile lusetwe ngokuchanekileyo.", "zu": "Kukhona umiso olungafanele kukufaka kwakho kwe-SimpleSAMLphp. Uma ungumlawuli wale sevisi, kufanele wenze isiqiniseko sokuthi umiso lwakho lwemethadatha lumiswe ngendlela efanele.", "st": "Ho na le tlhophiso e fosahetseng ya kenyo ya ho instola SimpleSAMLphp ya hao. Haeba o motsamaisi wa tshebeletso ena, o tlameha ho etsa bonnete ba hore tlhophiso ya metadata ya hao e setilwe ka nepo.", "ca": "Hi ha alguna configuració incorrecta a la vostra instal·lació de SimpleSAMLphp. Si sou l’administrador d’aquest servei, heu d’assegurar-vos que la configuració de les vostres metadades s’ha realitzat correctament." }, "title_NOACCESS": { "no": "Ingen tilgang", "nn": "Ingen tilgang", "sv": "Ingen \u00e5tkomst", "es": "Acceso no definido", "fr": "Pas d'acc\u00e8s", "de": "Kein Zugriff", "nl": "Geen toegang", "lb": "Keen Zougr\u00ebff", "sl": "Ni dostopa", "da": "Ingen Adgang", "hr": "Pristup nije dozvoljen", "hu": "Hozz\u00e1f\u00e9r\u00e9s megtagadva", "fi": "Ei oikeutta", "pt-br": "Acesso negado.", "pt": "Acesso negado", "pl": "Brak dost\u0119pu", "cs": "Nem\u00e1te p\u0159\u00edstup", "tr": "Giri\u015f yok", "lt": "Prieigos n\u0117ra", "it": "Nessun accesso", "ja": "\u30a2\u30af\u30bb\u30b9\u304c\u3042\u308a\u307e\u305b\u3093", "zh-tw": "\u7121\u6cd5\u5b58\u53d6", "et": "Ligip\u00e4\u00e4s puudub", "he": "\u05d0\u05d9\u05df \u05d2\u05d9\u05e9\u05d4", "zh": "\u7981\u6b62\u8bbf\u95ee", "sr": "Pristup nije dozvoljen", "ar": "\u0645\u0645\u0646\u0648\u0639 \u0627\u0644\u062f\u062e\u0648\u0644", "lv": "Nav pieejas", "id": "Tiaak ada akses", "ro": "Accesul este interzis", "ru": "\u041e\u0442\u043a\u0430\u0437 \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435", "eu": "Sarrera zehaztu gabe", "af": "Geen toegang", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7", "zu": "Akukho ukufinyelela", "xh": "Akukho fikelelo", "st": "Ha ho phihlello", "ca": "Sense accès" }, "descr_NOACCESS": { "no": "Dette endepunktet er ikke aktivert. Sjekk aktiveringsopsjonene i ditt SimpleSAMLphp-oppsett.", "nn": "Endepunktet er ikkje skrudd p\u00e5. Sjekk Enable Options i konfigurasjonen av SimpleSAMLphp.", "sv": "Denna \u00e4ndpunkt \u00e4r inte aktiverad. Kontrollera aktiveringsinst\u00e4llningarna i konfigurationen av SimpleSAMLphp.", "es": "Este punto de acceso no está habilitado. Verifique las opciones de habilitación en la configuración de SimpleSAMLphp.", "fr": "Cette terminaison (ou endpoint<\/i>) n'est pas activ\u00e9e. V\u00e9rifiez les options d'activation dans la configuration de SimpleSAMLphp.", "de": "Dieser Endpunkt ist nicht aktiviert. \u00dcberpr\u00fcfen Sie die Aktivierungsoptionen in der SimpleSAMLphp Konfiguration.", "nl": "Deze toegangsmogelijkheid is niet beschikbaar. Controleer de opties in de configuratie van SimpleSAMLphp.", "lb": "D\u00ebsen Punkt as net aktiv\u00e9iert. Verifiz\u00e9iert d Optiounen an der SimpleSAMLphp Konfiguratioun.", "sl": "Ta kon\u010dna to\u010dka ni omogo\u010dena. Preverite mo\u017enost omogo\u010danja storitve v konfiguraciji SimpleSAMLphp-ja.", "da": "Denne tjeneste er ikke tilsluttet. Check konfigurationen.", "hr": "Ova odredi\u0161na adresa nije omogu\u0107ena. Provjerite dozvole u konfiguraciji va\u0161e instalacije programskog alata SimpleSAMLphp.", "hu": "Ez a hozz\u00e1f\u00e9r\u00e9si pont nincs enged\u00e9lyezve. Enged\u00e9lyezze a SimpleSAMLphp be\u00e1ll\u00edt\u00e1sai k\u00f6z\u00f6tt.", "fi": "T\u00e4m\u00e4 p\u00e4\u00e4te ei ole otettu k\u00e4ytt\u00f6\u00f6n. Tarkasta enable-optiot SimpleSAMLphp:n asetuksissa.", "pt-br": "Este par\u00e2metro n\u00e3o est\u00e1 ativado. Marque a op\u00e7\u00e3o habilitar na configura\u00e7\u00e3o do SimpleSAMLphp.", "pt": "Este ponto de acesso (endpoint) n\u00e3o est\u00e1 dispon\u00edvel. Verifique as op\u00e7\u00f5es relevantes na configura\u00e7\u00e3o do SimpleSAMLphp.", "cs": "Tento koncov\u00fd bod nen\u00ed povolen. Zkontrolujte konfiguraci (zapn\u011bte volby).", "tr": "Bu k\u0131s\u0131m kullan\u0131mda de\u011fil. SimpleSAMLphp ayarlar\u0131n\u0131z\u0131n etkinle\u015ftirme se\u00e7eneklerini kontrol edin.", "lt": "Baigties ta\u0161kas ne\u012fjungtas. Patikrinkite savo SimpleSAMLphp konfig\u016bracij\u0105.", "it": "Questo endpoint non \u00e8 abilitato. Verifica le opzioni di attivazione nella configurazione di SimpleSAMLphp.", "zh-tw": "\u9019\u500b\u7aef\u9ede\u4e26\u672a\u555f\u7528\uff0c\u8acb\u65bc\u60a8\u7684 SimpleSAMLphp \u8a2d\u5b9a\u4e2d\u6aa2\u67e5\u7aef\u9ede\u662f\u5426\u5df2\u555f\u7528\u3002", "ja": "\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u304c\u6709\u52b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002SimpleSAMLphp\u306e\u8a2d\u5b9a\u3067\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u6709\u52b9\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "et": "See l\u00f5pp-punkt pole lubatud. Kontrolli oma simpleSAMPphp seadistust.", "he": "\u05e7\u05e6\u05d4 \u05d6\u05d4 \u05d0\u05d9\u05e0\u05d5 \u05de\u05d5\u05e4\u05e2\u05dc. \u05d1\u05d3\u05d5\u05e7 \u05d0\u05ea \u05d0\u05e4\u05e9\u05e8\u05d9\u05d5\u05ea \u05d4\u05d4\u05e4\u05e2\u05dc\u05d4 \u05d1\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea SimpleSAMLphp \u05e9\u05dc\u05da.", "zh": "\u8fd9\u4e2a\u7aef\u70b9\u6ca1\u6709\u542f\u7528\uff0c\u8bf7\u5728SimpleSAMLphp\u7684\u914d\u7f6e\u9009\u9879\u4e2d\u9009\u4e2d\u542f\u7528", "sr": "Pristup ovoj odredi\u0161noj adresa nije omogu\u0107en. Proverite pode\u0161avanja dozvola u SimpleSAMLphp-u.", "pl": "Brak uprawnie\u0144. Sprawd\u017a opcj\u0119 enable w konfiguracji SimpleSAMLphp.", "ar": "\u0647\u0630\u0647 \u0627\u0644\u0646\u0642\u0637\u0629 \u063a\u064a\u0631 \u0645\u0646\u0634\u0637\u0629. \u0631\u0627\u062c\u0639 \u062e\u064a\u0627\u0631\u0627\u062a \u0627\u0644\u062a\u0646\u0634\u064a\u0637 \u0628\u062a\u0631\u062a\u064a\u0628 SimpleSAMLphp", "lv": "\u0160is beigu punkts nav iesp\u0113jots. P\u0101rbaudiet iesp\u0113jo\u0161anas opcijas SimpleSAMLphp konfigur\u0101cij\u0101.", "id": "Endpoint ini tidak diaktifkan. Periksalah opsi enable pada konfigurasi SimpleSAMLphp Anda.", "ro": "Acest cap\u0103t\/obiectiv nu este activat. Verifica\u021bi op\u021biunile de activare \u00een configurarea SimpleSAMLphp.", "ru": "\u0414\u0430\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0430. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043e\u043f\u0446\u0438\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0430\u0448\u0435\u0433\u043e SimpleSAMLphp.", "eu": "Sarbide puntu hau ez dago gaituta. Egiazta itzazu SimpleSAMLphp-aren konfigurazioan gaitze aukerak.", "af": "Die eindpunt is nie beskikbaar nie. Gaan die staat opsies in jou opset van SimpleSAMLphp na.", "el": "\u0391\u03c5\u03c4\u03cc \u03c4\u03bf \u03c4\u03b5\u03bb\u03b9\u03ba\u03cc \u03c3\u03b7\u03bc\u03b5\u03af\u03bf \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2 (endpoint) \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf. \u0395\u03ac\u03bd \u03b5\u03af\u03c3\u03c4\u03b5 \u03bf \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae\u03c2 \u03c4\u03b7\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2, \u03b5\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03c4\u03b9\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 SimpleSAMLphp.", "xh": "Le ndawo yokuphela ayenziwanga yasebenza. Jonga ukhetho lokwenza isebenze kulungiselelo lwakho lwe-SimpleSAMLphp.", "zu": "Lesi siphetho asivunyelwe. Hlola izinketho zokuvumela kumiso lwakho lwe-SimpleSAMLphp.", "st": "Ntlha ya bofelo ha e a bulelwa. Hlahloba dikgetho tse tlhophisong ya hao ya SimpleSAMLphp.", "ca": "Aquest punt final no està habilitat. Comproveu les opcions d’habilitació en la configuració de SimpleSAMLphp." }, "title_NORELAYSTATE": { "no": "Spesifikasjon av RelayState mangler", "nn": "Ingen RelayState", "sv": "Ingen RelayState definierad", "es": "RelayState no definido", "fr": "Pas d'information RelayState", "de": "Kein Weiterleitungsangabge", "nl": "Geen RelayState", "lb": "Den ReplayState Parameter fehlt", "sl": "RelayState parameter ne obstaja", "da": "RelayState mangler", "hr": "Parametar RelayState nije zadan", "hu": "Nincs RelayState param\u00e9ter", "fi": "Ei RelayState ", "pt-br": "Sem RelayState", "pt": "RelayState n\u00e3o definido", "cs": "Nenalezen RelayState.", "tr": "RelayState verilmemi\u015f.", "lt": "N\u0117ra perdavimo statuso", "it": "Nessun RelayState", "ja": "RelayState\u304c\u3042\u308a\u307e\u305b\u3093", "zh-tw": "\u6c92\u6709 RelayState", "et": "RelayState puudub", "he": "\u05d0\u05d9\u05df RelayState", "sr": "Parametar RelayState nije zadan", "pl": "Brak RelayState", "zh": "\u65e0\u4f9d\u8d56\u72b6\u6001", "ar": "\u0627\u0646\u0639\u062f\u0627\u0645 \u0627\u0644\u062a\u0642\u0648\u064a\u0629", "lv": "Nav RelayState", "id": "Tidak ada RelayState", "ro": "Nu exist\u0103 RelayState<\/i>", "ru": "\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 RelayState", "eu": "RelayState zehaztu gabe", "af": "Geen aflos staat('RelayState')", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c0\u03b1\u03c1\u03b1\u03bc\u03ad\u03c4\u03c1\u03bf\u03c5 'RelayState'", "zu": "Ayikho I-RelayState", "xh": "Akukho RelayState", "st": "Ha ho RelayState", "ca": "Sense RelayState" }, "descr_NORELAYSTATE": { "no": "Kilden til denne foresp\u00f8rselen har ikke angitt noen RelayState-parameter som angir hvor vi skal fortsette etterp\u00e5.", "nn": "Opphavsmann til denne meldinga har ikkje sendt med RelayState-parameter. D\u00e5 veit vi ikke kvar vi skal, og det blir feil.", "sv": "Avs\u00e4ndaren av denna f\u00f6rfr\u00e5gan hade ingen parameter f\u00f6r RelayState vilket medf\u00f6r att n\u00e4sta plats inte \u00e4r definierad.", "es": "El iniciador de esta solicitud no proporcionó el parámetro RelayState que indica donde ir a continuación", "fr": "L'\u00e9metteur de cette requ\u00eate n'a pas fourni de param\u00e8tre RelayState indiquant quelle page afficher ensuite.", "de": "Der Initiator dieser Anfrage hat keinen Weiterleitungsparameter bereit gestellt, der Auskunft gibt, wohin es als n\u00e4chstes gehen soll.", "nl": "De afzender van deze request heeft geen RelayState parameter meegestuurd om aan te geven wat de volgende bestemming is.", "lb": "Den Initiator vun der Unfro huet ken ReplayState Parameter matgeschekt.", "sl": "Pobudnik te zahteve ni posredoval RelayState parametra.", "da": "Afsenderen af denne foresp\u00f8rgelse har ikke angivet en RelayStay parameter, der hvilket hvor der skal forts\u00e6ttes", "hr": "Aplikacija koja je inicirala ovaj zahtjev nije poslala RelayState parametar koji sadr\u017ei adresu na koju treba preusmjeriti korisnikov web preglednik nakon uspje\u0161ne autentifikacije.", "hu": "A k\u00e9r\u00e9s \u00f6ssze\u00e1ll\u00edt\u00f3ja nem adta meg a RelayState param\u00e9tert, amely azt hat\u00e1rozza meg, hogy hov\u00e1 ir\u00e1ny\u00edtsuk tov\u00e1bb.", "fi": "Pyynn\u00f6n luoja ei tarjonnut RelayState arvoa, joka ilmaisisi minne jatkaa.", "pt-br": "O promotor deste pedido n\u00e3o fornecer um par\u00e2metro RelayState indicando o local para onde seguir.", "pt": "Este pedido foi iniciado sem o par\u00e2metro RelayState necess\u00e1rio para continuar com o processamento.", "cs": "P\u016fvodce t\u00e9to \u017e\u00e1dosti nezadal parametr RelayState, kter\u00fd ur\u010duje kam d\u00e1l.", "tr": "Bu iste\u011fin ba\u015flat\u0131c\u0131s\u0131, bir sonraki gidi\u015f yerini bildiren RelayState parametresini sa\u011flamam\u0131\u015f.", "lt": "\u0160ios u\u017eklausos iniciatorius nepateik\u0117 perdavimo statuso parametro, kuris nusako kur toliau kreiptis.", "it": "Chi ha iniziato la richiesta non ha fornito un parametro RelayState per specificare come proseguire dopo il login.", "zh-tw": "\u521d\u59cb\u5316\u8acb\u6c42\u4e26\u672a\u63d0\u4f9b\u4e00\u500b\u4e2d\u7e7c\u72c0\u614b RelayState \u53c3\u6578\u8aaa\u660e\u4e0b\u4e00\u500b\u6b65\u9a5f\u3002", "ja": "\u30ea\u30af\u30a8\u30b9\u30c8\u751f\u6210\u6642\u306b\u306fRelayState\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3092\u63d0\u4f9b\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "et": "Selle p\u00e4ringu algataja ei t\u00e4itnud RelayState parameetrit, mis n\u00e4itab, kuhu edasi minna.", "he": "\u05d9\u05d5\u05d6\u05dd \u05d4\u05d1\u05e7\u05e9\u05d4 \u05dc\u05d0 \u05e1\u05d9\u05e4\u05e7 \u05e4\u05e8\u05de\u05d8\u05e8 RelayState \u05d4\u05de\u05e6\u05d9\u05d9\u05df \u05dc\u05d0\u05df \u05dc\u05dc\u05db\u05ea .", "zh": "\u8fd9\u4e2a\u8bf7\u6c42\u7684\u53d1\u8d77\u4eba\u6ca1\u6709\u63d0\u4f9bRelayState\u53c2\u6570\uff0c\u4ee5\u8bf4\u660e\u4e0b\u4e00\u6b65\u5904\u7406", "sr": "Servis koji je inicirao ovaj zahtjev nije poslao RelayState parametar koji sadr\u017ei adresu na koju treba preusmeriti korisnikov web pretra\u017eiva\u010d nakon uspe\u0161ne autentifikacije.", "pl": "Inicjator zlecenia nie dostarczy\u0142 parametru RelayState, wskazuj\u0105cego, gdzie przekaza\u0107 zlecenie.", "ar": "\u0644\u0645 \u064a\u0648\u0641\u0631 \u0637\u0627\u0644\u0628 \u0627\u0644\u062e\u062f\u0645\u0629 \u062e\u0635\u0627\u0626\u0635 \u062a\u0642\u0648\u064a\u0629 \u062a\u0642\u0648\u062f \u0644\u0644\u062e\u0637\u0648\u0629 \u0627\u0644\u062a\u0627\u0644\u064a\u0629", "lv": "Piepras\u012bjuma veidot\u0101js nav nor\u0101d\u012bjis RelayState parametru, kas par\u0101d\u012btu, kurp iet t\u0101l\u0101k.", "id": "Inisiator dari request ini tidak menyediakan parameter RelayState yang mengindikasikan kemana selanjutnya pergi.", "ro": "Ini\u021biatorul acestei cereri nu a furnizat parametrul RelayState<\/i> care indic\u0103 urm\u0103torul pas.", "ru": "\u0418\u043d\u0438\u0446\u0438\u0430\u0442\u043e\u0440 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 RelayState \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430.", "eu": "Eskaera honen abiarazleak ez du ematen ondoren nora joan adierazten duen RelayState parametroa", "af": "Die inisieerder van hierdie versoek het nie 'n aflos staat('RelayState') parameter wat aandui waarheen om volgende te gaan nie.", "el": "\u0397 \u03c0\u03b1\u03c1\u03ac\u03bc\u03b5\u03c4\u03c1\u03bf\u03c2 'RelayState' \u03c4\u03bf\u03c5 \u03c0\u03c1\u03c9\u03c4\u03bf\u03ba\u03cc\u03bb\u03bb\u03bf\u03c5 SAML \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5 \u03ae \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03bc\u03b5 \u03b1\u03c0\u03bf\u03c4\u03ad\u03bb\u03b5\u03c3\u03bc\u03b1 \u03bd\u03b1 \u03bc\u03b7\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03bc\u03b5\u03c4\u03ac\u03b2\u03b1\u03c3\u03b7 \u03c3\u03b5 \u03ba\u03ac\u03c0\u03bf\u03b9\u03bf\u03bd \u03c0\u03cc\u03c1\u03bf \u03c4\u03bf\u03c5 \u03c0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd0.", "xh": "Umqalisi wesi sicelo akanikelanga ngepharamitha ye-RelayState apho kufanele kuyiwe khona.", "zu": "Umqalisi walesi sicelo akazange ahlinzeke ngepharamitha ye-RelayState ebonisa ukuthi kufanele uye kuphi ngokulandelayo.", "st": "Moqadi wa kopo ena ha a fana pharamitha ya RelayState e bontshang hore ho uwe kae ho tloha mona.", "ca": "L’iniciador d’aquesta sol·licitud no ha proporcionat un paràmetre de RelayState que indiqui on seguirà." }, "title_PROCESSASSERTION": { "no": "Feil i behandling av svar fra innloggingstjenesten", "nn": "Feil under handtering av svar fr\u00e5 IdP", "sv": "Fel vid bearbetning av svar fr\u00e5n IdP", "es": "Error al procesar la respuesta procedente del IdP", "fr": "Erreur lors du traitement de la r\u00e9ponse de l'IdP", "de": "Fehler beim Bearbeiten der Antwort des IdP", "nl": "Fout in IdP response", "lb": "Fehler beim Bearbeschten vun de Aentwert vum IdP", "sl": "Pri obdelavi odgovora IdP-ja je pri\u0161lo do napake", "da": "Fejl i behandlingen af svar fra Identitetsudbyder", "hr": "Gre\u0161ka prilikom obrade odgovora pristiglog od autentifikacijskog servisa", "hu": "IdP v\u00e1lasz feldolgoz\u00e1si hiba", "fi": "Identiteetintarjoan vastauksen k\u00e4sittely ep\u00e4onnistui.", "pt-br": "Erro processando a resposta do Provedor de Identidade.", "pt": "Erro ao processar a resposta do fornecedor de identidade (IdP)", "pl": "B\u0142\u0105d przetwarzania odpowiedzi od Dostawcy To\u017csamo\u015bci", "cs": "Chyba zpracov\u00e1n\u00ed odpov\u011bdi od poskytovatele identity", "tr": "Kimlik sa\u011flay\u0131c\u0131dan gelen cevab\u0131 i\u015flerken hata", "lt": "Klaida apdorojant u\u017eklaus\u0105 i\u0161 tapatybi\u0173 teik\u0117jo", "it": "Errore nell'elaborazione della risposta ricevuta dall'Identity Provider.", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u304b\u3089\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u5f9e\u9a57\u8b49\u63d0\u4f9b\u8005\u53d6\u5f97\u932f\u8aa4\u57f7\u884c\u56de\u61c9", "et": "T\u00f5rge identiteedipakkuja vastuse t\u00f6\u00f6tlemisel", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05e2\u05d9\u05d1\u05d5\u05d3 \u05ea\u05d2\u05d5\u05d1\u05d4 \u05de\u05e1\u05e4\u05e7 \u05d4\u05d6\u05d4\u05d5\u05ea", "zh": "\u5904\u7406\u6765\u81ea\u8eab\u4efd\u63d0\u4f9b\u8005\u7684\u5e94\u7b54\u65f6\u51fa\u9519", "sr": "Gre\u0161ka pri obradi odgovora koji je poslao Davalac Identeteta", "ar": "\u062e\u0637\u0627 \u0628\u0625\u062c\u0631\u0627\u0621\u0627\u062a \u0645\u0639\u0627\u0645\u0644\u0629 \u0625\u062c\u0627\u0628\u0627\u062a \u0645\u0642\u062f\u0645 \u0627\u0644\u0647\u0648\u064a\u0629", "lv": "Identit\u0101tes pieg\u0101d\u0101t\u0101ja atbildes apstr\u0101des k\u013c\u016bda", "id": "Error memproses response dari Identity Provider.", "ro": "Eroare la procesarea r\u0103spunsului primit de la furnizorul de identitate", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0442\u043a\u043b\u0438\u043a\u0430 \u043e\u0442 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438", "eu": "Errorea IdP-tik datorren erantzuna prozesatzean", "af": "Fout in die Identiteits Verskaffer(IdP) versoek", "el": "\u0395\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03b7 \u03b1\u03c0\u03cc\u03ba\u03c1\u03b9\u03c3\u03b7 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2", "xh": "Impazamo iprosesa impendulo esuka kuMboneleli Wesazisi", "zu": "Iphutha lokucubungula impendulo esuka Kumhlinzeki Kamazisi", "st": "Phoso ho sebetseng karabelo ho tswa ho Mofani wa Boitsebiso", "ca": "S'ha produït un error en processar la resposta del proveïdor d’identitat" }, "descr_PROCESSASSERTION": { "no": "Svaret mottatt fra innloggingstjenesten kan ikke aksepteres.", "nn": "Svaret fr\u00e5 IdP var ikkje akseptabelt for oss", "sv": "Svaret fr\u00e5n identitetshanteraren (Identity Provider) \u00e4r inte accepterat.", "es": "No ha sido posible aceptar la respuesta enviada por el proveedor de identidad.", "fr": "Nous n'avons pas accept\u00e9 la r\u00e9ponse envoy\u00e9e par le fournisseur d'identit\u00e9.", "de": "Die Antwort des Identitiy Provider konnte nicht akzeptiert werden.", "nl": "Het antwoord van de Identity Provider is niet geaccepteerd.", "lb": "Mer konnten d Aentwert vum Identity Provider net akzept\u00e9iren", "sl": "Odgovor, poslan od IdP-ja, ni bil sprejet.", "da": "Svaret fra Identitetsudbydere kunne ikke accepteres", "hr": "Nije prihva\u0107en odgovor koji je poslao autentifikacijski servis.", "hu": "Nem fogadtuk el a szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (IdP) \u00e1ltal k\u00fcld\u00f6tt v\u00e1lasz\u00fczenetet.", "fi": "Emme hyv\u00e4ksyneet identiteetintarjoajan vastausta.", "pt-br": "N\u00f3s n\u00e3o aceitamos a resposta enviada pelo Provedor de Identidade.", "pt": "A resposta emitida pelo fornecedor de identidade n\u00e3o foi aceite.", "pl": "Nie zakceptowali\u015bmy odpowiedzi wys\u0142anej przez Dostawc\u0119 To\u017csamo\u015bci.", "cs": "Neakceptujeme odpov\u011b\u010f zaslanou poskytovatelem identity.", "tr": "Kimlik Sa\u011flay\u0131c\u0131'dan gelen cevab\u0131 kabul etmedik.", "lt": "Mes nepriimame u\u017eklausos, si\u0173stos i\u0161 tapatybi\u0173 teik\u0117jo.", "it": "Non \u00e8 stata accettata una risposta proveniente dall'Identity Provider.", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u304b\u3089\u9001\u4fe1\u3055\u308c\u305f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u53d7\u3051\u4ed8\u3051\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "zh-tw": "\u6211\u5011\u7121\u6cd5\u65bc\u9a57\u8b49\u63d0\u4f9b\u8005\u5b8c\u6210\u56de\u61c9\u50b3\u9001\u3002", "et": "Identiteedipakkuja poolt saadetud vastust ei aktsepteeritud.", "he": "\u05dc\u05d0 \u05e7\u05d9\u05d1\u05dc\u05e0\u05d5 \u05d0\u05ea \u05d4\u05ea\u05d2\u05d5\u05d1\u05d4 \u05e9\u05e0\u05e9\u05dc\u05d7\u05d4 \u05de\u05e1\u05e4\u05e7 \u05d4\u05d6\u05d4\u05d5\u05ea.", "zh": "\u6211\u4eec\u4e0d\u63a5\u53d7\u6765\u81ea\u8eab\u4efd\u63d0\u4f9b\u8005\u7684\u5e94\u7b54", "sr": "Odgovor koji je poslao Davalac Identiteta nije prihva\u0107en.", "ar": "\u0644\u0645 \u0646\u0642\u0628\u0644 \u0625\u062c\u0627\u0628\u0627\u062a \u0645\u0642\u062f\u0645 \u0627\u0644\u0647\u0648\u064a\u0629", "lv": "Netiek akcept\u0113ta atbilde no identit\u0101tes pieg\u0101d\u0101t\u0101ja.", "id": "Kami tidak menerima response yang dikirimlan dari Identity Provider.", "ro": "R\u0103spunsul de la acest furnizor de identitate nu a fost acceptat.", "ru": "\u041e\u0442\u043a\u043b\u0438\u043a \u043e\u0442 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d.", "eu": "Ezin izan da identitatearen hornitzaileak bidalitako erantzuna onartu.", "af": "Die antwoord vanaf die Indentiteits Verskaffer is nie aanvaar nie.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 \u03c4\u03b7\u03c2 \u03b1\u03c0\u03ac\u03bd\u03c4\u03b7\u03c3\u03b7\u03c2 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2.", "zu": "Asizange samukele impendulo ethunyelwe ukusuka Kumhlinzeki Kamazisi.", "xh": "Asiyamkelanga impendulo ethunyelwe ukusuka kuMboneleli Wesazisi.", "st": "Ha re a amohela karabelo ho tswa ho Mofani wa Boitsebiso.", "ca": "La resposta enviada pel proveïdor d’identitat no ha estat acceptada." }, "title_PROCESSAUTHNREQUEST": { "no": "Feil ved behandling av foresp\u00f8rsel fra SP", "nn": "Feil under handtering av svar fr\u00e5 tenesteleverand\u00f8r (SP)", "sv": "Fel vid bearbetning av f\u00f6rfr\u00e5gan fr\u00e5n en tj\u00e4nsteleverant\u00f6r (Service Provider)", "es": "Error al procesar la solicitud del proveedor de servicio", "fr": "Erreur lors du traitement de la requ\u00eate du fournisseur d'identit\u00e9", "de": "Fehler beim Bearbeiten der Anfrage des Service Providers", "nl": "Fout in Service Provider request", "lb": "Fehler beim Bearbeschten vun der Unfro vum Service Provider", "sl": "Napaka pri obdelavi zahteve SP", "da": "Fejl i behandlingen foresp\u00f8rgsel fra Tjeneste Udbyder", "hr": "Gre\u0161ka prilikom obrade autentifikacijskog zahtjeva", "hu": "Hib\u00e1s SP \u00fczenet", "fi": "Palveluntarjoajan pyynnin k\u00e4sittelyss\u00e4 tapahtui virhe.", "pt-br": "Erro processando o pedido do Provedor de Servi\u00e7os.", "pt": "Erro ao processar o pedido do fornecedor de servi\u00e7o (SP)", "pl": "B\u0142\u0105d przetwarzania \u017c\u0105dania od Dostawcy Serwisu", "cs": "Chyba prov\u00e1d\u011bn\u00ed \u017e\u00e1dosti poskytovatele slu\u017eby", "tr": "Servis Sa\u011flay\u0131c\u0131'dan gelen iste\u011fi i\u015flerken hata", "lt": "Klaida siun\u010diant u\u017eklaus\u0105 i\u0161 paslaug\u0173 teik\u0117jo", "it": "Errore nell'elaborazione della richiesta dal Service Provider", "ja": "\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u304b\u3089\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f", "zh-tw": "\u5f9e\u9a57\u8b49\u63d0\u4f9b\u8005\u5f97\u5230\u932f\u8aa4\u57f7\u884c\u8acb\u6c42", "et": "T\u00f5rge teenusepakkuja p\u00e4ringu t\u00f6\u00f6tlemisel", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05e2\u05d9\u05d1\u05d5\u05d3 \u05ea\u05d2\u05d5\u05d1\u05d4 \u05de\u05e1\u05e4\u05e7 \u05d4\u05e9\u05e8\u05d5\u05ea", "zh": "\u5904\u7406\u6765\u81ea\u670d\u52a1\u63d0\u4f9b\u8005\u7684\u8bf7\u6c42\u65f6\u51fa\u9519", "sr": "Gre\u0161ka prilikom obrade zahteva koji je poslao Davalac Servisa", "ar": "\u062e\u0637\u0627 \u0628\u0645\u0639\u0627\u0645\u0644\u0629 \u0637\u0644\u0628 \u0645\u0642\u062f\u0645 \u0627\u0644\u062e\u062f\u0645\u0629", "lv": "Servisa pieg\u0101d\u0101t\u0101ja piepras\u012bjuma apstr\u0101des k\u013c\u016bda", "id": "Error memproses request dari Service Provider", "ro": "Eroare la procesarea r\u0103spunsului primit de la furnizorul de servicii", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430", "eu": "Errorea zerbitzu hornitzailearen eskaera prozesatean ", "af": "Fout in Diens Verskaffer versoek proses", "el": "\u0395\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03bf \u03b1\u03af\u03c4\u03b7\u03bc\u03b1 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd", "xh": "Impazamo iprosesa isicelo esisuka kuMboneleli Wenkonzo", "zu": "Iphutha lokucubungula isicelo esisuka Kumhlinzeki Wesevisi", "st": "Phoso ho sebetseng kopo ho tswa ho Mofani wa Tshebeletso", "ca": "S'ha produït un error en processar la sol·licitud del proveïdor de serveis" }, "descr_PROCESSAUTHNREQUEST": { "no": "Innloggingstjenesten mottok en autentiserings-foresp\u00f8rsel fra en tjeneste, men en feil oppsto i behandling av foresp\u00f8rselen.", "nn": "Denne identitetsleverand\u00f8ren (IdP) mottok ei autentiseringsmelding fr\u00e5 ein tenesteleverand\u00f8r (SP), men det oppsto ein feil under handteringa av meldinga", "sv": "Identitetshanteraren (Identity Provider) har tagit emot en inloggningsf\u00f6rfr\u00e5gan fr\u00e5n en tj\u00e4nsteleverant\u00f6r (Service Provider) men ett fel uppstod vid bearbetningen av f\u00f6rfr\u00e5gan.", "es": "Este IdP ha recibido una petici\u00f3n de autenticaci\u00f3n de un proveedor de servicio pero se ha producido un error al tratar de procesar la misma.", "fr": "Ce fournisseur de service a re\u00e7u une requ\u00eate d'authentification d'un fournisseur d'identit\u00e9, mais une erreur s'est produite lors du traitement de cette requ\u00eate.", "de": "Dieser Identity Provider hat eine Authentifizierungsanfrage von einem Service Provider erhalten, aber es ist ein Fehler beim Bearbeiten dieser Anfrage aufgetreten.", "nl": "Deze IdP heeft een authenticatie verzoek ontvangen van een Service Provider, maar er is een fout opgetreden bij het verwerken ervan.", "lb": "D\u00ebsen IdP kruut eng Authenticatiounsunfro vun engem Service provider, mais et gouf en Fehler w\u00e9i d\u00e9i sollt bearbescht gin.", "sl": "IdP je prejel avtenticirano zahtevo SP-ja, vendar je pri\u0161lo do napake pri obdelavi te zahteve.", "da": "Denne IdP har modtaget en anmodning om single sign-on fra en tjeneste udbyder, men der opstod en fejl under behandlingen af denne anmodning.", "hr": "Autentifikacijski servis je dobio zahtjev od davatelja usluge, ali se pojavila gre\u0161ka prilikom obrade zahtjeva.", "hu": "Az IdP azonos\u00edt\u00e1si k\u00e9r\u00e9st kapott az SP-t\u0151l, de ennek feldolgoz\u00e1sa sor\u00e1n hiba t\u00f6rt\u00e9nt.", "fi": "Identiteetintarjoaja sai tunnistautumispyynn\u00f6n palveluntarjoajalta, mutta pyynnin k\u00e4sittelyss\u00e4 tapahtui virhe.", "pt-br": "Este Provedor de Identidade recebeu um Pedido de Autentica\u00e7\u00e3o de um Provedor de Servi\u00e7os, mas um erro ocorreu ao tentar processar o pedido.", "pt": "Ocorreu um erro ao processar o pedido de autentica\u00e7\u00e3o emitido pelo fornecedor de servi\u00e7o.", "cs": "Tento poskytovatel identity p\u0159ijal po\u017eadavek od poskytovatele slu\u017eby, ale p\u0159i jeho prov\u00e1den\u00ed vznikla chyba.", "tr": "Bu Kimlik Sa\u011flay\u0131c\u0131 bir Servis Sa\u011flay\u0131c\u0131'dan kimlik do\u011frulama iste\u011fi ald\u0131, ancak bu iste\u011fi i\u015flemeye \u00e7al\u0131\u015f\u0131rken bir hata olu\u015ftu.", "lt": "\u0160is tapatybi\u0173 tiek\u0117jas gavo autentikacijos pra\u0161ymo u\u017eklaus\u0105 i\u0161 paslaugos teik\u0117jo, ta\u010diau apdorojant prane\u0161im\u0105 \u012fvyko klaida.", "it": "Questo Identity Provider ha ricevuto una richiesta di autenticazione da parte di un Service Provider, ma si \u00e8 verificato un errore durante l'elaborazione di quest'ultima", "ja": "\u3053\u306e\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u306f\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\u304b\u3089\u306e\u8a8d\u8a3c\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u53d7\u3051\u4ed8\u3051\u307e\u3057\u305f\u304c\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u51e6\u7406\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u9019\u500b\u9a57\u8b49\u63d0\u4f9b\u8005\u6536\u5230\u4e00\u500b\u670d\u52d9\u63d0\u4f9b\u8005\u7684\u8a8d\u8b49\u8acb\u6c42\uff0c\u4f46\u5728\u6e96\u5099\u57f7\u884c\u9019\u500b\u8acb\u6c42\u6642\u767c\u751f\u932f\u8aa4\u3002", "et": "Identiteedipakkuja sai teenusepakkujalt autentimisp\u00e4ringu, kui p\u00e4ringu t\u00f6\u00f6tlemisel tekkis t\u00f5rge.", "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05d6\u05d4 \u05e7\u05d9\u05d1\u05dc \u05d1\u05e7\u05e9\u05ea \u05d4\u05d6\u05d3\u05d4\u05d5\u05ea \u05de\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea, \u05d0\u05d5\u05dc\u05dd \u05e7\u05e8\u05ea\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d6\u05de\u05df \u05e2\u05d9\u05d1\u05d5\u05d3 \u05d4\u05d1\u05e7\u05e9\u05d4.", "zh": "\u8be5\u8eab\u4efd\u63d0\u4f9b\u8005\u63a5\u53d7\u5230\u4e86\u4e00\u4e2a\u6765\u81ea\u670d\u52a1\u63d0\u4f9b\u8005\u7684\u8ba4\u8bc1\u8bf7\u6c42\uff0c\u4f46\u662f\u5728\u8bd5\u56fe\u5904\u7406\u8be5\u8bf7\u6c42\u7684\u8fc7\u7a0b\u4e2d\u53d1\u751f\u4e86\u9519\u8bef", "sr": "Davalac Identiteta je primio zahtev za autentikacijom od strane Davaoca Servisa, ali se javila gre\u0161ka prilikom poku\u0161aja obrade ovog zahteva.", "pl": "Dostawca to\u017csamo\u015bci otrzyma\u0142 od dostawcy us\u0142ugi zlecenie uwierzytelnienia, ale wyst\u0105pi\u0142 b\u0142\u0105d podczas przetwarzania zlecenia.", "ar": "\u062d\u0635\u0644 \u0645\u0642\u062f\u0645 \u0627\u0644\u0647\u0648\u064a\u0629 \u0647\u0630\u0627 \u0639\u0644\u064a \u0637\u0644\u0628 \u062a\u0648\u062b\u064a\u0642 \u0645\u0646 \u0645\u0642\u062f\u0645 \u0627\u0644\u062e\u062f\u0645\u0629 \u0644\u0643\u0646 \u062d\u062f\u062b \u062e\u0637\u0627 \u0628\u0627\u0644\u0625\u062c\u0631\u0627\u0621\u0627\u062a ", "lv": "Identit\u0101tes pieg\u0101d\u0101t\u0101js ir sa\u0146\u0113mis autentifik\u0101cijas piepras\u012bjumu no servisa pieg\u0101d\u0101t\u0101ja, bet to apstr\u0101d\u0101jot rad\u0101s k\u013c\u016bda.", "id": "Identity Provider ini menerima Request Autentifikasi dari sebuah Service Provider, tetapi error terjadi ketika memproses request.", "ro": "Acest furnizor de identitate a primit o cerere de autentificare de la un furnizor de servicii, dar a ap\u0103rut o eroare la procesarea cererii.", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430, \u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.", "eu": "IdP honek zerbitzu hornitzaile baten kautotze eskaera jaso du baina errore bat jazo da hau prozesatzen saiatzean.", "af": "Die Identiteits Verskaffer het 'n Verifikasie Versoek ontvang vanaf 'n Diens Verskaffer maar 'n fout het voorgekom tydens die verwerking van die versoek.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2 \u03c0\u03bf\u03c5 \u03ad\u03bb\u03b1\u03b2\u03b5 \u03bf \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd.", "zu": "Lo Mhlinzeki Kamazisi uthole Isicelo Sokuqinisekisa ukusuka Kumhlinzeki Wesevisi, kodw,a kuvele iphutha ngenkathi ezama ukucubungula isicelo.", "xh": "Lo Mboneleli Wesazisi ufumene Isicelo Songqinisiso esisuka kuMboneleli Wenkonzo, kodwa kwenzeke impazamo xa kuzanywa ukuprosesa isicelo.", "st": "Mofani enwa wa Boitsebiso o fumane Kopo ya Netefatso ho tswa ho Mofani wa Tshebeletso, empa ho bile le phoso ha ho leka ho fihlellwa kopo.", "ca": "Aquest proveïdor d’identitat ha rebut una sol·licitud d’autenticació d’un proveïdor de serveis, però s’ha produït un error en intentar processar la sol·licitud." }, "title_SLOSERVICEPARAMS": { "no": "Ingen SAML-melding angitt", "nn": "Fann ikkje SAML-melding", "sv": "Inget SAML-meddelande tillhandah\u00f6lls", "es": "Falta el mensaje SAML", "fr": "Aucun message SAML fourni", "de": "Keine SAML Nachricht bereit gestellt", "nl": "Geen SAML bericht gevonden", "lb": "Keen SAML message unginn", "sl": "SAML sporo\u010dilo ni na voljo", "da": "Ingen SAML besked", "hr": "Nije dostavljena nikakva SAML poruka", "hu": "Hi\u00e1nyz\u00f3 SAML \u00fczenet", "fi": "SAML-viesti puuttui", "pt-br": "N\u00e3o fornecida a mensagem SAML", "pt": "Mensagem SAML n\u00e3o fornecida", "cs": "\u017d\u00e1dn\u00e1 SAML zpr\u00e1va nebyla zasl\u00e1na", "tr": "SAML mesaj\u0131 verilmemi\u015f", "lt": "Nepateikta SAML \u017einut\u0117", "it": "Nessun messaggio SAML fornito", "ja": "SAML\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u3042\u308a\u307e\u305b\u3093", "zh-tw": "\u7121\u6cd5\u63d0\u4f9b SAML \u8a0a\u606f", "et": "SAML-teade puudub", "he": "\u05dc\u05d0 \u05e1\u05d5\u05e4\u05e7\u05d5 \u05d4\u05d5\u05d3\u05e2\u05d5\u05ea SAML", "zh": "\u6ca1\u6709\u63d0\u4f9bSAML\u6d88\u606f", "sr": "Nije dostavljena SAML poruka", "pl": "Nie dostarczono komunikatu SAML", "ar": "\u0644\u0645 \u064a\u062a\u0645 \u062a\u0642\u062f\u064a\u0645 \u0631\u0633\u0627\u0644\u0629 SAML", "lv": "Nav SAML zi\u0146ojuma", "id": "Tidak pesan SAML yang disediakan", "ro": "Nu a fost furnizat mesajul SAML", "ru": "\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 SAML ", "eu": "SAML mezua falta da", "af": "Geen SAML boodskap gevind nie", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03c0\u03b1\u03c6\u03ae SingleLogoutService", "zu": "Awukho umlayezo we-SAML onikeziwe", "xh": "Akukho myalezo we-SAML unikelweyo", "st": "Ha ho molaetsa wa SAML o fanweng", "ca": "No s’ha proporcionat cap missatge SAML" }, "descr_SLOSERVICEPARAMS": { "no": "Du brukte SingleLogoutService-grensesnittet uten \u00e5 angi enten en SAML LogoutRequest eller en LogoutResponse.", "nn": "Du har bruk utloggingstenesta (SingleLogoutService), men har ikkje sendt utloggingsmelding (SAML LogoutRequest) eller utloggingssvar (SAML LogoutResponse)", "sv": "Du har anroppat tj\u00e4nsten f\u00f6r Single Sing-Out utan att skicka med n\u00e5gon SAML LogoutRequest eller LogoutResponse.", "es": "Usted accedi\u00f3 a la interfaz SingleLogoutService pero no incluy\u00f3 un mensaje SAML LogoutRequest o LogoutResponse", "fr": "Vous avez acc\u00e9d\u00e9 \u00e0 l'interface SingleLogoutService, mais vous n'avez pas fourni de LogoutRequest ou LogoutResponse SAML.", "de": "Sie haben auf die SingleLogoutService Schnittstelle zugegriffen, aber keine SAML Abmeldeanfrage oder Abmeldeantwort bereit gestellt.", "nl": "Je hebt de SingleLogoutService interface aangeroepen, maar hebt geen SAML LogoutRequest of LogoutResponse meegestuurd.", "lb": "Der hud den SingleLogoutService acc\u00e9d\u00e9iert mais ken SAML LogoutRequest oder LogoutResponse unginn.", "sl": "Dostopili ste do SingleLogoutService vmesnika, ampak niste zagotovili SAML LogoutRequest ali LogoutResponse.", "da": "Du fors\u00f8ger at tilg\u00e5 Single Logout gr\u00e6nsefladen, uden at sendet et SAML LogoutRequest eller LogoutResponse", "hr": "Pristupili ste su\u010delju za odjavljivanje iz sustava jedinstvene autentifikacije, ali niste dostavili SAML LogoutRequest ili LogoutResponse poruku.", "hu": "A Single Logout interf\u00e9szen vagy SAML LogoutRequest vagy LogoutResponse \u00fczenetet kell megadni.", "fi": "Yritit kertauloskirjautumisliittym\u00e4\u00e4n, mutta et tarjonnut SAML LogoutRequest:i\u00e4 tai LogoutRespons:ia.", "pt-br": "Voc\u00ea acessou a interface do SingleLogoutService, mas n\u00e3o forneceu a SAML LogoutRequest ou LogoutResponse.", "pt": "Na interface SingleLogoutService deve fornecer uma mensagem SAML do tipo LogoutRequest ou LogoutResponse.", "cs": "P\u0159istupujete k SingleLogoutService rozhran\u00ed, ale nezad\u00e1v\u00e1te SAML LogoutRequest, nebo LogoutResponse.", "tr": "Tekli\u00c7\u0131k\u0131\u015fServis (SingleLogoutService) aray\u00fcz\u00fcne giri\u015f yapt\u0131n\u0131z, ancak bir SAML \u00c7\u0131k\u0131\u015f\u0130ste\u011fi ya da \u00c7\u0131k\u0131\u015fCevab\u0131 sa\u011flamad\u0131n\u0131z.", "lt": "J\u016bs pasiek\u0117te SingleLogoutService paslaug\u0105, ta\u010diau nepateik\u0117te SAML LogoutRequest ar LogoutResponse u\u017eklaus\u0173.", "it": "Hai acceduto all'interfaccia di SingleLogoutService, ma senza fornire un messaggio SAML di LogoutRequest o LogoutResponse.", "zh-tw": "\u60a8\u9023\u7d50\u55ae\u4e00\u767b\u51fa\u670d\u52d9\u754c\u9762\uff0c\u4f46\u662f\u6c92\u6709\u63d0\u4f9b\u4e00\u500b SAML \u767b\u51fa\u8acb\u6c42\u6216\u767b\u51fa\u56de\u61c9\u3002\u8acb\u6ce8\u610f\uff0c\u8a72\u7aef\u9ede\u4e26\u975e\u76f4\u63a5\u9023\u7dda\u3002", "ja": "SingleLogoutService\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3078\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3057\u305f\u304c\u3001SAML LogoutRequest \u3084 LogoutResponse \u304c\u63d0\u4f9b\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "et": "Sa k\u00fclastasid SingleLogoutService liidest, kui ei pakkunud SAML LogoutRequest v\u00f5i LogoutResponse.", "he": "\u05e0\u05d9\u05d2\u05e9\u05ea \u05dc\u05de\u05de\u05e9\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05d4\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05d4\u05db\u05dc\u05dc\u05d9\u05ea, \u05d0\u05d1\u05dc \u05dc\u05d0 \u05e1\u05d9\u05e4\u05e7\u05ea \u05d1\u05e7\u05e9\u05ea \u05d0\u05d5 \u05ea\u05d2\u05d5\u05d1\u05ea \u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05e9\u05dc SAML.", "zh": "\u4f60\u8bbf\u95ee\u4e86SingleLogoutService\u63a5\u53e3\uff0c\u4f46\u662f\u5e76\u6ca1\u6709\u63d0\u4f9b\u4e00\u4e2aSAML\u7684LogoutRequest\u6216\u8005LogoutResponse", "sr": "Pristupili ste interfejsu za jedinstvenu odjavu sa sistema, ali niste poslali SAML LogoutRequest<\/i> ili LogoutResponse<\/i> poruku.", "pl": "Zosta\u0142a wywo\u0142ana us\u0142uga SingleLogoutService, ale nie dostarczono komunikatu SAML LogoutRequest lub LogoutResponse.", "ar": "\u0644\u0642\u062f \u0648\u0635\u0644\u062a \u0644\u0646\u0642\u0637\u0629 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0627\u0644\u0645\u0648\u062d\u062f \u0644\u0643\u0646\u0643 \u0644\u0645 \u062a\u0648\u0641\u0631 \u0637\u0644\u0628 \u062a\u0633\u062c\u064a\u0644 \u062e\u0631\u0648\u062c SAML \u0627\u0648 \u0627\u0633\u062a\u062c\u0627\u0628\u0629 \u0644\u0637\u0644\u0628 \u0627\u0644\u062e\u0631\u0648\u062c", "lv": "J\u016bs izmantojat SingleLogoutService interfeisu, bet neesat devis SAML atsl\u0113g\u0161an\u0101s piepras\u012bjumu vai atsl\u0113g\u0161an\u0101s atbildi.", "id": "Anda mengakses antarmuka SingleLogout, tetapi tidak menyediakan LogoutRequest SAML atau LogoutResponse.", "ro": "A\u021bi accesat interfa\u021ba SingleLogoutService<\/i>, dar nu a\u021bi furnizat o cerere de deautentificare sau un r\u0103spuns de deautentificare SAML.", "ru": "\u0412\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 SingleLogoutService, \u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 SAML LogoutRequest \u0438\u043b\u0438 LogoutResponse \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.", "eu": "SingleLogoutService interfazera sartu zara baina ez duzu erantsi SAML LogoutRequest edo LogoutResponse mezurik", "af": "Jy het toegang verkry na die SingleLogoutService koppelvlak('interface'), maar het geen SAML LogoutRequest of LogoutResponse gestuur nie.", "el": "\u039a\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03ae \u03c3\u03b1\u03c2 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03c0\u03b1\u03c6\u03ae SingleLogoutService \u03c0\u03b1\u03c1\u03b1\u03bb\u03b5\u03af\u03c8\u03b1\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bc\u03c0\u03b5\u03c1\u03b9\u03bb\u03ac\u03b2\u03b5\u03c4\u03b5 \u03bc\u03ae\u03bd\u03c5\u03bc\u03b1 LogoutRequest \u03ae LogoutResponse \u03c4\u03bf\u03c5 \u03c0\u03c1\u03c9\u03c4\u03bf\u03ba\u03cc\u03bb\u03bb\u03bf\u03c5 SAML. \u03a3\u03b7\u03bc\u03b5\u03b9\u03ce\u03c3\u03c4\u03b5 \u03cc\u03c4\u03b9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c4\u03b5\u03bb\u03b9\u03ba\u03cc \u03c3\u03b7\u03bc\u03b5\u03af\u03bf (endpoint) \u03b4\u03b5\u03bd \u03c0\u03c1\u03bf\u03bf\u03c1\u03af\u03b6\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ac\u03bc\u03b5\u03c3\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b2\u03ac\u03c3\u03b9\u03bc\u03bf.", "zu": "Ufinyelele ukusebenzisana kwe-SingleLogoutService, kodwa awuzange uhlinzeke nge-SAML LogoutRequest noma i-LogoutResponse. Sicela uphawule ukuthi isiphetho asihloselwe ukufinyelelwa ngokuqondile.", "xh": "Ufikelele i-intafeyisi ye-SingleLogoutService, kodwa awukhange unikele i-SAML LogoutRequest okanye i-LogoutResponse. Nceda uqaphele ukuba le ndawo yokuphela ayilungiselelwanga ukuba ifikelelwe ngokuthe ngqo.", "st": "O fihletse tshebeletsano ya SingleLogoutService, empa ha o a fana ka SAML LogoutRequest kapa LogoutResponse. Ka kopo lemoha hore ntlha ena ya bofelo ha e a rerelwa ho fihlellwa ka kotloloho.", "ca": "Heu accedit a la interfície de SingleLogoutService, però no heu proporcionat un missatge SAML de LogoutRequest ni LogoutResponse. Tingueu en compte que en aquest punt no s'hi pot accedir directament." }, "title_ACSPARAMS": { "no": "Ingen SAML-respons angitt", "nn": "Fann ikkje SAML-svar", "sv": "Inget SAML-svar tillhandah\u00f6lls", "es": "Falta la respuesta SAML", "fr": "Aucune r\u00e9ponse SAML fournie", "de": "Keine SAML Antwort bereit gestellt", "nl": "Geen SAML response gevonden", "lb": "Keng SAML Aentwert ungin", "sl": "Nobenega odgovora za SAML ni na voljo", "da": "SAML response mangler", "hr": "Nije dostavljen nikakav SAML odgovor", "hu": "Nincs SAML v\u00e1lasz", "fi": "SAML-vastaus puuttuu", "pt-br": "N\u00e3o fornecida a resposta SAML", "pt": "Mensagem SAML n\u00e3o fornecida", "cs": "\u017d\u00e1dn\u00e1 SAML odpov\u011b\u010f nebyla zasl\u00e1na", "tr": "SAML cevab\u0131 verilmemi\u015f", "lt": "Nepateiktas SAML atsakymas", "it": "Nessuna risposta SAML fornita.", "ja": "SAML\u30ec\u30b9\u30dd\u30f3\u30b9\u304c\u3042\u308a\u307e\u305b\u3093", "zh-tw": "SAML \u7121\u56de\u61c9", "et": "SAML-vastust ei pakutud", "he": "\u05dc\u05d0 \u05e1\u05d5\u05e4\u05e7\u05d4 \u05ea\u05d2\u05d5\u05d1\u05ea SAML", "zh": "\u6ca1\u6709\u63d0\u4f9bSAML\u5e94\u7b54", "sr": "Nije dostavljen SAML odgovor", "pl": "Nie dostarczo odpowiedzi SAML", "ar": "\u0644\u0627 \u062a\u0648\u062c\u062f \u0627\u0633\u062a\u062c\u0627\u0628\u0629 SAML", "lv": "Nav SAML atbildes", "id": "Tidak ada response SAML yang disediakan", "ro": "Nu a fost furnizat r\u0103spunsul SAML", "ru": "\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 SAML \u043e\u0442\u043a\u043b\u0438\u043a", "eu": "SAML erantzuna falta da", "af": "Geen SAML versoek gevind nie", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03c0\u03b1\u03c6\u03ae AssertionConsumerService", "zu": "Ayikho impendulo ye-SAML enikeziwe", "xh": "Akukho mpendulo ye-SAML inikelweyo", "st": "Ha ho karabelo ya SAML e fanweng", "ca": "No s’ha proporcionat cap resposta de SAML" }, "descr_ACSPARAMS": { "no": "Du brukte AssertionConsumerService-grensesnittet uten \u00e5 angi en SAML AuthenticationResponse.", "nn": "Du har brukt grensesnittet for mottak av meldingar (Assertion Consumer Service), men utan \u00e5 senda SAML autentiseringssvar (Authentication Response)", "sv": "Du har anropat gr\u00e4nssnittet f\u00f6r Assertion Consumer Service utan att skicka med n\u00e5gon SAML Authentication Responce.", "es": "Usted accedi\u00f3 a la interfaz consumidora de aserciones pero no incluy\u00f3 una respuesta de autenticaci\u00f3n SAML.", "fr": "Vous avez acc\u00e9d\u00e9 \u00e0 l'interface du service de traitement des assertions, mais vous n'avez pas fourni de r\u00e9ponse d'authentification SAML.", "de": "Sie haben auf die Assertion Consumer Service Schnittstelle zugegriffen, aber keine SAML Authentifizierungsantwort bereit gestellt.", "nl": "Je hebt de Assertion Consumer Service interface aangeroepen, maar hebt geen SAML Authentication Response meegestuurd.", "lb": "Der hud den Assertion Consumer Sercice Interface acc\u00e9d\u00e9iert mais keng SAML Authentication Aentwert unginn", "sl": "Dostopili ste do \"Assertion Consumer Service\" vmesnika, ampak niste zagotovili \"SAML Authentication Responsa\".", "da": "Du fors\u00f8ger at tilg\u00e5 Assertion Consumer Service gr\u00e6nsefladen uden at sende et SAML Authentication Response", "hr": "Pristupili ste su\u010delju za obradu SAML potvrda, ali niste dostavili SAML autentifikacijski odgovor.", "hu": "Az Assertion Consumer Service interf\u00e9szen SAML Authentication Response \u00fczenetet kell megadni.", "fi": "Yritit Assertion Consumer Service-liittym\u00e4\u00e4n, mutta et tarjonnut SAML tunnistautumisvastausta.", "pt-br": "Voc\u00ea acessou a interface do Assertion Consumer Service, mas n\u00e3o forneceu uma SAML Authentication Response.", "pt": "Na interface Assertion Consumer Service deve fornecer uma mensagem SAML do tipo Authentication Response.", "cs": "P\u0159istupujete k Assertion Consumer Service rozhran\u00ed, ale nepos\u00edl\u00e1late SAML Authentication Response.", "tr": "Onay Al\u0131c\u0131 Servis (Assertion Consumer Service) aray\u00fcz\u00fcne giri\u015f yapt\u0131n\u0131z, ancak SAML Kimlik Do\u011frulama Cevab\u0131 sa\u011flamad\u0131n\u0131z.", "lt": "J\u016bs pasiek\u0117te vartotoj\u0173 aptarnavimo servis\u0105, ta\u010diau nepateik\u0117te SAML autentikacijos atsakymo.", "it": "Hai acceduto all'interfaccia di Assertion Consumer Service, ma senza fornire un messaggio SAML di Authentication Response.", "zh-tw": "\u60a8\u9023\u7d50\u6d88\u8cbb\u8005\u8072\u660e\u670d\u52d9\u754c\u9762\uff0c\u4f46\u8a72\u4ecb\u9762\u672a\u63d0\u4f9b SAML \u6d88\u8cbb\u8005\u8072\u660e\u8a0a\u606f\u3002\u8acb\u6ce8\u610f\uff0c\u8a72\u7aef\u9ede\u4e26\u975e\u76f4\u63a5\u9023\u7dda\u3002", "ja": "Assertion Consumer Service\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3078\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3057\u305f\u304c\u3001SAML\u8a8d\u8a3c\u30ec\u30b9\u30dd\u30f3\u30b9\u304c\u63d0\u4f9b\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "et": "Sa k\u00fclastasid Assertion Consumer Service liidest, kuid ei pakkunud SAML autentimisvastust.", "he": "\u05e0\u05d9\u05d2\u05e9\u05ea \u05dc\u05de\u05de\u05e9\u05e7 \u05d4\u05db\u05e8\u05d6\u05ea \u05e9\u05d9\u05e8\u05d5\u05ea \u05dc\u05dc\u05e7\u05d5\u05d7, \u05d0\u05d1\u05dc \u05dc\u05d0 \u05e1\u05d9\u05e4\u05e7\u05ea \u05ea\u05d2\u05d5\u05d1\u05ea \u05d4\u05d6\u05d3\u05d4\u05d5\u05ea SAML. ", "zh": "\u4f60\u8bbf\u95ee\u4e86Assertion Consumer Service\u63a5\u53e3\uff0c\u4f46\u662f\u5e76\u6ca1\u6709\u63d0\u4f9b\u4e00\u4e2aSAML\u8ba4\u8bc1\u5e94\u7b54", "sr": "Pristupili ste sistemu za obradu SAML potvrda, ali niste dostavili SAML autentikacioni odgovor.", "pl": "Zosta\u0142a wywo\u0142ana us\u0142uga Assertion Consumer Service, ale nie dostarczono komunikatu SAML 'Authentication Response'", "ar": "\u0644\u0642\u062f \u0648\u0635\u0644\u062a \u0644\u0646\u0637\u0627\u0642 \u062a\u0623\u0643\u064a\u062f \u062e\u062f\u0645\u0629 \u0632\u0628\u0648\u0646 \u0644\u0643\u0646\u0643 \u0644\u0645 \u062a\u0648\u0641\u0631 \u0627\u0633\u062a\u062c\u0627\u0628\u0629 \u062a\u0648\u062b\u064a\u0642 SAML", "lv": "J\u016bs izmantojat Assertion Consumer Service interfeisu, bet neesat devis SAML autentifik\u0101cijas atbildi.", "id": "Anda mengakses antarnyka Assertion Consumer Service, tetapi tidak menyediakan Response Autentifikasi SAML. ", "ro": "A\u021bi accesat interfa\u021ba Assertion Consumer Service<\/i> dar nu a\u021bi furnizat r\u0103spunsul de autentificare SAML.", "ru": "\u0412\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 Assertion Consumer Service, \u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043e\u0442\u043a\u043b\u0438\u043a SAML \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.", "eu": "Baieztapen kontsumitzailearen interfazera sartu zara baina ez duzu SAML kautotze erantzun bat erantsi.", "af": "Jy het aansoek gedoen vir toegang na die Assertion Consumer Service koppelvlak, maar geen SAML Verifikasie Versoek is saam gestuur nie.", "el": "\u039a\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03ae \u03c3\u03b1\u03c2 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03c0\u03b1\u03c6\u03ae AssertionConsumerService \u03c0\u03b1\u03c1\u03b1\u03bb\u03b5\u03af\u03c8\u03b1\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bc\u03c0\u03b5\u03c1\u03b9\u03bb\u03ac\u03b2\u03b5\u03c4\u03b5 \u03b1\u03c0\u03ac\u03bd\u03c4\u03b7\u03c3\u03b7 \u03c3\u03b5 \u03b1\u03af\u03c4\u03b7\u03bc\u03b1 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 \u03c0\u03c1\u03c9\u03c4\u03bf\u03ba\u03cc\u03bb\u03bb\u03bf\u03c5 SAML. \u03a3\u03b7\u03bc\u03b5\u03b9\u03ce\u03c3\u03c4\u03b5 \u03cc\u03c4\u03b9 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03c4\u03b5\u03bb\u03b9\u03ba\u03cc \u03c3\u03b7\u03bc\u03b5\u03af\u03bf (endpoint) \u03b4\u03b5\u03bd \u03c0\u03c1\u03bf\u03bf\u03c1\u03af\u03b6\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03ac\u03bc\u03b5\u03c3\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b2\u03ac\u03c3\u03b9\u03bc\u03bf.", "zu": "Ufinyelele ukusebenzisana Kwesevisi Yomthengi Yesimemezelo, kodwa awuzange uhlinzeke Ngempendulo Yokuqinisekisa ye-SAML. Sicela uphawule ukuthi isiphetho asihloselwe ukufinyelelwa ngokuqondile.", "xh": "Ufikelele i-intafeyisi ye-Assertion Consumer Service, kodwa awukhange unikele iMpendulo Yongqinisiso ye-SAML. Nceda uqaphele ukuba le ndawo yokuphela ayilungiselelwanga ukuba ifikelelwe ngokuthe ngqo.", "st": "O fihletse kopano ya Tiiso ya Tshebeletso ya Bareki, empa ha o a fana ka Karabelo ya Netefatso ya SAML. Ka kopo lemoha hore ntlha ena ya bofelo ha e a rerelwa ho fihlellwa ka kotloloho.", "ca": "Heu accedit a la interfície Assertion Consumer Service però no heu proporcionat una resposta d’autenticació SAML. Tingueu en compte que en aquest punt no s'hi pot accedir directament." }, "title_SSOPARAMS": { "zh-tw": "\u672a\u63d0\u4f9b SAML \u8acb\u6c42", "zu": "Asikho isicelo se-SAML esinikeziwe", "xh": "Akukho sicelo se-SAML sinikelweyo", "st": "Ha ho kopo ya SAML e fanweng", "ca": "No s’ha proporcionat cap sol·licitud SAML" }, "descr_SSOPARAMS": { "zh-tw": "\u60a8\u9023\u7d50\u55ae\u4e00\u7c3d\u5165\u670d\u52d9\u4ecb\u9762\uff0c\u4f46\u672a\u63d0\u4f9b\u4e00\u500b SAML \u9a57\u8b49\u8acb\u6c42\u3002\u8acb\u6ce8\u610f\uff0c\u8a72\u7aef\u9ede\u4e26\u975e\u76f4\u63a5\u9023\u7dda\u3002", "xh": "Ufikelele i-intafeyisi ye-Single Sign On Service, kodwa awukhange unikele iMpendulo Yongqinisiso ye-SAML. Nceda uqaphele ukuba le ndawo yokuphela ayilungiselelwanga ukuba ifikelelwe ngokuthe ngqo.", "zu": "Ufinyelele ukusebenzisana Kwesevisi Yokubhalisa Okukodwa, kodwa awuzange uhlinzeke Ngempendulo Yokuqinisekisa ye-SAML. Sicela uphawule ukuthi isiphetho asihloselwe ukufinyelelwa ngokuqondile.", "st": "O fihletse tshebeletsano ya Tshaeno ya Hang, empa ha o a fan aka Kopo ya Netefatso ya SAML. Ka kopo lemoha hore ntlha ena ya bofelo ha e a rerelwa ho fihlellwa ka kotloloho.", "ca": "Heu accedit a la interfície del servei d’inici de sessió únic, però no heu proporcionat una sol·licitud d’autenticació SAML. Tingueu en compte que en aquest punt no s'hi pot accedir directament." }, "title_ARSPARAMS": { "zh-tw": "\u672a\u63d0\u4f9b SAML \u8a0a\u606f", "zu": "Awukho umlayezo we-SAML onikeziwe", "xh": "Akukho myalezo we-SAML unikelweyo", "st": "Ha ho molaetsa wa SAML o fanweng", "ca": "No s’ha proporcionat cap missatge SAML" }, "descr_ARSPARAMS": { "zh-tw": "\u60a8\u9023\u7d50\u4eba\u5de5\u8655\u7406\u670d\u52d9\u4ecb\u9762\uff0c\u4f46\u672a\u63d0\u4f9b SAML \u4eba\u5de5\u8655\u7406\u670d\u52d9\u8a0a\u606f\u3002\u8acb\u6ce8\u610f\uff0c\u8a72\u7aef\u9ede\u4e26\u975e\u76f4\u63a5\u9023\u7dda\u3002", "xh": "Ufikelele i-intafeyisi ye-Artifact Resolution Service, kodwa awukhange unikrele umyalezo we-SAML ArtifactResolve. Nceda uqaphele ukuba le ndawo yokuphela ayilungiselelwanga ukuba ifikelelwe ngokuthe ngqo.", "zu": "Ufinyelele ukusebenzisana Kwesevisi Yokucaciswa Kobuciko, kodwa awuzange uhlinzeke umlayezo we-SAML ArtifactResolve. Sicela uphawule ukuthi isiphetho asihloselwe ukufinyelelwa ngokuqondile.", "st": "O fihletse kopano ya Tshebeletso ya Tlhakiso ya Athifekte, empa ha o a fana ka molaetsa wa SAML ArtifactResolve. Ka kopo lemoha hore ntlha ena ya bofelo ha e a rerelwa ho fihlellwa ka kotloloho.", "ca": "Heu accedit a la interfície del servei de resolució Artifact, però no heu proporcionat un missatge d’ArtifactResolve de SAML. Tingueu en compte que en aquest punt no s'hi pot accedir directament." }, "title_CASERROR": { "no": "CAS-feil", "nn": "CAS-feil", "sv": "CAS-error", "es": "Error del CAS", "fr": "Erreur CAS", "de": "CAS Fehler", "nl": "CAS Fout", "lb": "CAS Fehler", "sl": "CAS napaka", "da": "CAS fejl", "hr": "CAS gre\u0161ka", "hu": "CAS hiba", "fi": "CAS virhe", "pt-br": "Erro CAS", "pt": "Erro de CAS", "pl": "B\u0142\u0105d CAS", "cs": "CAS chyba", "tr": "CAS Hatas\u0131", "lt": "CAS klaida", "it": "Errore CAS", "ja": "CAS\u30a8\u30e9\u30fc", "zh-tw": "CAS \u932f\u8aa4", "et": "CAS t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05ea \u05e9\u05d4\u05dd", "zh": "CAS\u9519\u8bef", "sr": "CAS gre\u0161ka", "ar": "\u062e\u0637\u0627 CAS", "lv": "CAS k\u013c\u016bda", "id": "Error CAS", "ro": "Eroare CAS", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 CAS", "eu": "CAS Errorea", "af": "CAS Fout", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 CAS", "xh": "Impazamo ye-CAS", "zu": "Iphutha Le-CAS", "st": "Phoso ya CAS", "ca": "Error CAS" }, "descr_CASERROR": { "no": "Feil i kommunikasjonen med CAS-tjeneren.", "nn": "Feil under kommunikasjon med CAS-tenaren", "sv": "Ett fel uppstod vid kommunikation med CAS-servern.", "es": "Error al tratar de comunicar con el servidor CAS", "fr": "Erreur de communication avec le serveur CAS", "de": "Fehler bei der Kommunikation mit dem CAS Server.", "nl": "Fout tijdens communicatie met de CAS server.", "lb": "Fehler beim Kommunizeiren mam CAS Server", "sl": "Napaka pri komunikaciji s CAS stre\u017enikom.", "da": "Der opstod en fejl ved kommunikationen med CAS serveren", "hr": "Gre\u0161ka u komunikaciji sa CAS poslu\u017eiteljem.", "hu": "Hiba t\u00f6rt\u00e9nt a CAS kiszolg\u00e1l\u00f3val val\u00f3 kommunik\u00e1ci\u00f3 k\u00f6zben.", "fi": "CAS-palvelun k\u00e4ttelyvirhe", "pt-br": "Erro ao comunicar-se com o servidor CAS", "pt": "Ocorreu um erro ao comunicar com o servidor CAS.", "cs": "Chyba p\u0159i komunikaci s CAS serverem.", "tr": "CAS sunucusu ile ileti\u015fim kurarken hata", "lt": "Klaida bandant jungtis prie CAS serverio.", "it": "Errore nella comunicazione con il server CAS.", "ja": "CAS\u30b5\u30fc\u30d0\u30fc\u3068\u306e\u901a\u4fe1\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u8207 CAS \u4e3b\u6a5f\u901a\u8a0a\u6642\u767c\u751f\u932f\u8aa4\u3002", "et": "CAS-serveriga suhtlemisel tekkis t\u00f5rge.", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d4\u05ea\u05e7\u05e9\u05e8\u05d5\u05ea \u05e2\u05dd \u05e9\u05e8\u05ea \u05e9\u05d4\u05dd.", "zh": "\u5728\u548cCAS\u670d\u52a1\u5668\u7684\u901a\u8baf\u4e2d\u53d1\u751f\u4e86\u9519\u8bef", "sr": "Gre\u0161ka prilikom komunikacije sa CAS serverom.", "pl": "B\u0142\u0105d podczas komunikacji z serwerem CAS", "ar": "\u062e\u0637\u0627 \u0639\u0646\u062f \u0645\u062d\u0627\u0648\u0644\u0629 \u0627\u0644\u0627\u062a\u0635\u0627\u0644 \u0628\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 CAS", "lv": "K\u013c\u016bda komunic\u0113jot ar CAS serveri.", "id": "Error ketika berkomunikasi dengans server CAS.", "ro": "Eroare de comunicare cu serverul CAS.", "ru": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u043c\u0435\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c CAS.", "eu": "Errorea CAS zerbitzariarekin komunikatzen saiatzean", "af": "Fout tydens kommunikasie met die CAS bediener.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03b5\u03be\u03c5\u03c0\u03b7\u03c1\u03b5\u03c4\u03b7\u03c4\u03ae CAS.", "zu": "Iphutha ngenkathi kuxhunyanwa neseva ye-CAS.", "xh": "Impazamo xa kunxibelelwana neseva ye-CAS.", "st": "Phoso e bile teng ka seva ya CAS.", "ca": "S'ha produït un error al intentar connectar amb el servidor CAS." }, "title_CONFIG": { "no": "Feil i oppsettet", "nn": "Konfigurasjonsfeil", "sv": "Konfigurationsfel", "es": "Error de configuraci\u00f3n", "fr": "Erreur dans la configuration", "de": "Konfigurations Fehler", "nl": "Configuratie fout", "lb": "Konfiguratiounsfehler", "sl": "Napaka v nastavitvah", "da": "Konfigurationsfejl", "hr": "Gre\u0161ka u konfiguraciji", "hu": "Be\u00e1ll\u00edt\u00e1si hiba", "fi": "Virhe asetuksissa", "pt-br": "Erro na configura\u00e7\u00e3o", "pt": "Erro de configura\u00e7\u00e3o", "pl": "B\u0142\u0105d konfiguracji", "cs": "Chyba konfigurace", "tr": "Yap\u0131land\u0131rma hatas\u0131", "lt": "Konfig\u016bracijos klaida", "it": "Errore di configurazione", "ja": "\u8a2d\u5b9a\u30a8\u30e9\u30fc", "zh-tw": "\u8a2d\u5b9a\u932f\u8aa4", "et": "Konfiguratsioonit\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea", "zh": "\u914d\u7f6e\u9519\u8bef", "sr": "Gre\u0161ka u pode\u0161avanjima", "ar": "\u062e\u0637\u0627 \u0628\u0627\u0644\u062a\u0631\u062a\u064a\u0628", "lv": "Konfigur\u0101cijas k\u013c\u016bda", "id": "Error konfigurasi", "ro": "Eroare de configurare", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438", "eu": "Konfigurazio errorea", "af": "Instellings fout", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd", "zu": "Iphutha lomiso", "xh": "Impazamo yolungiselelo", "st": "Phoso ya Netefatso", "ca": "Error de configuració" }, "descr_CONFIG": { "no": "Det virker som det er en feil i oppsettet av SimpleSAMLphp.", "nn": "SimpleSAMLphp ser ut til \u00e5 vera feilkonfigurert", "sv": "Det f\u00f6rfaller som SimpleSAMLphp \u00e4r felkonfigurerat.", "es": "Parece que hay un error en la configuraci\u00f3n de SimpleSAMLphp", "fr": "Il semble que SimpleSAMLphp soit mal configur\u00e9.", "de": "SimpleSAMLphp scheint falsch konfiguriert zu sein.", "nl": "SimpleSAMLphp is niet goed geconfigureerd.", "lb": "SimpleSAMLphp sch\u00e9int falsch konfigur\u00e9iert ze sin.", "sl": "Nastavitve SimpleSAMLphp so napa\u010dne ali se med seboj izklju\u010dujejo.", "da": "SimpleSAMLphp er tilsyneladende ikke Konfigureret korrekt", "hr": "\u010cini se da je SimpleSAMLphp pogre\u0161no iskonfiguriran.", "hu": "Val\u00f3sz\u00edn\u0171leg helytelen\u00fcl lett konfigur\u00e1lva a SimpleSAMLphp", "fi": "Vaikuttaa silt\u00e4, ett\u00e4 SimpleSAMLphp:na asetuksissa on virhe.", "pt-br": "SimpleSAMLphp parece estar mal configurado.", "pt": "O software SimpleSAMLphp tem um problema de configura\u00e7\u00e3o.", "pl": "wydaje si\u0119, \u017ce SimpleSAMLphp jest b\u0142\u0119dnie skonfigurowany.", "cs": "SimpleSAMLphp je \u0161patn\u011b nakonfigurovan\u00fd", "tr": "SimpleSAMLphp do\u011fru yap\u0131land\u0131r\u0131lm\u0131\u015f gibi g\u00f6r\u00fcnm\u00fcyor.", "lt": "SimpleSAMLphp tikriausiai klaidingai sukonfig\u016bruotas.", "it": "Sembra che SimpleSAMLphp non sia configurato correttamente.", "ja": "SimpleSAMLphp\u306e\u8a2d\u5b9a\u306b\u30df\u30b9\u304c\u3042\u308b\u69d8\u3067\u3059\u3002", "zh-tw": "SimpleSAMLphp \u51fa\u73fe\u7121\u6548\u8a2d\u5b9a\u3002", "et": "Paistab, et SimpleSAMLphp on vigaselt seadistatud.", "he": "\u05e0\u05e8\u05d0\u05d4 \u05e9 SimpleSAMLphp \u05dc\u05d0 \u05de\u05d5\u05d2\u05d3\u05e8 \u05e0\u05db\u05d5\u05df", "zh": "SimpleSAMLphp\u51fa\u73b0\u914d\u7f6e\u9519\u8bef", "sr": "Izgleda da postoji gre\u0161ka u pode\u0161avanjima SimpleSAMLphp-a.", "ar": "\u064a\u0628\u062f\u0648 \u0627\u0646 \u062a\u0631\u062a\u064a\u0628 SimpleSAMLphp \u063a\u064a\u0631 \u0635\u062d\u064a\u062d", "lv": "SimpleSAMLphp nav pareizi nokonfigur\u0113ts.", "id": "SimpleSAMLphp sepertinya telah salah dikonfigurasi", "ro": "Probleme la configurarea SimpleSAMLphp.", "ru": "\u0412\u0438\u0434\u0438\u043c\u043e, SimpleSAMLphp \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.", "eu": "Badirudi errore bat jazo dela SimpleSAMLphp-en konfigurazioan", "af": "SimpleSAMLphp is nie korrek ingestel nie", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c4\u03bf\u03c5 SimpleSAMLphp. \u0395\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03ae\u03c3\u03c4\u03b5 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae \u03c4\u03b7\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2.", "xh": "I-SimpleSAMLphp ibonakala ingalungiselelwanga kakuhle.", "zu": "I-SimpleSAMLphp ibonakala ingamisiwe ngendlela efanele.", "st": "SimpleSAMLphp e bonahala e hlophisitswe hampe.", "ca": "SimpleSAMLphp sembla estar mal configurat." }, "title_NOTSET": { "no": "Passordet er ikke satt", "nn": "Finn ikkje passord", "sv": "L\u00f6senord \u00e4r inte satt", "es": "No ha establecido una clave de acceso", "fr": "Le mot de passe n'a pas \u00e9t\u00e9 renseign\u00e9", "de": "Password ist nicht gesetzt", "nl": "Wachtwoord niet ingevuld", "lb": "Passwuert net angin", "sl": "Geslo ni nastavljeno", "da": "Password er ikke sat", "hr": "Zaporka nije postavljena", "hu": "Jelsz\u00f3 nincs be\u00e1ll\u00edtva", "fi": "Salasanaa ei ole asetettu", "pt-br": "Senha n\u00e3o definida", "pt": "Password inalterada", "pl": "Nieustawione has\u0142o", "cs": "Heslo nebylo zad\u00e1no.", "tr": "\u015eifre atanmad\u0131", "lt": "Nepateiktas slapta\u017eodis", "it": "Password non impostata", "ja": "\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093", "zh-tw": "\u5bc6\u78bc\u672a\u8a2d\u5b9a", "et": "Parool m\u00e4\u00e4ramata", "he": "\u05e1\u05d9\u05e1\u05de\u05d4 \u05dc\u05d0 \u05de\u05d5\u05d2\u05d3\u05e8\u05ea", "zh": "\u6ca1\u6709\u8bbe\u7f6e\u5bc6\u7801", "sr": "Lozinka nije postavljena", "ar": "\u0644\u0645 \u062a\u0642\u0645 \u0628\u062a\u062d\u062f\u064a\u062f \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "lv": "Parole nav uzst\u0101d\u012bta", "id": "Password tidak diset", "ro": "Parola nu este configurat\u0103", "ru": "\u041f\u0430\u0440\u043e\u043b\u044c \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d", "eu": "Pasahitzik ez da ezarrii", "af": "Wagwoord nie opgestel nie", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", "xh": "Iphaswedi ayisetwanga", "zu": "Iphasiwedi ayisethiwe", "st": "Phasewete ha e a setwa", "ca": "No s'ha definit la contrasenya" }, "descr_NOTSET": { "no": "Admin passordet i konfigurasjonen (auth.adminpassword) er ikke satt til noe annet enn default verdien. Bytt passord i config.php.", "nn": "Passordet i konfigurasjonen din (auth.adminpassword) er ikkje endra fr\u00e5 opprinneleg verdi, dette er usikkert. G\u00e5 inn i konfigurasjonen og bytt passord.", "sv": "Konfigurationsl\u00f6senordet (auth.adminpassword) \u00e4r inte \u00e4ndrat fr\u00e5n standardv\u00e4rdet. Uppdatera kongiruationen med ett nytt l\u00f6senord!", "es": "La clave de acceso del fichero de configuraci\u00f3n (auth.adminpassword) no ha sido cambiada de su valor por defecto. Por favor, edite dicho fichero", "fr": "Le mot de passe dans la configuration (auth.adminpassword) n'a pas \u00e9t\u00e9 chang\u00e9 par rapport \u00e0 la valeur par d\u00e9faut. Veuillez modifier la configuration.", "de": "Sie benutzen noch immer das Standardpasswort, bitte \u00e4ndern Sie die Konfiguration (auth.adminpassword).", "nl": "Het default wachtwoord in de configuratie (auth.adminpassword) is niet aangepast; pas de configuratie aan aub.", "lb": "D'Passwuert an der Konfiguration (auth.adminpassword) as bis elo net ge\u00e4nnertgin. W.e.g aennert daat an der Konfiguratioun.", "sl": "V nastavitvah je geslo skrbnika (auth.adminpassword) \u0161e vedno nastavljeno na za\u010detno vrednost. Spremenite ga!", "da": "Der er ikke konfigureret et password til administrationsgr\u00e6nsefladen (auth.adminpassword). Opdater konfigurationen med et nyt password, der er forskelligt fra stadardpasswordet.", "hr": "Izvorna vrijednost administratorske zaporke (parametar auth.adminpassword) u konfiguraciji nije promjenjena. Molimo promjenite administratorsku zaporku u konfiguracijskoj datoteci.", "hu": "M\u00e9g nem lett megv\u00e1ltoztatva a karbantart\u00f3i jelsz\u00f3 (auth.adminpassword) a konfigur\u00e1ci\u00f3s f\u00e1jlban, k\u00e9rj\u00fck, v\u00e1ltoztassa meg most! ", "fi": "Yll\u00e4pit\u00e4j\u00e4n salasanaa (auth.adminpassword) ei ole vaihtunut oletusarvosta. Ole hyv\u00e4 ja muokkaa asetustiedostoa.", "pt-br": "A senha na configura\u00e7\u00e3o (auth.adminpassword) n\u00e3o foi alterada. Edite o arquivo de configura\u00e7\u00e3o.", "pt": "A password presente na configura\u00e7\u00e3o (auth.adminpassword) tem o valor de omiss\u00e3o. Por favor altere esta password no ficheiro de configura\u00e7\u00e3o.", "cs": "Heslo v konfiguraci (auth.adminpassword) nen\u00ed nastaveno. Pros\u00edm nastavte ho.", "tr": "Yap\u0131land\u0131rmadaki (auth.adminpassword) \u015fifrenin \u00f6ntan\u0131ml\u0131 de\u011feri de\u011fi\u015fmedi. L\u00fctfen yap\u0131land\u0131rma dosyas\u0131n\u0131 d\u00fczeltin.", "lt": "Konfig\u016bracijoje esantis slapta\u017eodis (auth.adminpassword) nepakeistas i\u0161 pradin\u0117s reik\u0161m\u0117s. Pra\u0161ome pakeisti konfig\u016bracijos fail\u0105.", "it": "La password definita nella configurazione (auth.adminpassword) non \u00e8 stata cambiata dal valore di default. Si prega di editare il file di configurazione.", "zh-tw": "\u8a2d\u5b9a\u6a94\u88e1\u7684\u5bc6\u78bc (auth.adminpassword) \u9084\u662f\u9810\u8a2d\u503c\uff0c\u8acb\u5148\u7de8\u8f2f\u8a2d\u5b9a\u6a94\u3002", "ja": "\u8a2d\u5b9a\u306e\u30d1\u30b9\u30ef\u30fc\u30c9(auth.adminpassword)\u306f\u65e2\u5b9a\u5024\u304b\u3089\u5909\u66f4\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u7de8\u96c6\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "et": "Seadistustes on vaikimisi parool (auth.adminpassword) muutmata. Palun muuda seadistustefaili.", "he": "\u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05d1\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea (auth.adminpassword) \u05dc\u05d0 \u05e9\u05d5\u05e0\u05ea\u05d4 \u05de\u05d4\u05e2\u05e8\u05da \u05d4\u05d4\u05ea\u05d7\u05dc\u05ea\u05d9. \u05d0\u05e0\u05d0 \u05e2\u05e8\u05d5\u05da \u05d0\u05ea \u05e7\u05d5\u05d1\u05e5 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea.", "zh": "\u4f60\u6ca1\u6709\u4fee\u6539\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u9ed8\u8ba4\u5bc6\u7801\uff0c\u8bf7\u4fee\u6539\u8be5\u5bc6\u7801", "sr": "Administratorska lozinka u pode\u0161avanjima(parametar auth.adminpassword<\/i>) i dalje ima izvornu vrednost. Molimo Vas izmenite konfiguracioni fajl.", "pl": "Has\u0142o w konfiguracji (auth.adminpassword) ma domy\u015bln\u0105 warto\u015b\u0107. Prosz\u0119 poprawi\u0107 konfiguracj\u0119.", "ar": "\u0644\u0645 \u062a\u0642\u0645 \u0628\u062a\u063a\u064a\u064a\u0631 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631 \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629 \u0628\u0627\u0644\u062a\u0631\u062a\u064a\u0628 (auth.adminpassword). \u0631\u062c\u0627\u0621\u0627\u064b \u0642\u0645 \u0628\u062a\u062d\u0631\u064a\u0631 \u0645\u0644\u0641 \u0627\u0644\u062a\u0631\u062a\u064a\u0628", "lv": "Konfigur\u0101cij\u0101 auth.adminpassword parolei ir noklus\u0113t\u0101 v\u0113rt\u012bba, t\u0101 nav main\u012bta. L\u016bdzu nomainiet to, labojot failu.", "id": "Password di konfigurasi (auth.adminspassword) tidak berubah dari nilai default. Silahkan edit file konfigurasi.", "ro": "Parola din configurare (auth.adminpassword<\/i>) este cea implicit\u0103, v\u0103 rug\u0103m s\u0103 o modifica\u021bi.", "ru": "\u041f\u0430\u0440\u043e\u043b\u044c \u0432 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 (auth.adminpassword) \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.", "eu": "Ez da aldatu konfigurazio fitxategiaren pasahitzaren (auth.adminpassword) balio lehenetsia. Mesedez, edita ezazu fitxategia", "af": "Die wagwoord in die konfigurasie (auth.adminpassword) is nie aangepas nie. Redigeer asb die konfigurasie le\u00ebr.", "el": "\u03a7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af\u03c4\u03b1\u03b9 \u03b7 \u03c0\u03c1\u03bf\u03ba\u03b1\u03b8\u03bf\u03c1\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7 \u03c4\u03b9\u03bc\u03ae \u03c4\u03bf\u03c5 \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03c4\u03b5\u03af\u03c4\u03b5 \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd.", "xh": "Iphaswedi ekulungiselelo (auth.adminpassword) ayitshintshwanga ukusuka kwixabiso lesiseko. Nceda uhlele ifayile yolungiselelo.", "zu": "Iphasiwedi kumiso (auth.adminpassword) ayishintshiwe kunani elizenzakalelayo. Sicela uhlele ifayela lomiso.", "st": "Phasewete ya tlhophiso (auth.adminpassword) ha e a fetolwa ho tswa palong ya tlwaelo. Ka kopo edita faele ya tlhophiso.", "ca": "La contrasenya de la configuració (auth.adminpassword) no s'ha canviat del valor predeterminat. Editeu el fitxer de configuració." }, "title_NOTVALIDCERT": { "no": "Ugyldig sertifikat", "nn": "Ugyldig sertifikat", "sv": "Felaktigt certifikat", "es": "Certificado no v\u00e1lido", "fr": "Certificat invalide", "de": "Ung\u00fcltiges Zertifikat", "nl": "Ongeldig certificaat", "lb": "Ong\u00fcltegen Zertifikat", "sl": "Napa\u010den certifikat", "da": "Ugyldigt Certifikat", "hr": "Certifikat nije valjan", "hu": "\u00c9rv\u00e9nytelen tan\u00fas\u00edtv\u00e1ny", "fi": "Ep\u00e4kelvollinen sertifikaatti", "pt-br": "Certificado inv\u00e1lido", "pt": "Certificado inv\u00e1lido", "pl": "Nieprawid\u0142owy certyfikat", "cs": "\u0160patn\u00fd certifik\u00e1t", "tr": "Ge\u00e7erli olmayan sertifika", "lt": "Neteisingas sertifikatas", "it": "Certificato non valido", "ja": "\u7121\u52b9\u306a\u8a3c\u660e\u66f8\u3067\u3059", "zh-tw": "\u7121\u6548\u6191\u8b49", "et": "Vigane sertifikaat", "he": "\u05ea\u05e2\u05d5\u05d3\u05d4 \u05dc\u05d0-\u05d7\u05d5\u05e7\u05d9\u05ea", "zh": "\u65e0\u6548\u7684\u8bc1\u4e66", "sr": "Neispravan sertifikat", "ar": "\u0634\u0647\u0627\u062f\u0629 \u063a\u064a\u0631 \u0635\u062d\u064a\u062d\u0629", "lv": "Neder\u012bgs sertifik\u0101ts", "id": "Sertifikat invalid", "ro": "Certificat nevalid", "ru": "\u041d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Ziurtagiri balio gabea", "af": "Ongeldige sertifikaat", "el": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc", "xh": "Isatifikethi esingasebenziyo", "zu": "Isitifiketi esingalungile", "st": "Setifikeiti se sa tshwaneleheng", "ca": "Certificat no vàlid" }, "descr_NOTVALIDCERT": { "no": "Du presenterte ikke et gyldig sertifikat", "nn": "Du har ikkje brukt eit gyldig sertifikat i kommunikasjonen din", "sv": "Du tillhandah\u00f6ll inget godk\u00e4nt certifikat", "es": "No se ha podido validar el certificado recibido", "fr": "Vous n'avez pas pr\u00e9sent\u00e9 de certificat valide", "de": "Sie haben kein g\u00fcltiges Zertifikat benutzt.", "nl": "Je hebt geen geldig certificaat meegegeven", "lb": "Dir hud keen g\u00fcltegen Zertifikat", "sl": "Posredovan certifikat je neveljaven", "da": "Du har ikke valgt et gyldigt certifikat", "hr": "Niste predo\u010dili valjani certifikat.", "hu": "Nem tal\u00e1lhat\u00f3 hiteles tan\u00fas\u00edtv\u00e1ny", "fi": "Et tarjonnut voimassaolevaa sertifikaattia", "pt-br": "Voc\u00ea n\u00e3o possui um certificado v\u00e1lido", "pt": "N\u00e3o foi apresentado um certificado v\u00e1lido.", "pl": "Nie przedstawi\u0142e\u015b prawid\u0142owego certyfikaty", "cs": "Nep\u0159edlo\u017eil jste validn\u00ed certifik\u00e1t.", "tr": "Ge\u00e7erli bir sertifika sa\u011flamad\u0131n\u0131z. ", "lt": "J\u016bs nepateik\u0117te teisingo sertifikato.", "it": "Non hai fornito un certificato valido.", "ja": "\u6b63\u5f53\u306a\u8a3c\u660e\u66f8\u304c\u63d0\u793a\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "zh-tw": "\u60a8\u63d0\u4f9b\u7684\u6191\u8b49\u7121\u6548\u3002", "et": "Sa ei esitanud kehtivat sertifikaati.", "he": "\u05dc\u05d0 \u05d4\u05e6\u05d2\u05ea \u05ea\u05e2\u05d5\u05d3\u05d4 \u05d7\u05d5\u05e7\u05d9\u05ea ", "zh": "\u4f60\u6ca1\u6709\u63d0\u4ea4\u4e00\u4e2a\u6709\u6548\u7684\u8bc1\u4e66", "sr": "Niste dostavili validan setifikat.", "ar": "\u0644\u0645 \u062a\u0642\u062f\u0645 \u0634\u0647\u0627\u062f\u0629 \u0635\u062d\u064a\u062d\u0629", "lv": "J\u016bs neesat nor\u0101d\u012bjis der\u012bgu sertifik\u0101tu.", "id": "Anda tidak menyediakan sertifikat yang valid.", "ro": "Nu a\u021bi oferit un certificat valid.", "ru": "\u0412\u044b \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442.", "eu": "Ez duzu baliozko ziurtagiririk aurkeztu ", "af": "Jy het nie 'n geldige sertifikaat gestuur nie.", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03bb\u03cc\u03b3\u03c9 \u03bc\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf\u03c5 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03bf\u03cd.", "zu": "Awuzange wethule isitifiketi esilungile.", "xh": "Awukhange uzise isatifikethi esisebenzayo.", "st": "Ha o a fana ka setifikeiti se nepahetseng.", "ca": "No heu presentat un certificat vàlid." }, "errorreport_header": { "no": "Feilrapport sent", "nn": "Feilrapport sendt", "sv": "Felrapport skickad", "es": "Informe de error enviado", "fr": "Rapport d'erreur envoy\u00e9", "de": "Fehlerbericht gesandt", "nl": "Foutmeldingsrapport verstuurd", "sl": "Poro\u010dilo o napaki je bilo poslano", "da": "Fejlrapportering sendt", "hr": "Prijava gre\u0161ke poslana", "hu": "Elk\u00fcld\u00f6tt hibabejelent\u00e9s", "fi": "Virheraportti l\u00e4hetetty", "pt-br": "Relat\u00f3rio de erro enviado", "pt": "Relat\u00f3rio de erro enviado", "pl": "Raport o b\u0142\u0119dzie wys\u0142any", "cs": "Chybov\u00fd report zasl\u00e1n", "eu": "Errore txostena bidalita", "tr": "Hata raporu g\u00f6nderildi", "lt": "Prane\u0161imas apie klaid\u0105 i\u0161si\u0173stas", "it": "Rapporto dell'errore inviato", "ja": "\u30a8\u30e9\u30fc\u5831\u544a\u3092\u9001\u4fe1", "zh-tw": "\u932f\u8aa4\u5831\u544a\u5df2\u9001\u51fa", "et": "T\u00f5rkeraport saadetud", "he": "\u05e0\u05e9\u05dc\u05d7 \u05d3\u05d5\u05d7 \u05e9\u05d2\u05d9\u05d0\u05d4", "zh": "\u53d1\u9001\u9519\u8bef\u62a5\u544a", "ar": "\u062a\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u062a\u0642\u0631\u064a\u0631 \u0639\u0646 \u0627\u0644\u062e\u0637\u0623 ", "lv": "K\u013c\u016bdas zi\u0146ojums nos\u016bt\u012bts", "id": "Laporan error dikirimkan", "sr": "Prijava gre\u0161ke poslata", "ro": "Raportul cu erori a fost trimis", "ru": "\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e", "af": "Foutmeldingsverslag gestuur", "el": "\u0397 \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c3\u03c4\u03ac\u03bb\u03b8\u03b7\u03ba\u03b5", "zu": "Umbiko wephutha uthunyelwe", "xh": "Ingxelo yempazamo ithunyelwe", "st": "Tlaleho ya phoso e rometswe", "ca": "S'ha enviat un informe d'error" }, "errorreport_text": { "no": "Feilrapport er sent til administrator.", "nn": "Feilrapport har blitt sendt til administrator", "sv": "Felrapporten \u00e4r skickad till den som sk\u00f6ter systemet.", "es": "El informe de error ha sido enviado a los administradores.", "fr": "Le rapport d'erreur a \u00e9t\u00e9 envoy\u00e9 aux administrateurs.", "de": "Der Fehlerbericht wurde an den Administrator gesandt.", "nl": "Het foutmeldingsrapport is verstuurd naar de beheerders", "sl": "Poro\u010dilo o napaki je bilo poslano skrbnikom sistema.", "da": "Fejlrapporten er nu sendt til system-administrator", "hr": "Prijava gre\u0161ke poslana je administratorima.", "hu": "A hibabejelent\u00e9st elk\u00fcldt\u00fck az adminisztr\u00e1toroknak.", "fi": "Virheraportti on l\u00e4hetetty yll\u00e4pit\u00e4jille.", "pt-br": "O relat\u00f3rio de erro foi enviado com sucesso para os administradores.", "pt": "O relat\u00f3rio de erro foi enviado aos administradores", "pl": "Raport o b\u0142\u0119dzie zosta\u0142 wys\u0142any do administrator\u00f3w.", "cs": "Chybov\u00fd report byl zasl\u00e1n administr\u00e1tor\u016fm.", "eu": "Errore txostena administratzaileei bidali zaie.", "tr": "Hata raporu y\u00f6neticilere g\u00f6nderildi", "lt": "Prane\u0161imas apie klaid\u0105 i\u0161si\u0173stas administratoriams.", "it": "Il rapporto dell'errore \u00e8 stato inviato agli amministratori.", "ja": "\u3053\u306e\u30a8\u30e9\u30fc\u306f\u7ba1\u7406\u8005\u306b\u9001\u4fe1\u3055\u308c\u307e\u3057\u305f\u3002", "zh-tw": "\u932f\u8aa4\u5831\u544a\u5df2\u9001\u7d66\u7ba1\u7406\u54e1\u3002", "et": "T\u00f5rkeraport saadeti administraatoritele.", "he": "\u05d3\u05d5\u05d7 \u05d4\u05e9\u05d2\u05d9\u05d0\u05d4 \u05e0\u05e9\u05dc\u05d7 \u05dc\u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea.", "zh": "\u9519\u8bef\u62a5\u544a\u5df2\u7ecf\u53d1\u9001\u7ed9\u7ba1\u7406\u5458", "ar": "\u062a\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u062a\u0642\u0631\u064a\u0631 \u0639\u0646 \u0627\u0644\u062e\u0637\u0623 \u0644\u0644\u0645\u0634\u0631\u0641", "lv": "K\u013c\u016bdas zi\u0146ojums administratoriem ir nos\u016bt\u012bts.", "id": "Laporan error telah dikirimkan ke administrator", "sr": "Prijava gre\u0161ke poslata je administratorima.", "ro": "Raportul cu erori a fost trimis c\u0103tre administratori.", "ru": "\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0431\u044b\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\u043c.", "af": "Die foutmeldings verslag is gestuur na die administrateurs.", "el": "\u0397 \u03b1\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u03c4\u03b7\u03c2 \u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac\u03c2 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c3\u03c4\u03bf\u03c5\u03c2 \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ad\u03c2 \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5.", "xh": "Ingxelo yempazamo ithunyelwe kubalawuli.", "zu": "Umbiko wephutha uthunyelwe kubalawuli.", "st": "Tlaleho ya phoso e rometswe ho batsamaisi.", "ca": "L’informe d’errors s’ha enviat als administradors." }, "title_LOGOUTINFOLOST": { "no": "Informasjon om utlogging er tapt", "nn": "Mista utloggingsinformasjon", "sv": "Utloggningsinformation \u00e4r borta", "es": "Se perdi\u00f3 la informaci\u00f3n para cerrar la sesi\u00f3n", "fr": "Information de d\u00e9connexion perdue", "de": "Abmeldeinformation verloren gegangen", "nl": "Logout informatie is verloren gegaan", "sl": "Odjavni (Logout) parametri niso na voljo.", "da": "Manglende logout-oplysninger", "hr": "Informacija o odjavljivanju je izgubljena", "hu": "Elveszett kijelentkez\u00e9si inform\u00e1ci\u00f3k", "fi": "Uloskirjautumistiedot h\u00e4visiv\u00e4t", "pt-br": "Informa\u00e7\u00f5es de desconex\u00e3o perdidas", "pt": "Informa\u00e7\u00e3o de logout perdida", "cs": "Odhla\u0161ovac\u00ed informace ztracena", "tr": "\u00c7\u0131k\u0131\u015f bilgisi kaybedildi", "lt": "Atsijungimo informacija prarasta", "it": "Informazioni di disconnessione smarrite.", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u60c5\u5831\u3092\u5931\u3044\u307e\u3057\u305f", "zh-tw": "\u767b\u51fa\u8cc7\u8a0a\u907a\u5931", "et": "V\u00e4ljalogimisinfo l\u00e4ks kaotsi", "he": "\u05de\u05d9\u05d3\u05e2 \u05d4\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05d0\u05d1\u05d3", "zh": "\u4e22\u5931\u4e86\u9000\u51fa\u6d88\u606f", "pl": "Utracono informacj\u0119 o wylogowaniu", "ar": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0645\u0641\u0642\u0648\u062f\u0629", "lv": "Atsl\u0113g\u0161an\u0101s inform\u0101cija zaud\u0113ta", "id": "Informasi logout hilang", "sr": "Informacija o odjavljivanju je izgubljena", "ro": "Informa\u021bia de deautentificare a fost pierdut\u0103", "ru": "\u041f\u043e\u0442\u0435\u0440\u044f\u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0432\u044b\u0445\u043e\u0434\u0435.", "eu": "Saioa ixteko informazioa galdu da", "af": "Afmelding informasie verlore", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2", "zu": "Ulwazi lokuphuma lulahlekile", "xh": "Inkcazelo yokuphuma ilahlekile", "st": "Tlhahisoleseding ya ho tswa e lahlehile", "ca": "S'ha perdut la informació del tancament de sessió" }, "descr_LOGOUTINFOLOST": { "no": "Informasjonen om den n\u00e5v\u00e6rende utloggingen har g\u00e5tt tapt. Du b\u00f8r g\u00e5 tilbake til den opprinnelige tjesesten og pr\u00f8ve \u00e5 logge ut p\u00e5 nytt. Informasjon om utloggingsoperasjoner er kun lagret i en begrenset tid - vanligvis noen timer. Dette er lengere tid enn en vanlig utlogging skal ta, s\u00e5 denne feilen kan tyde p\u00e5 at noe er galt med oppsettet. Ta kontakt med tjenesteyteren hvis problemet gjentar seg.", "nn": "Informasjon om utlogginga di har blitt borte. Du b\u00f8r g\u00e5 tilbake til tenesta du pr\u00f8ver \u00e5 logga ut av, og pr\u00f8va ein gong til. Feilen kan vera fordi utlogginga gjekk ut p\u00e5 tid. Utloggingsinformasjon er lagra i eit kort tidsrom (vanlegvis nokre f\u00e5 timar), og dersom utlogging tar lengre tid kan det vera feil i andre deler av konfigurasjonen p\u00e5 webstaden du var innlogga p\u00e5. Dersom problemet ikkje blir borte, ta kontakt med webstaden du var innlogga p\u00e5.", "sv": "Informationen om aktuell utloggning har f\u00f6rsvunnit. Du b\u00f6r \u00e5terv\u00e4nda till tj\u00e4nsten som du f\u00f6rs\u00f6kte logga ut fr\u00e5n och f\u00f6rs\u00f6ka logga ut p\u00e5 nytt. Detta fel kan intr\u00e4ffa om informationen om utloggningen \u00e4r f\u00f6r gammal. Utloggningsinformationen sparas en begr\u00e4nsad tid, oftas n\u00e5gra timmar. Det \u00e4r l\u00e4ngre \u00e4n vad utloggning b\u00f6r ta s\u00e5 felet kan indikera n\u00e5got fel med konfigurationen. Om problemet kvarst\u00e5r kontakta leverant\u00f6ren f\u00f6r den tj\u00e4nst du f\u00f6rs\u00f6kte logga ut fr\u00e5n.", "es": "La informaci\u00f3n sobre la operaci\u00f3n de cierre de sesi\u00f3n se ha perdido. Deber\u00eda volver al servicio del que intenta salir e intentar cerrar la sesi\u00f3n de nuevo. La informaci\u00f3n para cerrar la sesi\u00f3n se almacena durante un tiempo limitado, generalmente mucho m\u00e1s tiempo del que deber\u00eda tardar la operaci\u00f3n de cierre de sesi\u00f3n, de modo que este error puede deberse a algun error en la configuraci\u00f3n. Si el problema persiste, contacte con el proveedor del servicio.", "fr": "Information de d\u00e9connexion perdue. Les informations aff\u00e9rentes \u00e0 la proc\u00e9dure de d\u00e9connexion en cours ont \u00e9t\u00e9 perdues. Tentez de retourner au service depuis lequel vous avez tent\u00e9 de lancer la d\u00e9connexion, et essayez encore. Cette erreur peut \u00eatre caus\u00e9e par un probl\u00e8me d'obsolescence des information de d\u00e9connexion, qui ne sont conserv\u00e9es que durant un temps limit\u00e9, de l'ordre de quelques heures. Cette dur\u00e9e est bien plus longue qu'une op\u00e9ration de d\u00e9connexion typique, ce qui sugg\u00e8re une autre erreur dans la configuration. Si le probl\u00e8me persiste, contactez l'administrateur du fournisseur de service.", "de": "Die Information des aktuellen Abmeldevorgangs ist verloren gegangen. Bitte rufen Sie den Dienst auf, vom dem Sie sich abmelden wollten, und versuchen Sie dort das Abmelden nochmal. Dieser Fehler tritt auf, wenn die Abmeldeanfrage abl\u00e4uft, da diese nur eine gewisse Zeit (\u00fcblicherweise ein paar Stunden) zwischengespeichert wird. Das sollte im normalen Betrieb ausreichend sein, da ein Abmeldevorgang nicht so lange dauert. Dieser Fehler kann also auch ein Anzeichen sein, dass ein Konfigurationsfehler vorliegt. Tritt dieser Fehler wiederholt auf, wenden sie sich bitte an den benutzen Dienst (Service Provider), vom dem sie sich abmelden wollen.", "nl": "De informatie over de huidige logout operatie is verloren gegaan. Je zou nu moeten terugkeren naar de dienst waar je probeerde uit te loggen, om het nogmaals te proberen. Deze fout kan optreden wanneer de logout informatie is verlopen. De logout informatie wordt gedurende een beperkte tijdsduur bewaard, normaal gesproken een aantal uren. Dit is langer dan een normale logout operatie zou moeten duren, dus deze fout kan er op wijzen dat er een configuratie probleem is. Als het probleem zich blijft voordoen kun u contact opnemen met de Service Provider.", "sl": "Odjavni (Logout) parametri niso na voljo. Vrnite se na storitev, ki ste jo pravkar uporabljali in se ponovno poskusite odjaviti. Napaka je posledica poteka veljavnosti seje.", "da": "Oplysningerne om logout er tabt. Du b\u00f8r g\u00e5 tilbage til tjenesten du \u00f8nskede at logge ud af og pr\u00f8ve igen. Fejlen kan skyldes at oplysningerne blev for\u00e6ldet, da de kun gemmes i kort tid, typisk et par timer. Dette er dog l\u00e6ngere end hvad det burde tage at logge ud, s\u00e5 denne fejl kan indikere en konfigurationsfejl. Hvis fejlen genopst\u00e5r, bedes du kontakte tjenesteudbyderen.", "hr": "Informacija o aktualnom zahtjevu za odjavljivanjem se izgubila. Preporu\u010damo da se vratite u aplikaciju iz koje ste se htjeli odjaviti i poku\u0161ate se odjaviti ponovo. Ova gre\u0161ka mo\u017ee biti uzrokovana istekom valjanosti zahtjeva za odjavom. Zahtjev se pohranjuje odre\u0111eno vrijeme - u pravilu nekoliko sati. Obzirom da je to dulje nego \u0161to bi bilo koja operacija odjavljivanja trebala trajati, gre\u0161ka koja se pojavila mo\u017ee upu\u0107ivati na gre\u0161ku u konfiguraciji. Ako se problem nastavi, kontaktirajte administratora aplikacije. ", "hu": "A kijelentkez\u00e9si m\u0171velettel kapcsolatos inform\u00e1ci\u00f3k valahol elvesztek. K\u00e9rj\u00fck, t\u00e9rjen vissza ahhoz a szolg\u00e1ltat\u00e1shoz, ahonnan ki akart jelentkezni, \u00e9s pr\u00f3b\u00e1lja \u00fajra! Lehets\u00e9ges, hogy a hib\u00e1t az okozza, hogy a kijelentkez\u00e9shez sz\u00fcks\u00e9ges inform\u00e1ci\u00f3 el\u00e9v\u00fclt. A kijelentkez\u00e9si inform\u00e1ci\u00f3 csak korl\u00e1tozott ideig \u00e9rv\u00e9nyes - \u00e1ltal\u00e1ban n\u00e9h\u00e1ny \u00f3r\u00e1ig. Ez hosszabb, mint amennyi norm\u00e1lis esetben a kijelentkez\u00e9shez sz\u00fcks\u00e9ges, ez\u00e9rt ez a hiba\u00fczenet konfigur\u00e1ci\u00f3s hib\u00e1t jelenthet. Ha a probl\u00e9ma tov\u00e1bbra is fenn\u00e1ll, k\u00e9rj\u00fck, forduljon az alkalmaz\u00e1sszolg\u00e1ltat\u00f3hoz (SP)!", "fi": "Uloskirjautumistiedot h\u00e4visiv\u00e4t. Sinun tulee palata siihen palveluun mist\u00e4 aloitit uloskirjautumisen ja yritt\u00e4\u00e4 uutta uloskirjautumista. T\u00e4m\u00e4 virhe voi johtua uloskirjautumistietojen vanhenemisesta. Uloskirjautumistietoja talletetaan vain rajatun ajan - usein vain tunteja. T\u00e4m\u00e4 on selv\u00e4sti pidemp\u00e4\u00e4n kuin uloskirjautumisen pit\u00e4isi kestt\u00e4, joten virhe voi olla oire asetusten virheist\u00e4. Ota yhteutt\u00e4 yll\u00e4pit\u00e4j\u00e4\u00e4n mik\u00e4li ongelma jatkuu.", "pt-br": "As informa\u00e7\u00f5es sobre a opera\u00e7\u00e3o de desconex\u00e3o atual foram perdidas. Voc\u00ea deve voltar para o servi\u00e7o que estava antes de tentar sair e tente novamente. Esse erro pode ser causado pela expira\u00e7\u00e3o das informa\u00e7\u00f5es da desconex\u00e3o. As informa\u00e7\u00f5es s\u00e3o armazenadas em cache por uma quantia limitada de tempo - geralmente um n\u00famero de horas. Esta \u00e9 mais longa do que qualquer desconex\u00e3o em funcionamento normal deve ter, de modo que este erro pode indicar algum outro erro com a configura\u00e7\u00e3o. Se o problema persistir, contate o seu fornecedor de servi\u00e7os.", "pt": "A informa\u00e7\u00e3o acerca da opera\u00e7\u00e3o de logout foi perdida. Por favor, volte ao servi\u00e7o de onde efectuou o logout e tente de novo esta opera\u00e7\u00e3o. A informa\u00e7\u00e3o de logout possui um tempo de expira\u00e7\u00e3o que \u00e9 normalmente muito superior ao tempo normal de processamento desta opera\u00e7\u00e3o. Se o problema persistir pode ser um erro de configura\u00e7\u00e3o e dever\u00e1 ser comunicado.", "cs": "Informace o odhla\u0161ovac\u00ed operaci byla ztracena. M\u016f\u017eete se vr\u00e1tit do aplikace, ze kter\u00e9 jste se odhla\u0161ovali a zkusit to znova. Tato chyba byla zp\u016fsobena vypr\u0161en\u00edm odhla\u0161ovac\u00edh informac\u00ed. Ty jsou ulo\u017eeny omezen\u00fd \u010das (jednotky hodin). To by m\u011blo sta\u010di na norm\u00e1ln\u00ed odhla\u0161en\u00ed a tato chyba m\u016f\u017ee ukazovat na chyby v konfiguraci. Pokud probl\u00e9m p\u0159etrv\u00e1v\u00e1, kontaktujte administr\u00e1tora.", "tr": "Y\u00fcr\u00fcrl\u00fckteki \u00e7\u0131k\u0131\u015f i\u015flemi ile ilgili bilgi kayboldu. \u00c7\u0131kmak istedi\u011finiz servise geri d\u00f6n\u00fcn ve yeniden \u00e7\u0131kmay\u0131 denyin. Bu hata, \u00e7\u0131k\u0131\u015f bilgisinin s\u00fcresi doldu\u011fu i\u00e7in olu\u015fmu\u015f olabilir. \u00c7\u0131k\u0131\u015f bilgisi belirli bir s\u00fcre i\u00e7in tutulur - genellikle birka\u00e7 saat. Bu s\u00fcre normal bir \u00e7\u0131k\u0131\u015f i\u015fleminin tutaca\u011f\u0131ndan daha fazla bir s\u00fcredir; bu hata yap\u0131land\u0131rma ile ilgili ba\u015fka bir hatay\u0131 i\u015faret ediyor olabilir. E\u011fer sorun devam ederse, servis sa\u011flay\u0131c\u0131n\u0131zla ileti\u015fime ge\u00e7iniz.", "lt": "Informacija apie atsijungimo operacij\u0105 prarasta. J\u016bs tur\u0117tum\u0117te sugr\u012f\u017eti \u012f t\u0105 paslaug\u0105, i\u0161 kurios band\u0117te atsijungti ir pabandyti atlikti tai dar kart\u0105. \u0160i klaida gal\u0117jo b\u016bti sukelta, nes baig\u0117si atsijungimo informacijos galiojimo laikas. Informacija apie atsijungim\u0105 yra saugoma ribot\u0105 laiko tarp\u0105 - da\u017eniausiai kelias valandas. Tai yra daugiau nei bet kokia normali atsijungimo informacija gali u\u017etrukti, taigi \u0161i klaida gali b\u016bti sukelta kitos klaidos, kuri \u012fvyko d\u0117l konfig\u016bracijos. Jei problema t\u0119siasi, susisiekite su savo paslaugos teik\u0117ju.", "it": "Le informazioni riguardo all'attuale operazione di disconnessione sono andate perse. Si dovrebbe tornare al servizio da cui si cercava di disconnettersi e provare di nuovo. Questo errore pu\u00f2 essere causato dal termine della validit\u00e0 delle informazioni di disconnessione. Le informazioni per la disconnessione sono conservate per un breve arco temporale, in genere alcune ore. Questo \u00e8 un tempo superiore a quello che una operazione di disconnessione dovrebbe richiedere, quindi questo errore pu\u00f2 indicare un problema di configurazione di qualche altro tipo. Se il problema persiste, consultare il fornitore del service provider.", "zh-tw": "\u907a\u5931\u6b63\u5728\u767b\u51fa\u7684\u76f8\u95dc\u64cd\u4f5c\u8cc7\u8a0a\uff0c\u60a8\u53ef\u80fd\u8981\u56de\u5230\u60a8\u6e96\u5099\u767b\u51fa\u7684\u670d\u52d9\u518d\u767b\u51fa\u4e00\u6b21\u3002\u9019\u500b\u932f\u8aa4\u53ef\u80fd\u662f\u56e0\u70ba\u767b\u51fa\u8cc7\u8a0a\u903e\u6642\uff0c\u767b\u51fa\u8cc7\u8a0a\u50c5\u80fd\u5728\u6709\u9650\u7684\u6642\u9593\u88e1\u6709\u6548 - \u901a\u5e38\u662f\u5e7e\u5c0f\u6642\u3002\u9019\u5df2\u7d93\u5927\u65bc\u6b63\u5e38\u7684\u767b\u51fa\u64cd\u4f5c\u6240\u9700\u7684\u6642\u9593\uff0c\u6240\u4ee5\u9019\u500b\u932f\u8aa4\u4e5f\u8a31\u8aaa\u660e\u6709\u4e9b\u5176\u4ed6\u7684\u932f\u8aa4\u88ab\u8a2d\u5b9a\u3002\u5982\u679c\u9019\u500b\u932f\u8aa4\u6301\u7e8c\u5b58\u5728\uff0c\u8acb\u9023\u7d61\u60a8\u7684\u670d\u52d9\u63d0\u4f9b\u8005\u3002", "ja": "The information about the current logout operation has been lost. You should return to the service you were trying to log out from and try to log out again. This error can be caused by the logout information expiring. The logout information is stored for a limited amout of time - usually a number of hours. This is longer than any normal logout operation should take, so this error may indicate some other error with the configuration. If the problem persists, contact your service provider.", "et": "Teave aktiivse v\u00e4ljalogimisoperatsiooni kohta l\u00e4ks kaduma. P\u00f6\u00f6rdu tagasi teenuse juurde, millest soovisid v\u00e4lja logida ja proovi uuesti. See t\u00f5rge v\u00f5ib olla p\u00f5hjustatud v\u00e4ljalogimisinfo aegumisest. V\u00e4ljalogimisinfo salvestatakse piiratud ajaks, tavaliselt m\u00f5neks tunniks. See on kauem kui tavaline v\u00e4ljalogimine peaks aega v\u00f5tma, seega v\u00f5ib see t\u00f5rge anda m\u00e4rku ka m\u00f5nest teisest t\u00f5rkest seadistustes. Kui probleem ei kao, siis v\u00f5ta \u00fchendust oma teenusepakkujaga.", "he": "\u05d4\u05de\u05d9\u05d3\u05e2 \u05e2\u05dc \u05e4\u05e2\u05d5\u05dc\u05ea \u05d4\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05d4\u05e0\u05d5\u05db\u05d7\u05d9\u05ea \u05d0\u05d1\u05d3. \u05d0\u05ea\u05d4 \u05e6\u05e8\u05d9\u05da \u05dc\u05d7\u05d6\u05d5\u05e8 \u05dc\u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05de\u05e0\u05d5 \u05e0\u05d9\u05e1\u05d9\u05ea \u05dc\u05d4\u05ea\u05e0\u05ea\u05e7 \u05d5\u05dc\u05e0\u05e1\u05d5\u05ea \u05e9\u05d5\u05d1. \u05e9\u05d2\u05d9\u05d0\u05d4 \u05d6\u05d5 \u05d9\u05db\u05d5\u05dc\u05d4 \u05dc\u05d4\u05d9\u05d2\u05e8\u05dd \u05e2\u05dc \u05d9\u05d3\u05d9 \u05de\u05d9\u05d3\u05e2 \u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05e9\u05e4\u05d2 \u05ea\u05d5\u05e7\u05e4\u05d5. \u05de\u05d9\u05d3\u05e2 \u05d4\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05de\u05d0\u05d5\u05db\u05e1\u05df \u05dc\u05d6\u05de\u05df \u05de\u05d5\u05d2\u05d1\u05dc - \u05d1\u05d3\u05e8\u05da \u05db\u05dc\u05dc \u05db\u05de\u05d4 \u05e9\u05e2\u05d5\u05ea. \u05e4\u05e8\u05e7 \u05d6\u05de\u05df \u05d0\u05e8\u05d5\u05da \u05d1\u05d4\u05e8\u05d1\u05d4 \u05de\u05db\u05dc \u05d1\u05e7\u05e9\u05ea \u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05e0\u05d5\u05e8\u05de\u05dc\u05d9\u05ea, \u05dc\u05db\u05df \u05e9\u05d2\u05d9\u05d0\u05d4 \u05d6\u05d5 \u05d9\u05db\u05d5\u05dc\u05d4 \u05dc\u05d4\u05d2\u05e8\u05dd \u05de\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05dc\u05d0 \u05e0\u05db\u05d5\u05e0\u05d5\u05ea. \u05d0\u05dd \u05d4\u05d1\u05e2\u05d9\u05d9\u05d4 \u05de\u05de\u05e9\u05d9\u05db\u05d4, \u05e6\u05d5\u05e8 \u05e7\u05e9\u05e8 \u05e2\u05dd \u05e1\u05e4\u05e7 \u05d4\u05e9\u05e8\u05d5\u05ea.", "zh": "\u5173\u4e8e\u5f53\u524d\u9000\u51fa\u64cd\u4f5c\u7684\u76f8\u5173\u4fe1\u606f\u4e22\u5931\u4e86\uff0c\u4f60\u5e94\u8be5\u8fd4\u56de\u670d\u52a1\u4e2d\uff0c\u91cd\u65b0\u5c1d\u8bd5\u9000\u51fa\uff0c\u8fd9\u4e2a\u9519\u8bef\u53ef\u80fd\u662f\u9000\u51fa\u4fe1\u606f\u8d85\u65f6\u5f15\u8d77\u7684\u3002\u9000\u51fa\u6d88\u606f\u5728\u6709\u9650\u7684\u65f6\u95f4\u5185\u5b58\u50a8\uff0c\u901a\u5e38\u662f\u51e0\u4e2a\u5c0f\u65f6\uff0c\u8fd9\u6bd4\u4efb\u4f55\u5e38\u89c4\u7684\u9000\u51fa\u65f6\u95f4\u6240\u9700\u7684\u65f6\u95f4\u8981\u957f\u591a\u4e86\uff0c\u6240\u4ee5\u8fd9\u79cd\u9519\u8bef\u53ef\u80fd\u662f\u914d\u7f6e\u9519\u8bef\uff0c\u5982\u679c\u95ee\u9898\u4f9d\u65e7\u5b58\u5728\uff0c\u8054\u7cfb\u4f60\u7684\u670d\u52a1\u63d0\u4f9b\u5546", "pl": "Utracono informacj\u0119 o przebiegu operacji wylogowania. Powr\u00f3\u0107 do us\u0142ugi, z kt\u00f3rej pr\u00f3bowa\u0142e\u015b si\u0119 wylogowa\u0107 i pon\u00f3w pr\u00f3b\u0119. Ten b\u0142\u0105d mo\u017ce by\u0107 spowodowany przeterminowaniem informacji o wylogowaniu. Informacja o wylogowaniu jest przechowywana przez okre\u015blony czas, zwykle kilka godzin. Jest to d\u0142u\u017cej ni\u017c mo\u017ce zaj\u0105\u0107 operacja wylogowania, wi\u0119c b\u0142\u0105d mo\u017ce mie\u0107 inn\u0105 przyczyn\u0119, np. mo\u017ce oznacza\u0107 b\u0142\u0119dn\u0105 konfiguracj\u0119. Je\u015bli problem utrzymuje si\u0119, skontaktuj si\u0119 z dostawc\u0105 us\u0142ugi.", "ar": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0627\u0644\u062d\u0627\u0644\u064a \u0645\u0641\u0642\u0648\u062f\u0629. \u0639\u062f \u0644\u0635\u0641\u062d\u0629 \u0645\u0642\u062f\u0645 \u0627\u0644\u062e\u062f\u0645\u0629 \u0648 \u062d\u0627\u0648\u0644 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0645\u0631\u0629 \u0627\u062e\u0631\u064a. \u064a\u062d\u062f\u062b \u0647\u0630\u0627 \u0627\u0644\u062e\u0637\u0623 \u0646\u062a\u064a\u062c\u0629 \u0644\u0627\u0646\u062a\u0647\u0627\u0621 \u0635\u0644\u0627\u062d\u064a\u0629 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0627\u0644\u062a\u064a \u062a\u062d\u0641\u0638 \u0644\u0641\u062a\u0631\u0629 \u0645\u062d\u062f\u062f\u0629- \u0639\u062f\u0629 \u0633\u0627\u0639\u0627\u062a \u0639\u0627\u062f\u0629. \u0641\u062a\u0631\u0629 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0647\u0630\u0647 \u0623\u0637\u0648\u0644 \u0645\u0646 \u0627\u0644\u0645\u0639\u062a\u0627\u062f \u0645\u0645\u0627 \u064a\u062f\u0644 \u0639\u0644\u064a \u0648\u062c\u0648\u062f \u0623\u062e\u0637\u0627\u0621 \u0627\u062e\u0631\u064a \u0628\u0627\u0644\u062a\u0631\u062a\u064a\u0628. \u0627\u0630\u0627 \u0648\u0627\u062c\u0647\u062a\u0643 \u0647\u0630\u0647 \u0627\u0644\u0645\u0634\u0643\u0644\u0629 \u0645\u0631\u0629 \u0627\u062e\u0631\u064a \u0642\u0645 \u0631\u062c\u0627\u0621\u0627\u064b \u0628\u0627\u0644\u0627\u062a\u0635\u0627\u0644 \u0628\u0645\u0642\u062f\u0645 \u0627\u0644\u062e\u062f\u0645\u0629", "lv": "Inform\u0101cija par atsl\u0113g\u0161an\u0101s oper\u0101ciju ir pazaud\u0113ta. Jums j\u0101atgrie\u017eas pie servisa, no kura m\u0113\u0123in\u0101j\u0101t atsl\u0113gties, un j\u0101m\u0113\u0123ina atsl\u0113gties v\u0113lreiz. K\u013c\u016bda var rasties, ja atsl\u0113g\u0161an\u0101s norit p\u0101r\u0101k ilgi. Inform\u0101cija par atsl\u0113g\u0161anos tiek glab\u0101ta vair\u0101kas stundas. Tas ir ilg\u0101k nek\u0101 parasti norit atsl\u0113g\u0161an\u0101s proced\u016bra, t\u0101d\u0113\u013c \u0161\u012b k\u013c\u016bda var nor\u0101d\u012bt uz k\u013c\u016bdu konfigur\u0101cij\u0101. Ja probl\u0113ma turpin\u0101s, sazinieties ar servisa pieg\u0101d\u0101t\u0101ju.", "id": "Informasi tentang operasi logout saat ini telah hilang. Anda harus kembali ke layanan tempat Anda mencoba logout dan mencoba melakukan proses logout kembali. Error ini dapat disebabakan oleh informasi logout yang telah kadaluarsa. Informasi logout disimpan untuk waktu yang terbatas - biasanya dalam bilangan jam. Waktu ini lebih lama dari operasi logout normal umumnya, jadi error ini mungkin mengindikasikan beberapa erro lain pada konfigurasi. Jika masalah tetap terjadi, hubungi service provider Anda.", "sr": "Informacija o aktuelnom zahtevu za odjavljivanjem se izgubila. Preporu\u010dujemo da se vratite u aplikaciju iz koje ste se hteli odjaviti i poku\u0161ate da se odjavite ponovo. Ova gre\u0161ka mo\u017ee biti uzrokovana istekom validnosti zahteva za odjavom. Zahtev se skladi\u0161ti odre\u0111eno vreme - po pravilu nekoliko sati. Obzirom da je to du\u017ee nego \u0161to bi bilo koja operacija odjavljivanja trebala trajati, gre\u0161ka koja se pojavila mo\u017ee upu\u0107ivati na gre\u0161ku u pode\u0161avanjima. Ukoliko se problem nastavi, kontaktirajte administratora aplikacije.", "ro": "Informa\u021bia de deautentificare pentru aceast\u0103 opera\u021biune a fost pierdut\u0103. V\u0103 rug\u0103m s\u0103 v\u0103 \u00eentoarce\u021bi la serviciul din care a\u021bi \u00eencercat s\u0103 v\u0103 deautentifica\u021bi \u0219i s\u0103 \u00eencerca\u021bi din nou. Aceast\u0103 eroare poate fi cauzat\u0103 de expirarea informa\u021biei de deautentificare. Informa\u021bia de deautentificare este stocat\u0103 pentru un timp limitat, dar de obicei c\u00e2teva ore, ceea ce eate mai mult dec\u00e2t poate dura \u00een mod obi\u0219nuit o opera\u021biune de deautentificare. Prin urmare, mesajul poate indica o alt\u0103 eroare de configurare. Dac\u0103 problema persist\u0103, v\u0103 rug\u0103m s\u0103 contacta\u021bi furnizorul de servicii.", "ru": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0431\u044b\u043b\u0430 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u0430. \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043b\u0443\u0436\u0431\u0443, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0432\u044b\u0439\u0442\u0438 \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0439\u0442\u0438 \u0441\u043d\u043e\u0432\u0430. \u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0432\u044b\u0445\u043e\u0434\u0435. \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0432\u044b\u0445\u043e\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442\u0440\u0435\u0437\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 - \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e\u0438\u0445 \u0447\u0430\u0441\u043e\u0432. \u042d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0445\u043e\u0434\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0430, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0443.", "eu": "Saioa ixteko eragiketari buruzko informazioa galdu da. Irten nahi duzun zerbitzura itzuli eta saioa berriz ixten saitu behar duzu. Saioa ixteko informazioa denbora mugatu batean gordetzen da, orokorrean saio ixteko eragiketak iraun beharko lukeen denbora baino gehiago, beraz errore hau konfigurazioan erroreren bat jazo delako gerta liteke. Errorea etengabea bada, jar zaitez harremanetan zerbitzuaren hornitzailearekin.", "af": "Die inligting vir die huidige uiteken sessie is verlore. Jy moet terugkeer na die diens waarvan jy probeer afmeld het en probeer om weer af te meld. Di\u00e9 fout kan voorkom weens verstreke afmelding inligting. Die afmelding inligting word gestoor vir 'n beperkte tydperk - gewoonlik 'n paar ure. Dit is langer as wat 'n normale afmelding sessie moet vat, so die fout mag 'n indikasie wees van 'n probleem met die stellings. Kontak jou diens verskaffer sou die probleem voortduur.", "el": "\u039f\u03b9 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03b7\u03bd \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 \u03ad\u03c7\u03bf\u03c5\u03bd \u03c7\u03b1\u03b8\u03b5\u03af. \u0398\u03b1 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03c3\u03c4\u03c1\u03ad\u03c8\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03b1\u03c0\u03cc \u03c4\u03b7\u03bd \u03bf\u03c0\u03bf\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c0\u03b1\u03b8\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03ba\u03b1\u03b9 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c0\u03b1\u03b8\u03ae\u03c3\u03b5\u03c4\u03b5 \u03b5\u03ba \u03bd\u03ad\u03bf\u03c5. \u0391\u03c5\u03c4\u03cc \u03c4\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03b1\u03c3\u03c4\u03b5\u03af \u03b1\u03bd \u03b7 \u03b9\u03c3\u03c7\u03cd\u03c2 \u03c4\u03c9\u03bd \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03b9\u03ce\u03bd \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03b7\u03bd \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 \u03ad\u03c7\u03b5\u03b9 \u03bb\u03ae\u03be\u03b5\u03b9. \u039f\u03b9 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03b1\u03c5\u03c4\u03ad\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03b5\u03c4\u03b1\u03b9 \u03b3\u03b9\u03b1 \u03c0\u03b5\u03c1\u03b9\u03bf\u03c1\u03b9\u03c3\u03bc\u03ad\u03bd\u03bf \u03c7\u03c1\u03bf\u03bd\u03b9\u03ba\u03cc \u03b4\u03b9\u03ac\u03c3\u03c4\u03b7\u03bc\u03b1 - \u03c3\u03c5\u03bd\u03ae\u03b8\u03c9\u03c2 \u03bc\u03b5\u03c1\u03b9\u03ba\u03ce\u03bd \u03c9\u03c1\u03ce\u03bd. \u0391\u03c5\u03c4\u03cc \u03c3\u03c5\u03bd\u03ae\u03b8\u03c9\u03c2 \u03b5\u03c0\u03b1\u03c1\u03ba\u03b5\u03af \u03b3\u03b9\u03b1 \u03bc\u03b9\u03b1 \u03ba\u03b1\u03bd\u03bf\u03bd\u03b9\u03ba\u03ae \u03bb\u03b5\u03b9\u03c4\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2, \u03c3\u03c5\u03bd\u03b5\u03c0\u03ce\u03c2 \u03c3\u03c4\u03b7\u03bd \u03c0\u03c1\u03bf\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03b7 \u03c0\u03b5\u03c1\u03af\u03c0\u03c4\u03c9\u03c3\u03b7 \u03c4\u03bf \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c5\u03c0\u03bf\u03b4\u03b5\u03b9\u03ba\u03bd\u03cd\u03b5\u03b9 \u03ba\u03ac\u03c0\u03bf\u03b9\u03bf \u03ac\u03bb\u03bb\u03bf \u03b8\u03ad\u03bc\u03b1 \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2. \u0395\u03ac\u03bd \u03c4\u03bf \u03c0\u03c1\u03cc\u03b2\u03bb\u03b7\u03bc\u03b1 \u03c0\u03b1\u03c1\u03b1\u03bc\u03ad\u03bd\u03b5\u03b9, \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03ae\u03c3\u03c4\u03b5 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd.", "zu": "Ulwazi olumayelana nomsebenzi wokuphuma wamanje lulahlekile. Kufanele ubuyele kusevisi obuzama ukuphuma kuyo futhi uzame ukuphuma futhi. Leli phutha lingabangelwa ukuphelelwa isikhathi kolwazi lokuphuma. Ulwazi lokuphuma lugcinwa isikhathi esilinganiselwe - ngokuvamile amahora ambalwa. Lokhu kude kunanoma yimuphi umsebenzi wokuphuma ovamile, ngakho leli phutha lingase libonise elinye iphutha ngomiso. Uma inkinga iphikelela, thinta umhlinzeki wakho wesevisi.", "xh": "Inkcazelo malunga nomsebenzi wokuphuma wangoku ilahlekile. Ufanele ubuyele kwinkonzo ubuzama ukuphuma kuyo uzame ukuphuma kwakhona. Le mpazamo inokubangelwa kukuphelelwa kwenkcazelo yokuphuma. Inkcazelo yokuphuma igcinwa ixesha elithile - ngokuqhelekileyo iiyure eziliqela. Oku kuthatha ixesha elide kunawo nawuphi na umsebenzi wokuphuma ofanele ulithathe, ngoko le mpazamo isenokubonisa enye impazamo ngolungiselelo. Ukuba ingxaki iyaqhubeka, qhagamshela umboneleli wenkonzo wakho.", "st": "Tlhahisoleseding e mabapi le tshebetos ya ho tswa ya hajwale e lahlehile. O tlameha ho kgutlela tshebeletsong eo o neng o leka ho tswa ho yona le ho leka ho tswa hape. Phoso ena e ka bakwa ke phelo nako ya tlhahisoleseding ya ho tswa. Tlhahisoleseding ya ho tswa e bolokwa nako e lekantsweng - ka tlwaelo ke palo ya dihora. Sena se setelele ho feta nako eo tshebetso efe kapa efe ya tlwaelo ya ho tswa e tlamehang ho e nka, ka hona phoso ena e ka nna ya bontsha phoso e nngwe ka tlhophiso esele. Haeba bothata bo phehella, ikopanye le mofani wa tshebeletso wa hao.", "ca": "S'ha perdut la informació sobre el tancament de sessió actual. Heu de tornar al servei del qual esteu intentant desconnectar i provar de sortir de nou. Aquest error pot ser causat per l’expiració de la informació del tancament de sessió. La informació de tancament de sessió s’emmagatzema per un període limitat de temps, normalment un nombre d'hores. Això és més llarg del que hauria de tenir qualsevol operació de tancament de sessió normal, de manera que aquest error pot indicar algun altre error amb la configuració. Si el problema continua, poseu-vos en contacte amb el vostre proveïdor de serveis." }, "title_UNHANDLEDEXCEPTION": { "no": "Uh\u00e5ndtert feil", "nn": "Feilsituasjon som ikkje er riktig handtert", "sv": "Ohanterat undantag", "es": "Excepci\u00f3n no controlada", "fr": "Exception non g\u00e9r\u00e9e", "de": "Nicht abgefangene Code-Exception", "nl": "Onverwachte foutmelding", "sl": "Nedefinirana izjema.", "da": "Unhandled exception", "hr": "Neobra\u0111ena iznimka", "hu": "Kezeletlen kiv\u00e9tel", "pt-br": "Exce\u00e7\u00e3o n\u00e3o tratada", "pt": "Excep\u00e7\u00e3o n\u00e3o tratada", "cs": "Neo\u010dek\u00e1van\u00e1 vyj\u00edmka", "tr": "Beklenmeyen durum", "lt": "Ne\u017einoma klaida", "it": "Eccezione non gestita", "ja": "\u672a\u51e6\u7406\u4f8b\u5916", "zh-tw": "\u4e0d\u53ef\u9810\u671f\u7684\u4f8b\u5916", "et": "K\u00e4sitlemata t\u00f5rge", "he": "\u05d7\u05e8\u05d9\u05d2\u05d4 \u05dc\u05d0 \u05de\u05d8\u05d5\u05e4\u05dc\u05ea ", "zh": "\u672a\u5904\u7406\u7684\u5f02\u5e38", "pl": "Nieobs\u0142ugiwany b\u0142\u0105d", "ar": "\u0627\u0633\u062a\u062b\u0646\u0627\u0621 \u063a\u064a\u0631 \u0645\u0639\u0627\u0644\u062c", "lv": "Nezin\u0101ma k\u013c\u016bda", "id": "Exception yang tidak tertangani", "sr": "Neobra\u0111ena gre\u0161ka", "ro": "Excep\u021bie netratat\u0103", "ru": "\u041d\u0435\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435", "eu": "Kudeatu gabeko salbuespena", "fi": "K\u00e4sittelem\u00e4t\u00f6n poikkeus", "af": "Onverwagte foutmelding", "el": "\u0391\u03bd\u03b5\u03c0\u03af\u03bb\u03c5\u03c4\u03b7 \u03b5\u03be\u03b1\u03af\u03c1\u03b5\u03c3\u03b7", "xh": "Isinxaxhi esingasingathwanga", "zu": "Okuhlukile okungasingathiwe", "st": "Mokgelo o sa rarollwang", "ca": "Excepció no controlada" }, "descr_UNHANDLEDEXCEPTION": { "no": "En uventet feilsituasjon oppstod", "nn": "Programvaren gjev melding om uventa feilsituasjon", "sv": "Ett ohanterat undatag har intr\u00e4ffat. ", "es": "Se lanz\u00f3 una excepci\u00f3n no controlada.", "fr": "Une exception non g\u00e9r\u00e9e a \u00e9t\u00e9 lev\u00e9e.", "de": "Eine nicht abgefangene Code-Exception ist aufgetreten.", "nl": "Een onverwachte foutmelding is opgetreden", "sl": "Zagnana je bila nedefinirana izjema.", "da": "An unhandled exception was thrown", "hr": "Pojavila se iznimka koja ne mo\u017ee do kraja biti obra\u0111ena.", "hu": "Kezeletlen kiv\u00e9tel (exception) keletkezett.", "pt-br": "Uma exce\u00e7\u00e3o n\u00e3o tratada foi descartada.", "pt": "Foi despoletada um excep\u00e7\u00e3o que n\u00e3o foi tratada.", "cs": "Neo\u010dek\u00e1van\u00e1 vyj\u00edmka vznikla.", "tr": "Bir beklenmeyen durum g\u00f6nderildi.", "lt": "Ne\u017einoma klaida.", "it": "E' stata generata un'eccezione che non \u00e8 stata gestita.", "ja": "\u672a\u51e6\u7406\u4f8b\u5916\u304c\u6295\u3052\u3089\u308c\u307e\u3057\u305f\u3002", "zh-tw": "\u767c\u751f\u4e86\u4e00\u500b\u7121\u6cd5\u9810\u671f\u7684\u4f8b\u5916\u72c0\u6cc1", "et": "Ilmnes k\u00e4sitlemata t\u00f5rge.", "he": "\u05d4\u05d5\u05e9\u05dc\u05db\u05d4 \u05d7\u05e8\u05d9\u05d2\u05d4 \u05dc\u05dc\u05d0 \u05d8\u05d9\u05e4\u05d5\u05dc", "zh": "\u629b\u51fa\u4e00\u4e2a\u672a\u5904\u7406\u7684\u5f02\u5e38", "pl": "Zosta\u0142 zwr\u00f3cony b\u0142\u0105d, kt\u00f3ry nie mo\u017ce by\u0107 obs\u0142u\u017cony", "ar": "\u062a\u0645 \u0627\u0644\u062a\u062e\u0644\u0635 \u0645\u0646 \u0627\u0633\u062a\u062b\u0646\u0627\u0621 \u063a\u064a\u0631 \u0645\u0639\u0627\u0644\u062c", "lv": "Noticis nezin\u0101ms iz\u0146\u0113muma gad\u012bjums.", "id": "Exception yang tidak tertangani telah di-thrown", "sr": "Pojavila se gre\u0161ka koja ne mo\u017ee do kraja biti obra\u0111ena.", "ro": "A ap\u0103rut o excep\u021bie netratat\u0103.", "ru": "\u0412\u044b\u0434\u0430\u043d\u043e \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.", "eu": "Kudeatu gabeko salbuespen bat abiarazi da", "fi": "K\u00e4sittelem\u00e4t\u00f6n poikkeus heitetty", "af": "'n Onverwagte foutmelding is aangetoon", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03b1\u03bd\u03b5\u03c0\u03af\u03bb\u03c5\u03c4\u03b7 \u03b5\u03be\u03b1\u03af\u03c1\u03b5\u03c3\u03b7", "xh": "Isinxaxhi esingasingathwanga silahliwe.", "zu": "Okuhlukile okungasingathiwe kulahliwe.", "st": "Kgeloho e sa rarollwang e lahlilwe.", "ca": "S'ha enviat una excepció no controlada." }, "title_NOTFOUND": { "no": "Kan ikke finne siden", "nn": "Fann ikkje sida", "sv": "Sidan finns inte", "es": "P\u00e1gina no encontrada", "fr": "Page introuvable", "de": "Seite nicht gefunden", "nl": "Pagina niet gevonden", "sl": "Strani ni bilo mogo\u010de najti.", "da": "Siden kunne ikke findes", "hr": "Stranica nije prona\u0111ena", "hu": "Oldal nem tal\u00e1lhat\u00f3", "fi": "Sivua ei l\u00f6ytynyt", "pt-br": "P\u00e1gina n\u00e3o encontrada", "pt": "P\u00e1gina n\u00e3o encontrada", "pl": "Nie znaleziono strony", "cs": "Str\u00e1nka nenalezena.", "tr": "Sayfa bulunamad\u0131", "lt": "Puslapis nerastas", "it": "Pagina non trovata", "ja": "\u30da\u30fc\u30b8\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093", "zh-tw": "\u627e\u4e0d\u5230\u9801\u9762", "et": "Lehek\u00fclge ei leitud", "he": "\u05d3\u05e3 \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0", "zh": "\u9875\u9762\u6ca1\u6709\u627e\u5230", "ar": "\u0627\u0644\u0635\u0641\u062d\u0629 \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f\u0629", "lv": "Lapa nav atrasta", "id": "Halaman tidak ditemukan", "sr": "Stranica nije prona\u0111ena", "ro": "Pagina nu a fost g\u0103sit\u0103", "ru": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", "eu": "Ez da orria aurkitu", "af": "Bladsy nie gevind nie", "el": "\u0397 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1 \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5", "xh": "Ikhasi alifunyenwanga", "zu": "Ikhasi alitholakali", "st": "Leqephe ha le a fumanwa", "ca": "Pàgina no trobada" }, "descr_NOTFOUND": { "no": "Den angitte siden finnes ike. URLen var: %URL%", "nn": "Fann ikkje den aktuelle sida. URL var: %URL%", "sv": "Den angivna sidan finns inte. URL: %URL%", "es": "La p\u00e1gina que indic\u00f3 no se encontr\u00f3. La URL es: %URL%", "fr": "La page requise est introuvable. L'URL \u00e9tait : %URL%", "de": "Die gew\u00fcnschte Seite konnte nicht gefunden werden, der aufgerufene URL war %URL%", "nl": "Deze pagina bestaat niet. De URL was: %URL%", "sl": "Strani ni bilo mogo\u010de najti. Naveden URL strani je bil: %URL%", "da": "Siden kunne ikke findes. Sidens URL var: %URL%", "hr": "Tra\u017eena stranica nije prona\u0111ena. Adresa stranice je: %URL%", "hu": "Az al\u00e1bbi oldal nem tal\u00e1lhat\u00f3: %URL%", "fi": "Sivua ei l\u00f6ytynyt. Osoite oli %URL%", "pt-br": "A p\u00e1gina determinada n\u00e3o foi encontrada. A URL foi: %URL%", "pt": "A p\u00e1gina n\u00e3o foi encontrada. O URL fornecido foi: %URL%", "pl": "Podana strona nie zosta\u0142a znaleziona. Adres URL by\u0142: %URL%", "cs": "Str\u00e1nka nenalezena. URL je: %URL%", "tr": "Verilen sayfa bulunamad\u0131. URL %URL% idi.", "lt": "\u0160is puslapis nerastas. Puslapio adresas buvo: %URL%", "it": "La pagina data non \u00e8 stata trovata. URL della pagina: %URL%", "ja": "\u4e0e\u3048\u3089\u308c\u305f\u30da\u30fc\u30b8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002URL\u306f: %URL%", "zh-tw": "\u627e\u4e0d\u5230\u60a8\u6240\u8981\u5b58\u53d6\u7684\u9801\u9762\uff0c\u8a72\u7db2\u5740\u662f\uff1a%URL%", "et": "Seda lehek\u00fclge ei leitud. Aadress oli: %URL%", "he": "\u05d4\u05d3\u05e3 \u05d4\u05d4\u05de\u05d1\u05d5\u05e7\u05e9 \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0. \u05d4\u05db\u05ea\u05d5\u05d1\u05ea \u05d4\u05d9\u05d9\u05ea: %URL%", "zh": "\u6ca1\u6709\u627e\u5230\u7ed9\u5b9a\u7684URL\uff1a%URL%", "ar": "\u0627\u0644\u0635\u0641\u062d\u0629 \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f\u0629. \u0627\u0644\u0639\u0646\u0648\u0627\u0646 %URL%", "lv": "Nor\u0101d\u012bt\u0101 lapa nav atrasta. Saite: %URL%", "id": "Halaman yang diminta tidak dapat ditemukan. URL nya adalah %URL%", "sr": "Tra\u017eena stranica nije prona\u0111ena. Adresa stranice je: %URL%", "ro": "Pagina nu a fost g\u0103sit\u0103, URL-ul a fost urm\u0103torul: %URL%", "ru": "\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430. \u0421\u0441\u044b\u043b\u043a\u0430 \u0431\u044b\u043b\u0430: %URL%", "eu": "Ez da aurkitu adierazi duzun orria. URLa hau da: %URL%", "af": "Die bladsy bestaan nie. Die URL was: %URL%", "el": "\u0397 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c0\u03bf\u03c5 \u03b6\u03b7\u03c4\u03ae\u03c3\u03b1\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 %URL% \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5.", "zu": "Ikhasi elinikeziwe alitholakalanga. I-URL ibithi: %URL%", "xh": "Ikhasi elinikelweyo alifunyenwanga. I-URL ngu: %URL%", "st": "Leqephe le fanweng ha le a fumanwa. URL e bile: %URL%", "ca": "No s’ha trobat la pàgina indicada. L’URL és: %URL%" }, "title_NOTFOUNDREASON": { "no": "Kan ikke finne siden", "nn": "Fann ikkje sida", "sv": "Sidan finns inte", "es": "P\u00e1gina no encontrada", "fr": "Page introuvable", "de": "Seite nicht gefunden", "nl": "Pagina niet gevonden", "sl": "Strani ni bilo mogo\u010de najti.", "da": "Siden kunne ikke findes", "hr": "Stranica nije prona\u0111ena", "hu": "Oldal nem tal\u00e1lhat\u00f3", "fi": "Sivua ei l\u00f6ytynyt", "pt-br": "P\u00e1gina n\u00e3o encontrada", "pt": "P\u00e1gina n\u00e3o encontrada", "pl": "Nie znaleziono strony", "cs": "Str\u00e1nka nenalezena", "tr": "Sayfa bulunamad\u0131", "lt": "Puslapis nerastas", "it": "Pagina non trovata", "ja": "\u30da\u30fc\u30b8\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093", "zh-tw": "\u627e\u4e0d\u5230\u9801\u9762", "et": "Lehek\u00fclge ei leitud", "he": "\u05d3\u05e3 \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0", "zh": "\u9875\u9762\u6ca1\u6709\u627e\u5230", "ar": "\u0627\u0644\u0635\u0641\u062d\u0629 \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f\u0629", "lv": "Lapa nav atrasta", "id": "Halaman tidak ditemukan", "sr": "Stranica nije prona\u0111ena", "ro": "Pagina nu a fost g\u0103sit\u0103", "ru": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", "eu": "Ez da orria aurkitu", "af": "Bladsy nie gevind nie", "el": "\u0397 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1 \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5", "xh": "Ikhasi alifunyenwanga", "zu": "Ikhasi alitholakali", "st": "Leqephe ha le a fumanwa", "ca": "Pàgina no trobada" }, "descr_NOTFOUNDREASON": { "no": "Den angitte siden finnes ikke. Grunnen er: %REASON%. URLen var: %URL%", "nn": "Fann ikkje den aktuelle sida p\u00e5 grunn av %REASON%. URLen var %URL%", "sv": "Den angivna sidan finns inte. Orsak: %REASON% URL: %URL%", "es": "La p\u00e1gina que indic\u00f3 no se encontr\u00f3. El motivo es: %REASON% La URL es: %URL%", "fr": "La page demand\u00e9e est introuvable. Motif : %REASON% L'url \u00e9tait : %URL%", "de": "Die gew\u00fcnschte Seite konnte nicht gefunden werden. Der Grund ist: %REASON% Der aufgerufene URL war %URL%", "nl": "De opgegeven pagina kon niet worden gevonden. De oorzaak is: %REASON%. De URL is: %URL%", "sl": "Strani ni bilo mogo\u010de najti. Razlog: %REASON%. Naveden URL strani je bil: %URL%", "da": "Siden kunne ikke findes p\u00e5 grund af %REASON%. Url'en var %URL%", "hr": "Tra\u017eena stranica nije prona\u0111ena. Razlog: %REASON% Adresa stranice je: %URL%", "hu": "%URL% oldal nem tal\u00e1lhat\u00f3, a k\u00f6vetkez\u0151 ok miatt: %REASON% ", "fi": "Sivua ei l\u00f6ytynyt. Syyn\u00e4 oli: %REASON% Osoite oli %URL%", "pt-br": "A p\u00e1gina determinada n\u00e3o foi encontrada. A raz\u00e3o foi: %REASON% A URL foi: %URL%", "pt": "A p\u00e1gina n\u00e3o foi encontrada. A raz\u00e3o foi: %REASON% O URL fornecido foi: %URL%", "pl": "Podana strona nie zosta\u0142a znaleziona. Przyczyn\u0105 by\u0142o: %REASON% Adres strony: %URL%", "cs": "Str\u00e1nka nenalezena. D\u016fvod je: %REASON% URL je: %URL%", "tr": "Verilen sayfa bulunamad\u0131. Nedeni %REASON% idi. URL %URL% idi.", "lt": "\u0160is puslapis nerastas. Prie\u017eastis buvo: %REASON% Puslapio adresas buvo: %URL%", "it": "La pagina data non \u00e8 stata trovata. Motivo: %REASON%, URL: %URL%", "ja": "\u4e0e\u3048\u3089\u308c\u305f\u30da\u30fc\u30b8\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u7406\u7531\u306f: %REASON% URL\u306f: %URL%", "zh-tw": "\u627e\u4e0d\u5230\u60a8\u6240\u8981\u5b58\u53d6\u7684\u9801\u9762\uff0c\u539f\u56e0\uff1a%REASON% \uff1b\u7db2\u5740\uff1a%URL%", "et": "Seda lehek\u00fclge ei leitud. P\u00f5hjus oli %REASON%. Aadress oli: %URL%", "he": "\u05d4\u05d3\u05e3 \u05d4\u05e0\u05d9\u05ea\u05df \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0. \u05d4\u05e1\u05d9\u05d1\u05d4 \u05d4\u05d9\u05d9\u05ea\u05d4 %REASON% \u05d5\u05d4\u05db\u05ea\u05d5\u05d1\u05ea \u05d4\u05d9\u05d9\u05ea\u05d4 %URL%", "zh": "\u7ed9\u5b9a\u7684\u9875\u9762\u6ca1\u6709\u627e\u5230\uff0c\u539f\u56e0: %REASON%; URL: %URL%", "ar": "\u0627\u0644\u0635\u0641\u062d\u0629 \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f\u0629. \u0627\u0644\u0633\u0628\u0628 %REASON% \u0648 \u0627\u0644\u0639\u0646\u0648\u0627\u0646 %URL%", "lv": "Nor\u0101d\u012bt\u0101 lapa nav atrasta. Iemesls: %REASON% Saite: %URL%", "id": "Halaman yang diminta tidak ditemykan, Error-nya adalah: %REASON% URL-nya adalah: %URL%", "sr": "Tra\u017eena stranica nije prona\u0111ena. Razlog: %REASON% Adresa stranice je: %URL%", "ro": "Pagina nu a fost g\u0103sit\u0103, motivul a fost urm\u0103torul: %REASON%, URL-ul a fost: %URL%", "ru": "\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430: %REASON% \u0421\u0441\u044b\u043b\u043a\u0430: %URL%", "eu": "Ez da aurkitu adierazi duzun orria. Arrazoia hau da: %REASON% URL hau da: %URL%", "af": "Die gegewe bladsy is nie gevind nie. Die rede was: %REASON%. Die URL was: %URL%", "el": "\u0397 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c0\u03bf\u03c5 \u03b6\u03b7\u03c4\u03ae\u03c3\u03b1\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 %URL% \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b5: %REASON%", "zu": "Ikhasi elinikeziwe alitholakalanga. Isizathu besithi: %REASON% I-URL ibithi: %URL%", "xh": "Ikhasi elinikelweyo alifunyenwanga. Isizathu sesi: %REASON% I-URL ngu: %URL%", "st": "Leqephe le fanweng ha le a fumanwa. Lebaka e bile: %LEBAKA% URL e bile: %URL%", "ca": "No s’ha trobat la pàgina indicada. El motiu és: %REASON%. L’URL és: %URL%" }, "title_BADREQUEST": { "no": "Feil foresp\u00f8rsel motatt", "nn": "Feil sp\u00f8rsm\u00e5l mottatt", "sv": "Felaktigt anrop", "es": "Recibida una solicitud incorrecta", "fr": "Requ\u00eate invalide", "de": "Ung\u00fcltige Anfrage", "nl": "Incorrect request ontvangen", "sl": "Napaka v prejetem zahtevku.", "da": "Fejlagtig foresp\u00f8rgsel", "hr": "Dobiveni zahtjev nije ispravan", "hu": "Hib\u00e1s k\u00e9r\u00e9s", "pt-br": "A solicita\u00e7\u00e3o recebida \u00e9 inv\u00e1lida", "pt": "Pedido inv\u00e1lido recebido", "pl": "Otrzymano nieprawid\u0142owe \u017cadanie", "cs": "Zasl\u00e1n \u0161patn\u00fd po\u017eadavek", "tr": "Hatal\u0131 istek al\u0131nd\u0131", "fi": "V\u00e4\u00e4r\u00e4nlainen pyynt\u00f6 vastaanotettu", "lt": "Gauta neteisinga u\u017eklausa", "it": "E' stata ricevuta una richiesta erronea.", "ja": "\u4e0d\u6b63\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u53d7\u4fe1\u3057\u307e\u3057\u305f", "zh-tw": "\u932f\u8aa4\u8acb\u6c42", "et": "Saabus halb p\u00e4ring", "he": "\u05d4\u05ea\u05e7\u05d1\u05dc\u05d4 \u05d1\u05e7\u05e9\u05d4 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9\u05ea", "zh": "\u6536\u5230\u4e86\u9519\u8bef\u7684\u8bf7\u6c42", "ar": "\u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0637\u0644\u0628 \u0633\u064a\u0621", "lv": "Sa\u0146emts nepareizs piepras\u012bjums", "id": "Request buruk diterima", "sr": "Dobijeni zahtev nije ispravan", "ro": "S-a primit o cerere incorect\u0103", "ru": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u043a\u043b\u0438\u043a", "eu": "Eskaera oker bat jaso da.", "af": "Foutiewe versoek ontvang", "el": "\u0395\u03c3\u03c6\u03b1\u03bb\u03bc\u03ad\u03bd\u03bf \u03b1\u03af\u03c4\u03b7\u03bc\u03b1", "zu": "Kutholwe umlayezo ongalungile", "xh": "Kufunyenwe isicelo esibi", "st": "Kopo e mpe e amohetswe", "ca": "S'ha rebut una petició incorrecta" }, "descr_BADREQUEST": { "no": "En feil oppsto i foresp\u00f8rselen til denne siden. Grunnen var: %REASON%", "nn": "Det er ein feil i sp\u00f8rringa etter denne sida. Grunnen til dette er %REASON%", "sv": "Det \u00e4r ett fel i anropet till denna sida. Orsak: %REASON%", "es": "Existe un error en la solicitud de esta p\u00e1gina. La raz\u00f3n es: %REASON%", "fr": "Erreur dans la requ\u00eate de cette page. Motif : %REASON%", "de": "In der Anfrage dieser Seite trat ein Fehler auf, der Grund ist: %REASON%", "nl": "Er is een fout opgetreden in het verzoek voor deze pagina. De oorzaak is: %REASON%", "sl": "Pri\u0161lo je do napake pri prejetem zahtevku. Razlog: %REASON%", "da": "Der er en fejl i foresp\u00f8rgslen til siden. Grunden er: %REASON%", "hr": "Dogodila se gre\u0161ka prilikom dohva\u0107anja ove stranice. Razlog: %REASON%", "hu": "Hiba t\u00f6rt\u00e9nt az oldal lek\u00e9rdez\u00e9se k\u00f6zben. A hiba\u00fczenet: %REASON%", "pt-br": "H\u00e1 um erro no pedido para esta p\u00e1gina. O motivo foi: %REASON%", "pt": "Ocorreu um erro com o pedido a esta p\u00e1gina. A raz\u00e3o foi: %REASON%", "cs": "Toho je chyba po\u017eadavku pro tuto str\u00e1nku. D\u016fvod je: %REASON%", "tr": "Bu sayfaya yap\u0131lan istekte bir hata var. Nedeni %REASON% idi.", "lt": "U\u017eklausoje \u012f \u0161\u012f puslap\u012f rasta klaida. Prie\u017eastis buvo: %REASON%", "it": "C'\u00e8 un errore nella richiesta di questa pagina: %REASON%", "ja": "\u30da\u30fc\u30b8\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u7406\u7531\u306f: %REASON%", "zh-tw": "\u9019\u88e1\u6709\u500b\u932f\u8aa4\u65bc\u6b64\u9801\u9762\u7684\u8acb\u6c42\u3002\u539f\u56e0\u70ba\uff1a%REASON%", "et": "Lehek\u00fcljele esitati vigane p\u00e4ring. P\u00f5hjus: %REASON%", "he": "\u05d9\u05e9\u05e0\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05d1\u05e7\u05e9\u05d4 \u05dc\u05d3\u05e3 \u05d6\u05d4. \u05d4\u05e1\u05d9\u05d1\u05d4 \u05d4\u05d9\u05d9\u05ea\u05d4: %REASON%", "zh": "\u8bf7\u6c42\u8be5\u9875\u7684\u8bf7\u6c42\u5b58\u5728\u9519\u8bef\uff0c\u539f\u56e0\uff1a%REASON%", "pl": "Wyst\u0105pi\u0142 nast\u0119puj\u0105cy b\u0142\u0105d w zleceniu: %REASON%", "ar": "\u062e\u0637\u0627 \u0628\u0637\u0644\u0628 \u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629. \u0627\u0644\u0633\u0628\u0628 %REASON%", "lv": "K\u013c\u016bdains piepras\u012bjums \u0161ai lapai. Iemesls: %REASON%", "id": "Terjadi error pada request ke halaman ini. Alasannya adalah: %REASON%", "sr": "Dogodila se gre\u0161ka prilikom dohvatanja ove stranice. Razlog: %REASON%", "ro": "Exist\u0103 o eroare \u00een cererea c\u0103tre aceast\u0103 pagin\u0103. Motivul este: %REASON%", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u041f\u0440\u0438\u0447\u0438\u043d\u0430: %REASON%", "eu": "Errore bat dago orri honen eskaeran. Arrazoia hau da: %REASON%", "af": "Daar is 'n fout in die versoek na die bladsy. Die rede is: %REASON%", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2: %REASON%", "zu": "Kukhona iphutha kusicelo saleli khasi. Isizathu besithi: %REASON%", "xh": "Kukho impazamo kwisicelo kweli khasi. Isizathu sesi: %REASON%", "st": "Ho na le phoso kopong e leqepheng lena. Lebaka e bile: %REASON%", "ca": "Hi ha un error en la sol·licitud d’aquesta pàgina. El motiu és: %REASON%" }, "title_WRONGUSERPASS": { "no": "Feil brukernavn og passord", "nn": "Feil brukarnamn eller passord", "sv": "Felaktig anv\u00e4ndaridentitet eller l\u00f6senord", "es": "Nombre de usuario o contrase\u00f1a incorrectos", "fr": "Nom d'utilisateur ou mot de passe incorrect", "de": "Nutzername oder Passwort falsch.", "nl": "Incorrecte gebruikersnaam of wachtwoord", "sl": "Napa\u010dno uporabni\u0161ko ime ali geslo", "da": "Forkert brugernavn eller kodeord", "hr": "Neispravna korisni\u010dka oznaka ili zaporka", "hu": "Hib\u00e1s felhaszn\u00e1l\u00f3n\u00e9v vagy jelsz\u00f3", "fi": "Virheellinen k\u00e4ytt\u00e4j\u00e4tunnus tai salasana", "pt-br": "Nome de usu\u00e1rio ou senha incorreto.", "pt": "Utilizador ou senha incorrecto", "pl": "Bl\u0119dna nazwa u\u017cytkownika lub has\u0142o", "cs": "\u0160patn\u00e9 jm\u00e9no a heslo.", "tr": "Ge\u00e7ersiz kullan\u0131c\u0131 ad\u0131 yada \u015fifre", "lt": "Neteisingas prisijungimo vardas arba slapta\u017eodis", "it": "Nome utente o password non corretti", "ja": "\u30e6\u30fc\u30b6\u30fc\u540d\u304b\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u9593\u9055\u3063\u3066\u3044\u307e\u3059", "zh-tw": "\u5e33\u865f\u6216\u5bc6\u78bc\u932f\u8aa4", "et": "Kasutajatunnus v\u00f5i parool pole \u00f5ige", "he": "\u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9 \u05d0\u05d5 \u05e1\u05d9\u05e1\u05de\u05d4 \u05dc\u05d0 \u05e0\u05db\u05d5\u05e0\u05d9\u05dd", "zh": "\u4e0d\u6b63\u786e\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801", "ar": "\u0627\u0633\u0645 \u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0648 \u0643\u0644\u0645\u0629 \u0633\u0631 \u062e\u0637\u0627 ", "lv": "Nekorekts lietot\u0101ja v\u0101rds vai parole", "id": "Username atau password salah", "sr": "Neispravno korisni\u010dko ime ili lozinka", "ro": "Nume de utilizator incorect sau parol\u0103 incorect\u0103", "ru": "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c", "eu": "Erabiltzaile-izena edo pasahitz okerra", "af": "Inkorrekte gebruikersnaam of wagwoord", "el": "\u03a4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ae \u03bf \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03bb\u03ac\u03b8\u03bf\u03c2", "zu": "Igama lomsebenzisi elingalungile noma iphasiwedi", "xh": "Igama lomsebenzisi okanye iphaswedi engachanekanga", "st": "Lebitso la mosebedisi kapa phasewete e fosahetseng", "ca": "Nom d'usuari o contrasenya incorrecta" }, "descr_WRONGUSERPASS": { "no": "Enten var brukernavnet, eller kombinasjonen med brukernavn og passord feil. Sjekk brukernavn og passord og pr\u00f8v igjen.", "nn": "Fann ingen brukar med det brukarnamnet du oppgav, eller passordet var feil. Sjekk brukarnamn og pr\u00f8v igjen.", "sv": "Antingen finns det ingen anv\u00e4ndare med angiven anv\u00e4ndaridentitet eller s\u00e5 har du angivit fel l\u00f6senord. F\u00f6rs\u00f6k igen.", "es": "No existe un usuario con el identificador indicado, o la contrase\u00f1a indicada es incorrecta. Por favor revise el identificador de usuario e int\u00e9ntelo de nuevo.", "fr": "Utilisateur inexistant, ou mot de passe incorrect. V\u00e9rifiez le nom d'utilisateur, et r\u00e9-essayez.", "de": "Entweder es konnte kein Nutzer mit dem angegebenen Nutzernamen gefunden werden oder das Passwort ist falsch. \u00dcberpr\u00fcfen Sie die Zugangsdaten und probieren Sie es nochmal.", "nl": "De opgegeven gebruikersnaam bestaat niet, of het wachtwoord is ongeldig. Verifieer de gebruikersnaam en probeer het nogmaals.", "sl": "Uporabnika s tem uporabni\u0161kim imenom ni bilo mogo\u010de najti ali pa je vpisano geslo napa\u010dno. Preverite svoje uporabni\u0161ko ime in poskusite znova.", "da": "Enten kunne brugeren ikke findes eller ogs\u00e5 var kodeordet forkert. Pr\u00f8v igen.", "hr": "Korisnik s navedenom korisni\u010dkom oznakom ne mo\u017ee biti prona\u0111en ili je zaporka koju ste unijeli neispravna. Molimo provjerite korisni\u010dku oznaku i poku\u0161ajte ponovo.", "hu": "Nem l\u00e9tezik ilyen felhaszn\u00e1l\u00f3 vagy a jelsz\u00f3 hib\u00e1s. K\u00e9rj\u00fck, pr\u00f3b\u00e1lja \u00fajra!", "pt-br": "Ou nenhum usu\u00e1rio com o nome de usu\u00e1rio pode ser encontrado, ou a senha que voc\u00ea digitou est\u00e1 incorreta. Verifique o nome de usu\u00e1rio e tente novamente.", "pt": "O utilizador ou senha fornecidos s\u00e3o incorrectos. Por favor tente de novo.", "cs": "U\u017eivatel bu\u010f nebyl nalezen, nebo jste zadal \u0161patn\u00e9 heslo. Pros\u00edm zkontrolujte login a zkuste se p\u0159ihl\u00e1sit znovu.", "tr": "Ya bu kullan\u0131c\u0131 ad\u0131nda bir kullan\u0131c\u0131 bulunamad\u0131, yada \u015fifreniz yanl\u0131\u015f. L\u00fctfen kullan\u0131c\u0131 ad\u0131n\u0131 kontrol edin ve yeniden deneyin.", "lt": "Naudotojas su tokiu prisijungimo vardu nerastas, arba neteisingai \u012fved\u0117te slapta\u017eod\u012f. Pasitikrinkite prisijungimo vard\u0105 ir bandykite dar kart\u0105.", "it": "L'utente fornito non \u00e8 stato trovato, oppure la password fornita era sbagliata. Si prega di verificare il nome utente e provare di nuovo", "zh-tw": "\u627e\u4e0d\u5230\u60a8\u6240\u63d0\u4f9b\u7684\u4f7f\u7528\u8005\u540d\u7a31\u4e4b\u4f7f\u7528\u8005\uff0c\u6216\u60a8\u7d66\u4e86\u932f\u8aa4\u5bc6\u78bc\uff0c\u8acb\u6aa2\u67e5\u4f7f\u7528\u8005\u5e33\u5bc6\u4e26\u518d\u8a66\u4e00\u6b21\u3002", "ja": "\u30e6\u30fc\u30b6\u30fc\u540d\u304c\u898b\u3064\u304b\u3089\u306a\u304b\u3063\u305f\u304b\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u9593\u9055\u3063\u3066\u3044\u308b\u304b\u306e\u4f55\u65b9\u304b\u3067\u3059\u3002\u30e6\u30fc\u30b6\u30fc\u540d\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u78ba\u8a8d\u3057\u3066\u8a66\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "et": "Kas sellise kasutajatunnusega kasutajat ei leitud v\u00f5i pole sinu poolt sisestatud parool \u00f5ige. Palun kontrolli kasutajatunnust ja parooli uuesti.", "he": "\u05d0\u05d5 \u05e9\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0 \u05de\u05e9\u05ea\u05de\u05e9 \u05d1\u05e9\u05dd \u05d6\u05d4, \u05d0\u05d5 \u05e9\u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05dc\u05d0 \u05d4\u05d9\u05d9\u05ea\u05d4 \u05e0\u05db\u05d5\u05e0\u05d4. \u05d1\u05d3\u05d5\u05e7 \u05d1\u05d1\u05e7\u05e9\u05d4 \u05d0\u05ea \u05e9\u05dd \u05d4\u05de\u05e9\u05ea\u05de\u05e9 \u05d5\u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1. ", "zh": "\u5982\u679c\u4e0d\u662f\u7ed9\u5b9a\u7684\u7528\u6237\u540d\u6ca1\u6709\u627e\u5230\u5c31\u662f\u7ed9\u5b9a\u7684\u5bc6\u7801\u9519\u8bef\uff0c\u8bf7\u518d\u6b21\u68c0\u67e5\u7528\u6237\u540d\u548c\u5bc6\u7801", "pl": "Nie istnieje u\u017cytkownik o tej nazwie, lub podano z\u0142e has\u0142o. Sprawd\u017a nazw\u0119 u\u017cytkownika i pon\u00f3w pr\u00f3b\u0119.", "ar": "\u0627\u0645\u0627 \u0627\u0646\u0647 \u0644\u0645 \u0646\u062a\u0645\u0643\u0646 \u0645\u0646 \u0627\u0644\u062a\u0639\u0631\u0641 \u0639\u0644\u064a \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0648 \u0627\u0646 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631 \u062e\u0637\u0627. \u0631\u0627\u062c\u0639 \u0627\u0633\u0645 \u0627\u0644\u062f\u062e\u0648\u0644 \u0648 \u062d\u0627\u0648\u0644 \u0645\u0631\u0629 \u0627\u062e\u0631\u064a", "lv": "Vai nu nav lietot\u0101ja ar nor\u0101d\u012bto lietot\u0101ja v\u0101rdu, vai parole nor\u0101d\u012bta k\u013c\u016bdaini. L\u016bdzu m\u0113\u0123iniet v\u0113lreiz.", "id": "Username yang diberikan tidak dapat ditemukan, atau password yang Anda berikan salah. Silahkan periksa username dan coba lagi.", "sr": "Korisnik s navedenim korisni\u010dkim imenom ne mo\u017ee biti prona\u0111en ili je lozinka koju ste uneli neispravna. Molimo proverite korisni\u010dko ime i poku\u0161ajte ponovo.", "ro": "Nu a fost g\u0103sit niciun utilizator cu numele de utilizator specificat, sau parola introdus\u0103 este gre\u0219it\u0103. V\u0103 rug\u0103m s\u0103 \u00eencerca\u021bi din nou.", "ru": "\u041b\u0438\u0431\u043e \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u043b\u0438\u0431\u043e \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c.\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.", "eu": "Ez dago erabiltzailerik adierazitako identifikadorearekin, edo adierazitako pasahitza okerra da. Mesedez, berrikusi ezazu erabiltzaile-identifikadorea eta saia zaiztez berriro.", "af": "Die gegewe gebruikersnaam bestaan nie, of die wagwoord wat jy verskaf het is verkeerd. Bevestig die gebruikersnaam en probeer weer.", "el": "\u039f \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc\u03c2 \u03bf\u03bd\u03cc\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ba\u03b1\u03b9 \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c9\u03c3\u03c4\u03cc\u03c2. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b5\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03c4\u03b7\u03bd \u03bf\u03c1\u03b8\u03cc\u03c4\u03b7\u03c4\u03b1 \u03c4\u03c9\u03bd \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03c9\u03bd \u03c3\u03b1\u03c2 \u03ba\u03b1\u03b9 \u03c0\u03c1\u03bf\u03c3\u03c0\u03b1\u03b8\u03ae\u03c3\u03c4\u03b5 \u03be\u03b1\u03bd\u03ac.", "zu": "Kungenzeka ukuthi akekho umsebenzisi onegama lomsebenzisi otholiwe, noma iphasiwedi oyinikezile ayilungile. Sicela uhlole igama lomsebenzisi bese uzame futhi.", "xh": "Kusenokwenzeka akukho msebenzisi unegama lomsebenzisi elinikelweyo ofunyenweyo, okanye iphaswedi oyinikeleyo ayichanekanga. Nceda ujonge igama lomsebenzisi uzame kwakhona.", "st": "Ekaba mosebedisi wa lebitso la mosebedisi le fanweng ha a fumanwe, kapa phasewete eo o e fananeng e fosahetse. Ka kopo hlahloba lebitso la mosebedisi la hao, ebe o leka hape.", "ca": "No s’ha pogut trobar cap usuari amb el nom d’usuari donat, o la contrasenya no és correcta. Comproveu el nom d’usuari i torneu-ho a provar." }, "title_RESPONSESTATUSNOSUCCESS": { "no": "Feilmelding mottatt fra innloggingstjenesten", "sv": "Fel mottaget fr\u00e5n IdP", "es": "Hubo un error por parte del IdP", "nl": "Foutmelding ontvangen van Identity Provider", "sl": "Napaka na IdP", "da": "Fejl modtaget fra institution", "tr": "Kimlik Sa\u011flay\u0131c\u0131dan hata al\u0131nd\u0131.", "de": "Fehlermeldung vom Identity Provider erhalten", "fi": "Virhe vastaanotettu Identiteetintarjoajalta.", "pt": "Erro recebido do Fornecedor de Identidade", "fr": "Erreur lev\u00e9e par le fournisseur d'identit\u00e9", "hr": "Autentifikacijski servis je prijavio gre\u0161ku", "nn": "Feil fr\u00e5 vertsorganisasjonen (IdP)", "lt": "Gautas klaidos prane\u0161imas i\u0161 tapatybi\u0173 teik\u0117jo", "it": "E' stato ricevuto un errore dall'Identity Provider", "hu": "Hiba t\u00f6rt\u00e9nt az azonos\u00edt\u00f3 szervezet (IdP) oldal\u00e1n", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u304b\u3089\u30a8\u30e9\u30fc\u3092\u53d7\u4fe1\u3057\u307e\u3057\u305f", "zh-tw": "\u5f9e\u9a57\u8b49\u63d0\u4f9b\u8005\u6536\u5230\u932f\u8aa4", "et": "Identiteedipakkujalt saadi t\u00f5rge", "he": "\u05d4\u05ea\u05e7\u05d1\u05dc\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4 \u05de\u05e1\u05e4\u05e7 \u05d4\u05d6\u05d9\u05d4\u05d5\u05ea", "pt-br": "Erro recebido do Provedor de Identidade", "zh": "\u4ece\u8eab\u4efd\u63d0\u4f9b\u8005\u6536\u5230\u4e00\u4e2a\u9519\u8bef", "pl": "Dostawca to\u017csamo\u015bci przes\u0142a\u0142 b\u0142\u0105d", "ar": "\u062e\u0637\u0627 \u062a\u0645 \u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u064a\u0647 \u0645\u0646 \u0645\u0642\u062f\u0645 \u0627\u0644\u0647\u0648\u064a\u0629", "lv": "K\u013c\u016bda no identit\u0101tes pieg\u0101d\u0101t\u0101ja", "id": "Error diterima dari Identity Provider", "sr": "Davalac Identiteta je prijavio gre\u0161ku", "cs": "Chyba p\u0159ijat\u00e1 od poskytovatele identity", "ro": "Eroare primit\u0103 de la furnizorul de identitate", "ru": "\u041e\u0442 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430", "eu": "Errore bat jazo da IdP-aren aldetik", "af": "Foutmelding ontvang vanaf die Identiteits Verskaffer", "el": "\u039b\u03ae\u03c8\u03b7 \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03cd \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1\u03c4\u03bf\u03c2 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c0\u03ac\u03c1\u03bf\u03c7\u03bf \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2", "zu": "Iphutha litholwe ukusuka Kumhlinzeki Kamazisi", "xh": "Impazamo efunyenwe kuMboneleli Wesazisi", "st": "Phoso e amohetswe ho tswa ho Mofani wa Boitsebiso", "ca": "S'ha rebut un error del proveïdor d’identitats" }, "descr_RESPONSESTATUSNOSUCCESS": { "no": "Innloggingstjenesten svarte med en feilmelding. (Statuskoden i SAML-svaret var noe annet enn OK)", "sv": "Identitetshanteraren (Identity Provider) svarade med ett felmeddelande. (Statusmeddelandet i SAML-svaret var ett felmeddelande)", "es": "El IdP respondi\u00f3 a la solicitud con un error. (El c\u00f3digo de estado en la respuesta SAML no fue exitoso)", "nl": "De Identity Provider antwoordde met een fout. (De statuscode in de SAML Response was niet success)", "sl": "Odziv IdP vsebuje napako (\"SAML-Response\" ni uspel)! ", "da": "Institutionen har sendt en fejl. (Status koden i SAML responset var ikke succes)", "tr": "Kimlik Sa\u011flay\u0131c\u0131 hatal\u0131 cevap verdi. (SAML Cevab\u0131'ndaki durum kodu ba\u015far\u0131lamad\u0131)", "de": "Der Identity Provider gab einen Fehler zur\u00fcck (Der Statuscode in der SAML-Antwort war nicht \"Erfolg\")", "fi": "Identiteetintarjoaja vastasi virheell\u00e4. ( Tilakoodi SAML vastauksessa oli ep\u00e4onnistunut)", "pt": "O Fornecedor de Identidade respondeu com um erro. (A resposta SAML cont\u00e9m um c\u00f3digo de insucesso)", "fr": "Le fournisseur d'identit\u00e9 a renvoy\u00e9 une erreur (le code de statut de la r\u00e9ponse SAML n'indiquait pas le succ\u00e8s)", "hr": "Autentifikacijski servis je poslao odgovor koji sadr\u017ei informaciju o pojavi gre\u0161ke. (\u0160ifra statusa dostavljena u SAML odgovoru ne odgovara \u0161ifri uspje\u0161no obra\u0111enog zahtjeva)", "nn": "Vertsorganisasjonen din (IdP) gav feilmelding (SAML-svaret hadde statuskode som varsla om feil)", "lt": "Tapatybi\u0173 teik\u0117jas atsak\u0117 klaidos prane\u0161imu. (Statuso kodas SAML atsakyme buvo nes\u0117kmingas)", "it": "L'Identity Provider ha risposto con un errore. (Il codice di stato nel messaggio SAML Response non indicava un successo)", "hu": "Hiba t\u00f6rt\u00e9nt az azonos\u00edt\u00f3 szervezet (IdP) oldal\u00e1n. Ismeretlen \u00e1llapotk\u00f3d.", "zh-tw": "\u9a57\u8b49\u63d0\u4f9b\u8005\u56de\u61c9\u4e00\u500b\u932f\u8aa4\u3002(\u5728 SAML \u56de\u61c9\u88e1\u7684\u72c0\u614b\u78bc\u986f\u793a\u70ba\u4e0d\u6210\u529f)", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u304c\u30a8\u30e9\u30fc\u3092\u53d7\u3051\u3068\u308a\u307e\u3057\u305f\u3002(SAML\u30ec\u30b9\u30dd\u30f3\u30b9\u306b\u5931\u6557\u3057\u305f\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9)", "et": "Identiteedipakkuja vastas t\u00f5rkega (SAML-vastuse olekukood polnud positiivne).", "he": "\u05e1\u05e4\u05e7 \u05d4\u05d6\u05d9\u05d4\u05d5\u05ea \u05d4\u05d7\u05d6\u05d9\u05e8 \u05e9\u05d2\u05d9\u05d0\u05d4. (\u05e7\u05d5\u05d3 \u05d4\u05de\u05e6\u05d1 \u05d1\u05ea\u05d2\u05d5\u05d1\u05ea \u05d4 SAML \u05e9\u05d5\u05e0\u05d4 \u05de\u05d4\u05e6\u05dc\u05d7\u05d4)", "pt-br": "O Provedor de Identidade respondeu com um erro. (O c\u00f3digo de resposta do SAML n\u00e3o teve sucesso.", "zh": "\u8eab\u4efd\u63d0\u4f9b\u8005\u7684\u5e94\u7b54\u5b58\u5728\u9519\u8bef\uff08SAML\u5e94\u7b54\u72b6\u6001\u7801\u5e76\u6ca1\u6709\u6210\u529f\uff09", "pl": "Odpowied\u017a dostawcy to\u017csamo\u015bci oznacza b\u0142\u0105d (kod stanu w odpowiedzi SAML nie oznacza sukcesu)", "ar": "\u0645\u0642\u062f\u0645 \u0627\u0644\u0647\u0648\u064a\u0629 \u0627\u0633\u062a\u062c\u0627\u0628 \u0628\u062e\u0637\u0623. (\u0631\u0645\u0632 \u0627\u0644\u062d\u0627\u0644\u0629 \u0628\u0627\u0633\u062a\u062c\u0627\u0628\u0629 SAML \u0641\u0627\u0634\u0644)", "lv": "Identit\u0101tes pieg\u0101d\u0101t\u0101js atbild\u0113jis ar k\u013c\u016bdu. Statusa kods SAML atbild\u0113 at\u0161\u0137iras no veiksm\u012bga", "id": "Identity Provider merespon dengan error. (Kode status di Response SAML adalah tidak berhasil)", "sr": "Davalac Identiteta je poslao odgovor koji sadr\u017ei informaciju o pojavi gre\u0161ke(\u0160ifra statusa dostavljena u SAML odgovoru ne odgovara \u0161ifri uspe\u0161no obra\u0111enog zahteva).", "cs": "Poskytovatel identity odpov\u011bd\u011bl chybou. (Stavov\u00fd k\u00f3d v SAML nebyl \u00fasp\u011b\u0161n\u00fd)", "ro": "Furnizorul de identitate a r\u0103spuns cu o eroare. (Codul de stare in r\u0103spunsul SAML a fost \u00eencercare nereu\u0219it\u0103)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435. (\u041a\u043e\u0434 \u0441\u0442\u0430\u0442\u0443\u0441 \u0432 \u043e\u0442\u043a\u043b\u0438\u043a\u0435 SAML \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0435)", "eu": "Idp-ak errore batekin erantzun dio eskaerari. (SAML erantzunean egoera kodea ez da arrakastatsua izan)", "af": "Die Identiteits Verskaffer reageer met 'n fout. (Die status kode in die SAML reaksie was onsuksesvol)", "el": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2 \u03c0\u03bf\u03c5 \u03c0\u03b5\u03c1\u03b9\u03ad\u03c7\u03b5\u03b9 \u03b7 \u03b1\u03c0\u03ac\u03bd\u03c4\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03c0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03c5\u03c0\u03bf\u03b4\u03b5\u03b9\u03ba\u03bd\u03cd\u03b5\u03b9 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1.", "xh": "Umboneleli Wesazisi uphendule ngempazamo. (Ikhowudi yobume kwiMpendulo ye-SAML ayiphumelelanga)", "zu": "Umhlinzeki Womazisi uphendule ngephutha. (Ikhodi yesimo Sempendulo ye-SAML ayizange iphumelele)", "st": "Mofani wa Boitsebiso o arabetse ka phoso. (Khoutu ya boemo Karabelong ya SAML ha e a atleha)", "ca": "El proveïdor d’identitat ha respost amb un error (el codi d'estat de la resposta SAML no ha estat exitós)." }, "title_NOCERT": { "fr": "Aucun certificat pr\u00e9sent\u00e9", "sl": "Ni digitalnega potrdila", "da": "Intet certifikat", "de": "Kein Zertifikat", "nn": "Manglar sertifikat", "sv": "Inget certfikat", "lt": "N\u0117ra sertifikato", "it": "Nessun certificato", "no": "Ikke noe sertifikat mottatt", "es": "No certificado", "hu": "Hi\u00e1nyz\u00f3 tan\u00fas\u00edtv\u00e1ny.", "ja": "\u8a3c\u660e\u66f8\u304c\u3042\u308a\u307e\u305b\u3093", "nl": "Geen certificaat", "hr": "Nema digitalnog certifikata", "zh-tw": "\u7121\u6191\u8b49", "et": "Sertifikaat puudub", "he": "\u05d0\u05d9\u05df \u05ea\u05e2\u05d5\u05d3\u05d4", "pt-br": "Sem Certificado", "zh": "\u65e0\u8bc1\u4e66", "pl": "Brak certyfikatu", "ar": "\u0627\u0644\u0634\u0647\u0627\u062f\u0627\u062a \u0645\u0641\u0642\u0648\u062f\u0629", "lv": "Nav sertifik\u0101ta", "id": "Tidak ada sertifikat", "sr": "Nema digitalnog sertifikata", "cs": "Chyb\u00ed certiifik\u00e1t", "ro": "Lipse\u0219te certificatul", "ru": "\u0421\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442", "eu": "Ziurtagiri gabe", "fi": "Ei sertifikaattia", "af": "Geen sertifikaat", "el": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc", "xh": "Akukho satifikethi", "zu": "Asikho isitifiketi", "st": "Ha ho setifikeiti", "ca": "Sense certificat" }, "descr_NOCERT": { "fr": "\u00c9chec de l'authentification : votre navigateur n'a pas pr\u00e9sent\u00e9 de certificat", "sl": "Avtentikacija je spodletela: va\u0161 spletni brskalnik ni posredoval digitalnega potrdila!", "da": "Login fejlede - din browser sendte ikke noget certifikat", "de": "Authentifizierung fehlgeschlagen: ihr Browser hat kein Zertifikat gesandt", "nn": "Feil autentisering: din browser sender ikkje sertifikat", "sv": "Inloggning mislyckades: Din webbl\u00e4sare skickade inget certifikat", "lt": "Autentikacija nepavyko: J\u016bs\u0173 nar\u0161ykl\u0117 nei\u0161siunt\u0117 jokio sertifikato", "it": "L'autenticazione \u00e8 fallita perch\u00e9 il tuo browser non ha inviato alcun certificato", "no": "Autentisering feilet: nettleseren din sendte ikke noe klient-sertifikat", "es": "Fallo de autenticaci\u00f3n: su navegador no envi\u00f3 ning\u00fan certificado", "hu": "Azonos\u00edt\u00e1si hiba: a b\u00f6ng\u00e9sz\u0151 nem k\u00fcld\u00f6tt tan\u00fas\u00edtv\u00e1nyt.", "nl": "Authenticatie niet gelukt: uw browser stuurde geen certificaat", "ja": "\u8a8d\u8a3c\u5931\u6557: \u3042\u306a\u305f\u306e\u30d6\u30e9\u30a6\u30b6\u306f\u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3057\u307e\u305b\u3093\u3067\u3057\u305f", "hr": "Neuspje\u0161na autentifikacija: va\u0161 web preglednik nije poslao digitalni certifikat", "zh-tw": "\u8a8d\u8b49\u932f\u8aa4\uff1a\u60a8\u7684\u700f\u89bd\u5668\u4e26\u672a\u9001\u51fa\u4efb\u4f55\u6191\u8b49", "et": "Autentimine ei \u00f5nnestunud: brauser ei saatnud \u00fchtegi sertifikaati", "he": "\u05d4\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4: \u05d4\u05d3\u05e4\u05d3\u05e4\u05df \u05dc\u05d0 \u05e9\u05dc\u05d7 \u05ea\u05e2\u05d5\u05d3\u05d4", "pt-br": "Falha na Autentica\u00e7\u00e3o: Seu navegador (browser) n\u00e3o enviou nenhum certificado", "zh": "\u8ba4\u8bc1\u5931\u8d25\uff0c\u4f60\u7684\u6d4f\u89c8\u5668\u6ca1\u6709\u53d1\u9001\u4efb\u4f55\u8bc1\u4e66", "pl": "Nie powiod\u0142o si\u0119 uwierzytelnienie: przegl\u0105darka nie przes\u0142a\u0142a certyfikatu", "ar": "\u0641\u0634\u0644 \u0627\u0644\u062a\u0648\u062b\u064a\u0642 \u0644\u0627\u0646 \u0645\u062a\u0635\u0641\u062d\u0643 \u0644\u0645 \u064a\u0631\u0633\u0644 \u0634\u0647\u0627\u062f\u0627\u062a", "lv": "Autentifik\u0101cija neizdev\u0101s, jo J\u016bsu interneta p\u0101rl\u016bks nav ats\u016bt\u012bjis nevienu sertifik\u0101tu", "id": "Autentifikasi gagal: Browser anada tidak mengirim sertifikat", "sr": "Neuspe\u0161na autentifikacija: va\u0161 web pretra\u017eiva\u010d nije poslao digitalni sertifikat", "cs": "P\u0159ihl\u00e1\u0161en\u00ed neprob\u011bhlo: V\u00e1\u0161 prohl\u00ed\u017ee\u010d neodeslal \u017e\u00e1dn\u00fd certifik\u00e1t", "ro": "Autentificare e\u0219uat\u0103: browser-ul dumneavoastr\u0103 nu a trimis niciun certificat", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438: \u0432\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043d\u0435 \u0432\u044b\u0441\u043b\u0430\u043b \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Kautotze okerra: zure nabigatzaileak ez du bidali ziurtagiririk ", "af": "Verifikasie het misluk: Jou webblaaier het geen sertifikaat gestuur nie", "el": "\u0397 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5: \u03a4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ae\u03b3\u03b7\u03c3\u03b7\u03c2 \u03b9\u03c3\u03c4\u03bf\u03cd \u03c0\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af\u03c4\u03b5 \u03b4\u03b5\u03bd \u03ad\u03c3\u03c4\u03b5\u03b9\u03bb\u03b5 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc.", "zu": "Ukuqinisekisa kuhlulekile: isiphequluli sakho asizange sithumele noma yisiphi isitifiketi", "xh": "Ungqinisiso lusilele: ibhrawuza yakho ayithumelanga nasiphi na isatifikethi", "st": "Netefatso e hlolehile: sebadi sa hao ha se a romela setifikeiti sa letho", "ca": "Ha fallat l’autenticació: el navegador no ha enviat cap certificat" }, "title_INVALIDCERT": { "fr": "Certificat invalide", "sl": "Neveljavno digitalno potrdilo", "da": "Ugyldigt certifikat", "de": "Ung\u00fcltiges Zertifikat", "nn": "Ugyldig sertifikat", "sv": "Felaktigt certifikat", "lt": "Nevalidus sertifikatas", "it": "Certificato non valido", "no": "Ugyldig sertifikat", "es": "Certificado inv\u00e1lido", "hu": "Hib\u00e1s tan\u00fas\u00edtv\u00e1ny.", "ja": "\u7121\u52b9\u306a\u8a3c\u660e\u66f8\u3067\u3059", "nl": "Ongeldig certificaat", "hr": "Neispravan digitalni certifikat", "zh-tw": "\u7121\u6548\u6191\u8b49", "et": "Vigane sertifikaat", "he": "\u05ea\u05e2\u05d5\u05d3\u05d4 \u05dc\u05d0-\u05d7\u05d5\u05e7\u05d9\u05ea", "pt-br": "Certificado Inv\u00e1lido", "zh": "\u65e0\u6548\u7684\u8bc1\u4e66", "pl": "Niepoprawny certyfikat", "ar": "\u0634\u0647\u0627\u062f\u0629 \u063a\u064a\u0631 \u0635\u062d\u064a\u062d\u0629", "lv": "Neder\u012bgs sertifik\u0101ts", "id": "Sertifikat invalid", "sr": "Neispravan digitalni sertifikat", "cs": "\u0160patn\u00fd certifik\u00e1t", "ro": "Certificat nevalid", "ru": "\u041d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Ziurtagiri baliogabea", "fi": "Virheellinen sertifikaatti", "af": "Ongeldige sertifikaat", "el": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc", "xh": "Isatifikethi esingasebenziyo", "zu": "Isifiketi esingalungile", "st": "Setifikeiti se sa nepahalang", "ca": "Certificat no vàlid" }, "descr_INVALIDCERT": { "fr": "\u00c9chec de l'authentification : le certificat pr\u00e9sent\u00e9 par votre navigateur est invalide ou illisible", "sl": "Avtentikacija je spodletela: va\u0161 spletni brskalnik je posredoval neveljavno digitalno potrdilo ali pa ga ni mo\u010d prebrati!", "de": "Authentifizierung fehlgeschlagen: das von ihrem Browser gesandte Zertifikat ist ung\u00fcltig oder kann nicht gelesen werden", "nn": "Feil autentisering: sertifikatet fr\u00e5 browsaren din er ugyldig eller uleseleg", "sv": "Inloggning mislyckades: Certfikatet som din webbl\u00e4sare skickade var felaktigt eller kunde inte l\u00e4sas", "lt": "Autentikacija nepavyko: J\u016bs\u0173 nar\u0161ykl\u0117s si\u0173stas sertifikatas yra nevalidus arba negali b\u016bti perskaitytas", "it": "L'autenticazione \u00e8 fallita perch\u00e9 il tuo browser ha inviato un certificato non valido o illegibile.", "no": "Autentisering feilet: sertifikatet nettleseren din sendte er ugyldig, og kan ikke leses", "es": "Fallo de autenticaci\u00f3n: El certificado enviado por su navegador es inv\u00e1lido o no puede ser le\u00eddo", "hu": "Azonos\u00edt\u00e1si hiba: a b\u00f6ng\u00e9sz\u0151 \u00e1ltal k\u00fcld\u00f6tt tan\u00fas\u00edtv\u00e1ny hib\u00e1s.", "nl": "Authenticatie niet gelukt: uw browser stuurde een certificaat dat ongeldig is of niet gelezen kon worden", "ja": "\u8a8d\u8a3c\u5931\u6557: \u3042\u306a\u305f\u306e\u30d6\u30e9\u30a6\u30b6\u306f\u7121\u52b9\u304b\u8aad\u3080\u3053\u3068\u306e\u51fa\u6765\u306a\u3044\u8a3c\u660e\u66f8\u3092\u9001\u4fe1\u3057\u307e\u3057\u305f\u3002", "da": "Authentifikation fejlede: Certifikatet som din browser har sendt er ugyldigt og kan ikke l\u00e6ses", "hr": "Neuspje\u0161na autentifikacija: digitalni certifikat koji je poslao va\u0161 web preglednik nije ispravan ili se ne mo\u017ee pro\u010ditati", "zh-tw": "\u9a57\u8b49\u5931\u6557\uff1a\u60a8\u7684\u700f\u89bd\u5668\u50b3\u9001\u4e4b\u6191\u8b49\u70ba\u7121\u6548\u6216\u7121\u6cd5\u8b80\u53d6", "et": "Autentimine ei \u00f5nnestunud: brauseri poolt saadetud sertifikaat on vigane v\u00f5i pole loetav", "he": "\u05d4\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4: \u05d4\u05ea\u05e2\u05d5\u05d3\u05d4 \u05e9\u05d4\u05d3\u05e4\u05d3\u05e4\u05df \u05e9\u05dc\u05d7 \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9\u05ea \u05d0\u05d5 \u05dc\u05d0 \u05e0\u05d9\u05ea\u05e0\u05ea \u05dc\u05e7\u05e8\u05d9\u05d0\u05d4", "pt-br": "Falha na Autentica\u00e7\u00e3o: O certificado que seu navegador (browser) enviou \u00e9 inv\u00e1lido ou n\u00e3o pode ser lido", "zh": "\u8ba4\u8bc1\u5931\u8d25\uff1a\u4f60\u7684\u6d4f\u89c8\u5668\u53d1\u9001\u7684\u8bc1\u4e66\u65e0\u6548\u6216\u8005\u4e0d\u80fd\u8bfb\u53d6", "pl": "Nie powiod\u0142o si\u0119 uwierzytelnienie: certyfikat przes\u0142any przez przegl\u0105dark\u0119 jest niepoprawny lub nie mo\u017ce zosta\u0107 przeczytany", "ar": "\u0641\u0634\u0644 \u0627\u0644\u062a\u0648\u062b\u064a\u0642 \u0644\u0627\u0646 \u0645\u062a\u0635\u0641\u062d\u0643 \u0627\u0631\u0633\u0644 \u0634\u0647\u0627\u062f\u0627\u062a \u063a\u064a\u0631 \u0635\u062d\u064a\u062d\u0629 \u0627\u0648 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0642\u0631\u0627\u0621\u062a\u0647\u0627 ", "lv": "Autentifik\u0101cija neizdev\u0101s, jo J\u016bsu interneta p\u0101rl\u016bks ats\u016bt\u012bjis neder\u012bgu vai nelas\u0101mu sertifik\u0101tu", "id": "Autentifikasi gagal: Sertifikat yang browser Anda kirimkan invalid atau tidak dapat dibaca", "sr": "Neuspe\u0161na autentifikacija: digitalni sertifikat koji je poslao va\u0161 web pretra\u017eiva\u010d nije ispravan ili se ne mo\u017ee pro\u010ditati", "cs": "P\u0159ihl\u00e1\u0161en\u00ed neprob\u011bhlo: certifik\u00e1t kter\u00fd odeslal V\u00e1\u0161 rohl\u00ed\u017ee\u010d nemohl b\u00fdt p\u0159e\u010dten", "ro": "Autentificare e\u0219uat\u0103: certificatul trimis de browser-ul dumneavoastr\u0103 nu este valid sau nu poate fi citit", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438: \u0432\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432\u044b\u0441\u043b\u0430\u043b \u043d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043b\u0438 \u043d\u0435\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Kautotze okerra: Zure nabigatzaileak bidalitako ziurtagiria baliogabea da edo ezin da irakurri", "af": "Verifikasie het misluk: Jou webblaaier het 'n ongeldige of korrupte sertifikaat gestuur", "el": "\u0397 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5: \u03a4\u03bf \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc \u03c0\u03bf\u03c5 \u03ad\u03c3\u03c4\u03b5\u03b9\u03bb\u03b5 \u03c4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ae\u03b3\u03b7\u03c3\u03b7\u03c2 \u03b9\u03c3\u03c4\u03bf\u03cd \u03c0\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af\u03c4\u03b5 \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03ae \u03b4\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03ae \u03c4\u03bf\u03c5.", "xh": "Ungqinisiso lusilele: isatifikethi esithunyelwe yibhrawuza yakho asisebenzi okanye asikwazi ukufundwa", "zu": "Ukuqinisekisa kuhlulekile: isitifiketi esithunyelwe isiphequluli sakho asivumelekile noma asikwazi ukufundwa", "st": "Netefatso e hlolehile: setifikeiti seo sebadi sa hao se se rometseng ha se a nepahala kapa ha se balehe", "ca": "Ha fallat l’autenticació: el certificat que el navegador ha enviat no és vàlid o no es pot llegir" }, "title_UNKNOWNCERT": { "fr": "Certificat inconnu", "sl": "Nepoznano digitalno potrdilo", "de": "Unbekanntes Zertifikat", "nn": "Ukjent sertifikat", "sv": "Ok\u00e4nt certfikat", "lt": "Ne\u017einomas sertifikatas", "it": "Certificato sconosciuto", "no": "Ukjent sertifikat", "es": "Certificado desconocido", "hu": "Ismeretlen tan\u00fas\u00edtv\u00e1ny", "ja": "\u4e0d\u660e\u306a\u8a3c\u660e\u66f8\u3067\u3059", "nl": "Onbekend certificaat", "da": "Ukendt certifikat", "hr": "Nepoznat digitalni certifikat", "zh-tw": "\u672a\u77e5\u7684\u6191\u8b49", "et": "Tundmatu sertifikaat", "he": "\u05ea\u05e2\u05d5\u05d3\u05d4 \u05dc\u05d0 \u05d9\u05d3\u05d5\u05e2\u05d4", "pt-br": "Certificado Desconhecido", "zh": "\u672a\u77e5\u7684\u8bc1\u4e66", "pl": "Nieznany certyfikat", "ar": "\u0634\u0647\u0627\u062f\u0629 \u063a\u064a\u0631 \u0645\u0639\u0644\u0648\u0645\u0629", "lv": "Nepaz\u012bstams sertifik\u0101ts", "id": "Sertifikat tidak dikenal", "sr": "Nepoznat digitalni sertifikat", "cs": "Nezn\u00e1m\u00fd certifik\u00e1t", "ro": "Certificat necunoscut", "ru": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Ziurtagiri ezezaguna", "fi": "Tuntematon sertifikaatti", "af": "Onbekende sertifikaat", "el": "\u0386\u03b3\u03bd\u03c9\u03c3\u03c4\u03bf \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc", "zu": "Isitifiketi esingaziwa", "xh": "Isatifikethi esingaziwayo", "st": "Setifikeiti se sa tsejweng", "ca": "Certificat desconegut" }, "descr_UNKNOWNCERT": { "fr": "\u00c9chec de l'authentification : le certificat pr\u00e9sent\u00e9 par votre navigateur n'est pas connu", "sl": "Avtentikacija je spodletela: va\u0161 spletni brskalnik je posredoval nepoznano digitalno potrdilo", "de": "Authentifizierung fehlgeschlagen: das von ihrem Browser gesandte Zertifikat ist unbekannt", "nn": "Feil autentisering: ukjent sertifikat mottatt fr\u00e5 din browser", "sv": "Inloggning mislyckades: Certifikatet som din webbl\u00e4sare skickade \u00e4r ok\u00e4nt", "lt": "Autentikacija nepavyko: J\u016bs\u0173 nar\u0161ykl\u0117s si\u0173stas sertifikatas yra ne\u017einomas", "it": "L'autenticazione \u00e8 fallita perch\u00e9 il tuo browser ha inviato un certificat sconosciuto.", "no": "Authentisering feilet: sertifikatet nettleseren din sendte er ukjent", "es": "Fallo de autenticaci\u00f3n:el certificado enviado por su navegador es desconocido", "hu": "Azonos\u00edt\u00e1si hiba: a b\u00f6ng\u00e9sz\u0151 \u00e1ltal k\u00fcld\u00f6tt tan\u00fas\u00edtv\u00e1nyt ismeretlen t\u00edpus\u00fa.", "ja": "\u8a8d\u8a3c\u306b\u5931\u6557\u3057\u307e\u3057\u305f: \u30d6\u30e9\u30a6\u30b6\u304b\u3089\u4e0d\u660e\u306a\u8a3c\u660e\u66f8\u304c\u9001\u3089\u308c\u307e\u3057\u305f", "nl": "Authenticatie niet gelukt: het certificaat dat uw browser stuurde is onbekend", "da": "Authentifikation fejlede: Certifikatet som din browser har send er ukendt", "hr": "Neuspje\u0161na autentifikacija: digitalni certifikat kojeg je poslao va\u0161 web preglednik je nepoznat", "zh-tw": "\u8a8d\u8b49\u932f\u8aa4\uff1a\u60a8\u7684\u700f\u89bd\u5668\u50b3\u9001\u4e86\u4e00\u500b\u672a\u77e5\u7684\u6191\u8b49", "et": "Autentimine ei \u00f5nnestunud: brauser saatis tundmatu sertifikaadi", "he": "\u05d4\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4: \u05d4\u05ea\u05e2\u05d5\u05d3\u05d4 \u05e9\u05d4\u05d3\u05e4\u05d3\u05e4\u05df \u05e9\u05dc\u05d7 \u05dc\u05d0 \u05d9\u05d3\u05d5\u05e2\u05d4", "pt-br": "Falha na Autentica\u00e7\u00e3o: O certificado que seu navegador (browser) enviou \u00e9 desconhecido", "zh": "\u8ba4\u8bc1\u5931\u8d25\uff1a\u4f60\u7684\u6d4f\u89c8\u5668\u53d1\u9001\u7684\u662f\u672a\u77e5\u7684\u8bc1\u4e66", "pl": "Nie powiod\u0142o si\u0119 uwierzytelnienie: certyfikat przes\u0142any przez przegl\u0105dark\u0119 jest nieznany", "ar": "\u0641\u0634\u0644 \u0627\u0644\u062a\u0648\u062b\u064a\u0642 \u0644\u0627\u0646 \u0645\u062a\u0635\u0641\u062d\u0643 \u0627\u0631\u0633\u0644 \u0634\u0647\u0627\u062f\u0647 \u063a\u064a\u0631 \u0645\u0639\u0644\u0648\u0645\u0629", "lv": "Autentifik\u0101cija neizdev\u0101s, jo J\u016bsu interneta p\u0101rl\u016bks ats\u016bt\u012bjis nepaz\u012bstamu sertifik\u0101tu", "id": "Autentifikasi gagal: sertifikat yang browser anda kirimkan tidak dikenal", "sr": "Neuspe\u0161na autentifikacija: digitalni sertifikat koji je poslao va\u0161 web pretra\u017eiva\u010d je nepoznat", "cs": "P\u0159ihl\u00e1\u0161en\u00ed neprob\u011bhlo: certifik\u00e1t kter\u00fd odeslal V\u00e1\u0161 prohl\u00ed\u017ee\u010d je nezn\u00e1m\u00fd", "ro": "Autentificare e\u0219uat\u0103: certificatul trimis de browser-ul dumneavoastr\u0103 nu este recunoscut", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438: \u0432\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0432\u044b\u0441\u043b\u0430\u043b \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442", "eu": "Kautotze okerra: zure nabigatzaileak bidalitako ziurtagiria ezezaguna da", "af": "Verifikasie het misluk: die sertifikaat wat jou webblaaier gestuur het is onbekend", "el": "\u0397 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5: \u03a4\u03bf \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03cc \u03c0\u03bf\u03c5 \u03ad\u03c3\u03c4\u03b5\u03b9\u03bb\u03b5 \u03c4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c0\u03b5\u03c1\u03b9\u03ae\u03b3\u03b7\u03c3\u03b7\u03c2 \u03b9\u03c3\u03c4\u03bf\u03cd \u03c0\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b5\u03af\u03c4\u03b5 \u03b4\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03cc \u03bd\u03b1 \u03b1\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b5\u03af.", "zu": "Ukuqinisekisa kuhlulekile: isitifiketi esithunyelwe isiphequluli sakho asaziwa", "xh": "Ungqinisiso lusilele: isatifikerthi esithunyelwe yibhrawuza yakho asaziwa", "st": "Netefatso e hlolehile: setifikeiti se rometsweng ke sebadi sa hao ha se tsejwe", "ca": "Ha fallat l’autenticació: el certificat que el navegador ha enviat és desconegut" }, "title_USERABORTED": { "da": "Autentificering aubrudt", "hr": "Proces autentifikacije je prekinut", "it": "Autenticazione interrotta", "sv": "Inloggning avbruten", "sl": "Avtentikacija prekinjena", "no": "Godkjenning avbrutt", "ja": "\u8a8d\u8a3c\u306f\u4e2d\u65ad\u3055\u308c\u307e\u3057\u305f", "zh-tw": "\u8a8d\u8b49\u53d6\u6d88", "et": "Autentimine katkestatud", "he": "\u05d4\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea \u05d1\u05d5\u05d8\u05dc\u05d4", "de": "Authentifizierung abgebrochen", "pt-br": "Autentica\u00e7\u00e3o abortada", "zh": "\u8ba4\u8bc1\u4e2d\u6b62", "lt": "Autentikacija nutraukta", "es": "Autenticacion abortada", "pl": "Przerwane uwierzytelnienie", "ar": "\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u062a\u0648\u062b\u064a\u0642", "lv": "Autentifik\u0101cija p\u0101rtraukta", "id": "Autentifikasi dibatalkan", "sr": "Proces autentifikacije je prekinut", "nl": "Authenticatie afgebroken", "hu": "Azonos\u00edt\u00e1s megszak\u00edtva", "nn": "Avbroten innlogging", "fr": "Authentification abandonn\u00e9e", "cs": "P\u0159ihl\u00e1\u0161en\u00ed odm\u00edtnuto", "ro": "Autentificare \u00eentrerupt\u0103", "ru": "\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430", "eu": "Kautotzea bertan behera utzia", "af": "Verifikasie gestop", "el": "\u0397 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03bc\u03b1\u03c4\u03b1\u03b9\u03ce\u03b8\u03b7\u03ba\u03b5", "zu": "Ukuqinisekisa kuyekisiwe", "xh": "Ungqinisiso luyekiwe", "st": "Netefatso e kgaoditswe", "ca": "S'ha avortat l’autenticació" }, "descr_USERABORTED": { "da": "Autentificering blev afbrudt af brugeren", "hr": "Korisnik je prekinuo proces autentifikacie", "it": "L'autenticazione \u00e8 stata interrotta dall'utente", "sv": "Inloggning avbr\u00f6ts av anv\u00e4ndaren", "sl": "Avtentikacija prekinjena na zahtevo uporabnika", "no": "Godkjenningen ble avbrutt av brukeren", "ja": "\u8a8d\u8a3c\u306f\u30e6\u30fc\u30b6\u30fc\u306b\u3088\u3063\u3066\u4e2d\u65ad\u3055\u308c\u307e\u3057\u305f", "zh-tw": "\u4f7f\u7528\u8005\u4e2d\u65b7\u8a8d\u8b49", "et": "Autentimine katkestati kasutaja poolt", "he": "\u05d4\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea \u05d1\u05d5\u05d8\u05dc\u05d4 \u05e2\u05dc \u05d9\u05d3\u05d9 \u05d4\u05de\u05e9\u05ea\u05de\u05e9", "de": "Die Authentifizierung wurde durch den Benutzer abgebrochen", "pt-br": "A autentica\u00e7\u00e3o foi abortada pelo usu\u00e1rio", "zh": "\u8ba4\u8bc1\u88ab\u7528\u6237\u4e2d\u6b62", "lt": "Autentikacija nutrauk\u0117 naudotojas", "es": "La Autenticacion fue abortada por el usuario", "pl": "Uwierzytelnienie zosta\u0142o przerwane przez u\u017cytkownika", "ar": "\u062a\u0645 \u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u062a\u0648\u062b\u064a\u0642 \u0628\u0648\u0627\u0633\u0637\u0629 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645", "lv": "Autentifik\u0101ciju p\u0101rtraucis lietot\u0101js", "id": "Autentifikasi dibatalkan oleh user", "sr": "Korisnik je prekinuo proces autentifikacie", "hu": "Az azonos\u00edt\u00e1st a felhaszn\u00e1l\u00f3 megszak\u00edtotta", "nn": "Innlogging blei avbroten av sluttbrukaren", "fr": "L'authentification a \u00e9t\u00e9 abandonn\u00e9e par l'usager", "cs": "P\u0159ihl\u00e1\u0161en\u00ed bylo p\u0159eru\u0161eno u\u017eivatelem", "nl": "De authenticatie is afgebroken door de gebruiker", "ro": "Autentificarea a fost \u00eentrerupt\u0103 de utilizator", "ru": "\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c", "eu": "Kautotzea bertan behera utzi du erabiltzaileak", "af": "Die verifikasie is gestop deur die gebruiker", "el": "\u0397 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03bc\u03b1\u03c4\u03b1\u03b9\u03ce\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7.", "zu": "Ukuqinisekisa kuyekiswe umsebenzisi", "xh": "Ungqinisiso luyekiswe ngumsebenzisi", "st": "Netefatso e kgaoditswe ke mosebedisi", "ca": "L’usuari ha cancel·lat l’autenticació" }, "title_NOSTATE": { "da": "State information tabt", "hr": "Podaci o stanju su izgubljeni", "it": "Informazioni di stato perse", "sv": "Sessionsinformationen \u00e4r borttappad", "sl": "Podatki o stanju so izgubljeni", "no": "Tilstandsinformasjon tapt", "ja": "\u72b6\u614b\u60c5\u5831\u3092\u5931\u3044\u307e\u3057\u305f", "zh-tw": "\u72c0\u614b\u8cc7\u8a0a\u907a\u5931", "et": "Olekuinfo kadunud", "he": "\u05d0\u05d1\u05d3 \u05de\u05d9\u05d3\u05e2 \u05d4\u05de\u05e6\u05d1", "de": "Statusinformationen verloren", "zh": "\u72b6\u6001\u4fe1\u606f\u4e22\u5931", "lt": "B\u016bsenos informacija prarasta", "es": "Informaci\u00f3n de estado perdida", "pl": "Utracono informacje o stanie", "ar": "\u0641\u0642\u062f\u0627\u0646 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062d\u0627\u0644\u0629", "hu": "Elveszett az \u00e1llapotinform\u00e1ci\u00f3", "lv": "St\u0101vok\u013ca inform\u0101cija pazaud\u0113ta", "id": "Informasi state hilang", "sr": "Podaci o stanju su izgubljeni", "nn": "Mista tilstandsinformasjon", "fr": "Information d'\u00e9tat perdue", "cs": "Stavov\u00e1 informace ztracena", "nl": "Toestandsinformatie verloren", "ro": "Informa\u021bia de stare a fost pierdut\u0103", "ru": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0443\u0442\u0435\u0440\u044f\u043d\u0430", "eu": "Egoera informazioa galdua", "af": "Toestandsinformasie verlore", "pt-br": "Informa\u00e7\u00f5es de estado perdidas", "el": "\u0394\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b1\u03b9\u03c4\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2", "xh": "Inkcazelo yobume ilahlekile", "zu": "Ulwazi lwesifunda lulahlekile", "st": "Tlhahisoleseding ya provense e lahlehile", "ca": "Informació d'estat perduda" }, "descr_NOSTATE": { "da": "State information er tabt og der er ikke muligt at gentage forsp\u00f8rgelsen", "hr": "Podaci o stanju su izgubljeni i zahtjev se ne mo\u017ee reproducirati", "it": "Le informazioni di stato sono andate perse, e non c'\u00e8 modo di far ripartire la richiesta", "sv": "Sessionsinformationen \u00e4r borttappad och det \u00e4r inte m\u00f6jligt att \u00e5terstarta f\u00f6rfr\u00e5gan", "sl": "Podatki o stanju so izgubljeni, zato zahteve ni mogo\u010de obnoviti\/ponovno zagnati.", "no": "Tilstandsinformasjon tapt, det er ikke mulig \u00e5 gjenoppta foresp\u00f8rselen", "ja": "\u72b6\u614b\u60c5\u5831\u3092\u5931\u3044\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u518d\u958b\u51fa\u6765\u307e\u305b\u3093", "zh-tw": "\u72c0\u614b\u8cc7\u8a0a\u907a\u5931\uff0c\u4e14\u7121\u6cd5\u91cd\u65b0\u555f\u52d5\u8acb\u6c42", "et": "Olekuinfo l\u00e4ks kaduma ja p\u00e4ringut pole v\u00f5imalik uuesti k\u00e4ivitada", "he": "\u05d0\u05d1\u05d3 \u05de\u05d9\u05d3\u05e2 \u05d4\u05de\u05e6\u05d1, \u05d5\u05d0\u05d9 \u05d0\u05e4\u05e9\u05e8 \u05dc\u05d4\u05ea\u05d7\u05dc \u05de\u05d7\u05d3\u05e9 \u05d0\u05ea \u05d4\u05d1\u05e7\u05e9\u05d4", "de": "Die Statusinformationen gingen verloren und die Anfrage kann nicht neu gestartet werden", "zh": "\u72b6\u6001\u4fe1\u606f\u4e22\u5931\uff0c\u5e76\u4e14\u65e0\u6cd5\u91cd\u65b0\u8bf7\u6c42", "lt": "B\u016bsenos informacija prarasta, n\u0117ra galimybi\u0173 pakartoti u\u017eklaus\u0105", "es": "Informaci\u00f3n de estado perdida y no hay manera de restablecer la petici\u00f3n", "pl": "Utracono informacje o stanie i nie ma mo\u017cliwo\u015bci ponowienia zlecenia", "ar": "\u0641\u0642\u062f\u0627\u0646 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062d\u0627\u0644\u0629 \u0648 \u0644\u0627 \u064a\u0645\u0643\u0646 \u0627\u0639\u0627\u062f\u0629 \u0627\u0644\u0628\u062f\u0621 \u0644\u0644\u0637\u0644\u0628", "lv": "St\u0101vok\u013ca inform\u0101cija pazaud\u0113ta un nav iesp\u0113jams atk\u0101rtot piepras\u012bjumu", "id": "Informasi state hilang, dan tidak ada cara untuk me-restat request", "sr": "Podaci o stanju su izgubljeni i zahtev se ne mo\u017ee reprodukovati", "hu": "\u00c1llapotinform\u00e1ci\u00f3 elveszett, a k\u00e9r\u00e9st nem lehet \u00fajraind\u00edtani", "nn": "Mista tilstandsinformasjon, og klarer ikkje \u00e5 gjera omstart", "fr": "Information d'\u00e9tat perdue, et aucun moyen de relancer la requ\u00eate", "cs": "Stavov\u00e1 informace ", "nl": "Informatie over de toestand is verloren, en het verzoek kan niet herstart worden", "ro": "Informa\u021bia de stare a fost pierdut\u0103, cererea nu poate fi reluat\u0103", "ru": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0443\u0442\u0435\u0440\u044f\u043d\u0430, \u043d\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u043d\u043e\u0432\u043e", "eu": "Egoera informazioa galdua eta ez dago modurik eskaera berrabiarazteko", "af": "Toestandsinformasie verlore en daar is geen manier om die versoek weer te stuur nie", "pt-br": "Informa\u00e7\u00f5es de estado perdidas, e n\u00e3o \u00e9 poss\u00edvel reiniciar a requisi\u00e7\u00e3o", "el": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03cc \u03bd\u03b1 \u03b5\u03be\u03c5\u03c0\u03b7\u03c1\u03b5\u03c4\u03b7\u03b8\u03b5\u03af \u03c4\u03bf \u03b1\u03af\u03c4\u03b7\u03bc\u03ac \u03c3\u03b1\u03c2 \u03ba\u03b1\u03b8\u03ce\u03c2 \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03ae \u03c4\u03bf\u03c5", "xh": "Inkcazelo yobume ilahlekile, yaye akukho ndlela yokuqalisa isicelo", "zu": "Ulwazi lwesifunda lulahlekile, futhi ayikho indlela yokuqala kabusha isicelo", "st": "Tlhahisoleeding ya porofensi e lahlehile, mmeha ho tsela ya ho qala kopo botjha", "ca": "Infomració d'estat perduda, i no hi ha cap manera de reiniciar la sol·licitud" }, "title_METADATANOTFOUND": { "da": "Metadata ikke fundet", "hr": "Metapodaci nisu prona\u0111eni", "it": "Metadati non trovati", "sv": "Metadata saknas", "sl": "Metapodatkov ni bilo mo\u010d najti", "no": "Ingen metadata funnet", "ja": "\u30e1\u30bf\u30c7\u30fc\u30bf\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093", "et": "Metaandmeid ei leitud", "he": "\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0 \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2", "zh-tw": "\u627e\u4e0d\u5230 Metadata", "de": "Keine Metadaten gefunden", "zh": "\u6ca1\u6709\u627e\u5230\u5143\u4fe1\u606f", "lt": "Metaduomenys nerasti", "es": "Metadatos no econtrados", "pl": "Nie znaleziono metadanych", "ar": "\u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627 \u0645\u0641\u0642\u0648\u062f\u0629", "lv": "Metadati nav atrasti", "id": "Metadata tidak ditemukan", "sr": "Metapodaci nisu prona\u0111eni", "hu": "Metadata nem tal\u00e1lhat\u00f3", "nn": "Finn ikkje metadata", "fr": "M\u00e9tadonn\u00e9es non trouv\u00e9es", "nl": "Metadata niet gevonden", "ro": "Metadatele nu au fost g\u0103site", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b", "cs": "Metadata nenalezena", "eu": "Ez dira metadatuak aurkitu", "af": "Metadata nie gevind nie", "pt-br": "Metadado n\u00e3o encontrado", "el": "\u0394\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1", "zu": "Imethadatha ayitholakalanga", "xh": "Imetadata ayifunyenwanga", "st": "Metadata ha e a fumanwa", "ca": "Metadades no trobades" }, "descr_METADATANOTFOUND": { "da": "Kan ikke finde metadata for %ENTITYID%", "hr": "Metapodaci za %ENTITYID% nisu prona\u0111eni", "it": "Impossibile individuare i metatadi per %ENTITYID%", "sv": "Kan inte hitta metadata f\u00f6r %ENTITYID%", "sl": "Metapodatkov za %ENTITYID% ni bilo mo\u010d najti", "no": "Ikke mulig \u00e5 finne metadata for %ENTITYID%", "ja": "%ENTITYID% \u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093", "et": "Olemi metaandmeid ei leitud: %ENTITYID%", "he": "\u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05dc\u05d0\u05ea\u05e8 \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e2\u05d1\u05d5\u05e8 %ENTITYID%", "zh-tw": "\u7121\u6cd5\u627e\u5230 Metadata \u65bc %ENTITYID%", "de": "Keine Metadaten f\u00fcr %ENTITYID% gefunden", "zh": "\u65e0\u6cd5\u4e3a%ENTITYID%\u5b9a\u4f4d\u5143\u4fe1\u606f", "lt": "Nepavyko rasti objekto %ENTITYID% metaduomen\u0173", "es": "No se puede localizar los metadatos en %ENTITYID%", "pl": "Nie mo\u017cna zlokalizowa\u0107 metadanych dotycz\u0105cych %ENTITYID%", "ar": "\u0644\u0627 \u064a\u0645\u0643\u0646 \u062a\u062d\u062f\u064a\u062f \u0645\u0648\u0642\u0639 \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627 \u0644 %ENTITYID%", "lv": "Nav iesp\u0113jams atrast metadatus priek\u0161 %ENTITYID%", "id": "Tidak dapat menemukan metadata untuk %ENTITYID%", "sr": "Metapodaci za %ENTITYID% nisu prona\u0111eni", "hu": "%ENTITYID% entit\u00e1shoz nem tal\u00e1lhat\u00f3 metadataA", "nn": "Klarer ikkje \u00e5 finna metadata for %ENTITYID%", "fr": "Impossible de localiser les m\u00e9tadonn\u00e9es pour %ENTITYID%", "nl": "Kan geen metadata vinden voor %ENTITYID%", "ro": "Nu pot fi localizate metadatele pentru %ENTITYID%", "ru": "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f %ENTITYID%", "cs": "Nebyly nalezeny metadata pro %ENTITYID%", "eu": "Ezin da aurkitu metadaturik %ENTITYID%-(a)rentzat", "af": "Kan geen metadata vind vir %ENTITYID%", "pt-br": "N\u00e3o foi poss\u00edvel localizar os metadados de %ENTITYID%", "el": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03cc \u03bd\u03b1 \u03b2\u03c1\u03b5\u03b8\u03bf\u03cd\u03bd \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1 %ENTITYID%", "xh": "Ayikwazi ukufumana iimpawu-ngcaciso zefayile ze-%ENTITYID%", "zu": "Ayikwazi ukuthola imethadatha yokuthi %ENTITYID%", "st": "Ha e kgone ho fumana metadata bakeng sa %ID YA SETHEO%", "ca": "No es poden localitzar les metadades per a %ENTITYID%" }, "title_AUTHSOURCEERROR": { "hr": "Gre\u0161ka u autentifikacijskom modulu", "zh-tw": "\u8a8d\u8b49\u4f86\u6e90\u932f\u8aa4", "sl": "Napaka v avtentikacijskem viru", "sv": "Inloggningsk\u00e4llfel", "ja": "\u8a8d\u8a3c\u5143\u30a8\u30e9\u30fc", "et": "Autentimisallika t\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05de\u05e7\u05d5\u05e8 \u05d4\u05d4\u05d6\u05d3\u05d4\u05d5\u05ea", "de": "Authentifizierungsquellenfehler", "zh": "\u8ba4\u8bc1\u6e90\u9519\u8bef", "da": "Authentication source fejl", "lt": "Autentikacijos \u0161altinio klaida", "es": "Error en la Autenticacion de origen", "pl": "B\u0142\u0105d \u017ar\u00f3d\u0142a uwierzytelnienia", "ar": "\u062e\u0637\u0627 \u0628\u0645\u0635\u062f\u0631 \u0627\u0644\u062a\u0648\u062b\u064a\u0642", "lv": "Autentifik\u0101cijas avota k\u013c\u016bda", "id": "Error sumber autentifikasi", "sr": "Gre\u0161ka u autentifikacionom modulu", "hu": "Azonos\u00edt\u00e1si forr\u00e1s hiba", "nn": "Innloggingsfeil: autentisering", "fr": "Erreur sur la source d'authentification", "it": "Errore di sorgente di autenticazione", "nl": "Fout in authenticatiebron", "ro": "Eroare surs\u0103 de autentificare", "no": "Autentiseringskildefeil", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438", "cs": "Chyba autentiza\u010dn\u00edho zdroje", "eu": "Errorea kautotze jatorrian", "af": "Fout in verifikasie bron", "pt-br": "Erro na fonte de autentica\u00e7\u00e3o", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b7\u03b3\u03ae \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2", "zu": "Iphutha lomthombo wokuqinisekisa", "xh": "Impazamo yomthombo wongqinisiso", "st": "Phoso ya netefatso ya mohlodi", "ca": "Error en l’autenticació d'origen" }, "descr_AUTHSOURCEERROR": { "hr": "Do\u0161lo je do gre\u0161ke u autentifikacijskom modulu %AUTHSOURCE%. Razlog: %REASON%", "zh-tw": "\u8a8d\u8b49\u932f\u8aa4\u4f86\u81ea %AUTHSOURCE% \u3002\u539f\u56e0\u70ba\uff1a %REASON%", "sl": "Napaka v avtentikacijskem viru: %AUTHSOURCE%. Opis napake: %REASON%", "sv": "Fel i inloggningsk\u00e4llan %AUTHSOURCE%. Orsaken var:%REASON%", "ja": "\u8a8d\u8a3c\u5143: %AUTHSOURCE% \u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u7406\u7531: %REASON%", "et": "T\u00f5rge autentimisallikas %AUTHSOURCE%. P\u00f5hjus: %REASON%", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05de\u05e7\u05d5\u05e8 \u05d4\u05d6\u05d3\u05d4\u05d5\u05ea %AUTHSOURCE%. \u05d4\u05e1\u05d9\u05d1\u05d4 \u05d4\u05d9\u05d9\u05ea\u05d4: %REASON%", "de": "Authentifizierungsfehler in der Quelle %AUTHSOURCE%. Der Grund hier f\u00fcr ist: %REASON%", "zh": "\u8ba4\u8bc1\u6e90%AUTHSOURCE%\u5b58\u5728\u9519\u8bef\uff0c \u539f\u56e0: %REASON%", "da": "Autentificeringsfejl i %AUTHSOURCE%. \u00c5rsagen var: %REASON%", "lt": "Autentikacijos klaida %AUTHSOURCE% \u0161altinyje. Prie\u017eastis: %REASON%", "es": "Error en la Autenticacion en el origen %AUTHSOURCE%. La razon fue: %REASON%", "pl": "B\u0142\u0105d uwierzytelnienia dla \u017ar\u00f3d\u0142a %AUTHSOURCE%. Przyczyn\u0105 jest: %REASON%", "ar": "\u062e\u0637\u0627 \u0628\u0645\u0635\u062f\u0631 \u0627\u0644\u062a\u0648\u062b\u064a\u0642 %AUTHSOURCE% \u0646\u062a\u064a\u062c\u0629 \u0644 %REASON%", "lv": "Autentifik\u0101cijas k\u013c\u016bda avot\u0101 %AUTHSOURCE%. Iemesls: %REASON%", "id": "Error autentifikasi di sumber %AUTHSOURCE%. Alasannya adalah: %REASON%", "sr": "Do\u0161lo je do gre\u0161ke u autentifikacionom modulu %AUTHSOURCE%. Razlog: %REASON%", "hu": "A(z) %AUTHSOURCE% azonos\u00edt\u00e1si forr\u00e1sban hiba van. A ok: %REASON%", "nn": "Innloggingsfeil knytta til %AUTHSOURCE% p\u00e5 grunn av %REASON%", "fr": "Erreur d'authentification pour la source %AUTHSOURCE%. La raison \u00e9tait %REASON%", "it": "Errore di autenticazione in sorgente %AUTHSOURCE%. La ragione \u00e8 $REASON%", "nl": "Fout in authenticatiebron %AUTHSOURCE%. Als reden werd gegeven: %REASON%.", "ro": "Eroare de autentificare la sursa %AUTHSOURCE%. Motivul a fost: %REASON%", "no": "Feil i autentiseringskilden %AUTHSOURCE%. Feilen var: %REASON%", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 %AUTHSOURCE%. \u041f\u0440\u0438\u0447\u0438\u043d\u0430: %REASON%", "cs": "Autentiza\u010dn\u00ed chyba ve zdroji %AUTHSOURCE%. D\u016fvodem bylo: %REASON%", "eu": "Errorea kautotze jatorrian %AUTHSOURCE%. Arrazoia hau da: %REASON%", "af": "Fout in verifikasie bron %AUTHSOURCE%. Die rede was %REASON%", "pt-br": "Erro de autentica\u00e7\u00e3o na origem %AUTHSOURCE%. O motivo foi:%REASON%", "el": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b7\u03b3\u03ae \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2 %AUTHSOURCE%: %REASON%", "zu": "Iphutha lokuqinisekisa kumthombo othi %AUTHSOURCE%. Isizathu besithi: %REASON%", "xh": "Impazamo yongqinisiso kumthombo %AUTHSOURCE%. Isizathu sesi: %REASON%", "st": "Phoso ya tiiso mohloding %AUTHSOURCE%. Lebaka e bile: %REASON%", "ca": "Error en l’autenticació d'origen %AUTHSOURCE%. El motiu és: %REASON%" }, "title_MEMCACHEDOWN": { "zh-tw": "\u7121\u6cd5\u53d6\u5f97\u9023\u7dda Session \u8cc7\u8a0a", "el": "\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bd\u03ac\u03ba\u03c4\u03b7\u03c3\u03b7 \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1\u03c2", "xh": "Ayikwazi ukubuyisela ingcombolo yeseshoni", "zu": "Ayikwazi ukubuyisela idatha yeseshini", "st": "Ha e a kgona ho fumana datha ya seshene", "ca": "No es poden recuperar les dades de la sessió" }, "descr_MEMCACHEDOWN": { "zh-tw": "\u60a8\u7684\u9023\u7dda Session \u8cc7\u8a0a\u56e0\u70ba\u6280\u8853\u56f0\u96e3\u73fe\u5728\u7121\u6cd5\u53d6\u5f97\uff0c\u8acb\u7a0d\u5f85\u5e7e\u5206\u9418\u5f8c\u518d\u91cd\u8a66", "el": "\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bd\u03ac\u03ba\u03c4\u03b7\u03c3\u03b7 \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1\u03c2 \u03bb\u03cc\u03b3\u03c9 \u03c4\u03b5\u03c7\u03bd\u03b9\u03ba\u03ce\u03bd \u03b4\u03c5\u03c3\u03ba\u03bf\u03bb\u03b9\u03ce\u03bd. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03be\u03b1\u03bd\u03ac \u03b1\u03c1\u03b3\u03cc\u03c4\u03b5\u03c1\u03b1", "zu": "Idatha yeseshini yakho ayikwazi ukubuyiswa njengamanje ngenxa yezinkinga zobuchwepheshe. Sicela uzame futhi emizuzwini embalwa.", "xh": "Ingcombolo yeseshoni yakho ayikwazi ukubuyiselwa okwangoku ngenxa yeengxaki zobugcisa. Nceda uzame kwakhona kwimizuzu embalwa.", "st": "Datha ya seshene ya hao ha e kgone ho fumanwa hona jwale ka lebaka la mathata a sethekeniki. Ka kopo leka hape kamora metsotso e mmalwa.", "ca": "Les vostres dades de sessió no es poden recuperar ara mateix a causa de dificultats tècniques. Torneu-ho a provar d'aquí a uns minuts." } } simplesamlphp-1.19.1/dictionaries/attributes.translation.json0000644000000000000000000023544114042503475023267 0ustar rootroot{ "attribute_edupersonaffiliation": { "no": "Tilh\u00f8righet", "nn": "Rolle ved organisasjonen", "sv": "Anknytning", "es": "Afiliaci\u00f3n", "fr": "Affiliation", "de": "Organisationszugeh\u00f6rigkeit", "nl": "Affiliatie", "lb": "Zesummenschloss", "sl": "Vloga uporabnika", "da": "Brugerens tilknytning til hjemmeorganisationen", "se": "Du doaibma organisa\u0161uvnnas", "hr": "Povezanost s ustanovom", "hu": "Viszony", "fi": "Suhde organisaatioon", "pt-br": "Filia\u00e7\u00e3o", "pt": "Afilia\u00e7\u00e3o com a organiza\u00e7\u00e3o de origem", "pl": "Przynale\u017cno\u015b\u0107 (Affiliation)", "cs": "Vztah k organizaci", "tr": "Ba\u011flant\u0131", "it": "Affiliazione", "lt": "Pareigos", "ja": "\u6240\u5c5e", "zh-tw": "\u9023\u7d61\u65b9\u5f0f", "he": "\u05d4\u05e9\u05ea\u05d9\u05d9\u05db\u05d5\u05ea", "ru": "\u0427\u043b\u0435\u043d\u0441\u0442\u0432\u043e", "et": "Rollid", "zh": "\u8054\u7edc\u65b9\u5f0f", "sr": "Povezanost sa institucijom", "ar": "\u062c\u0647\u0629 \u0627\u0644\u0639\u0645\u0644", "id": "Afiliasi", "lv": "Pieder\u012bba", "ro": "Afiliere", "eu": "Afiliazioa", "af": "Affiliasie", "el": "\u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1\u002f\u03b5\u03c2", "xh": "Indima", "zu": "Indima", "st": "Kamano", "ca": "Afiliació" }, "attribute_title": { "no": "Tittel", "nn": "Tittel", "sv": "Titel", "es": "Tratamiento", "fr": "Titre", "de": "Titel", "nl": "Titel", "lb": "Zougeh\u00e9iregkeet", "sl": "Naziv", "da": "Titel", "hr": "Naziv", "hu": "C\u00edm", "fi": "Titteli", "pt-br": "T\u00edtulo", "pt": "T\u00edtulo", "pl": "Tytu\u0142 (Title)", "cs": "Nadpis", "eu": "Tratamendua", "tr": "Ba\u015fl\u0131k", "it": "Titolo", "lt": "Pavadinimas", "ja": "\u30bf\u30a4\u30c8\u30eb", "zh-tw": "\u6a19\u984c", "he": "\u05ea\u05d5\u05d0\u05e8", "ru": "\u0417\u0430\u0433\u043b\u0430\u0432\u0438\u0435", "et": "Tiitel", "zh": "\u6807\u9898", "sr": "Zvanje", "ar": "\u0627\u0644\u0644\u0642\u0628", "id": "Gelar", "lv": "Amats", "ro": "Titlu\/titulatur\u0103", "af": "Titel", "el": "\u03a4\u03af\u03c4\u03bb\u03bf\u03c2", "xh": "Isibizo", "zu": "Isiqu", "st": "Thaetlele", "ca": "Tractament" }, "attribute_uid": { "no": "Bruker-ID", "nn": "Lokalt brukarnamn", "sv": "Anv\u00e4ndaridentitet", "es": "Identificador de usuario", "fr": "ID Utilisateur", "de": "Nutzer ID", "nl": "Gebruikers ID", "lb": "Benotzer ID", "sl": "Uporabni\u0161ko ime", "da": "Brugernavn", "se": "Namahus", "hr": "Identifikator korisnika u ustanovi", "hu": "Felhaszn\u00e1l\u00f3i azonos\u00edt\u00f3", "fi": "uid", "pt-br": "Identifica\u00e7\u00e3o (UID)", "pt": "Identifica\u00e7\u00e3o de utilizador", "pl": "ID u\u017cytkownika (User ID)", "cs": "Identifik\u00e1tor (UID)", "eu": "Erabiltzaile ID", "tr": "Kullan\u0131c\u0131 ID", "it": "Identificativo utente", "lt": "Naudotojo ID", "ja": "\u30e6\u30fc\u30b6\u30fcID", "zh-tw": "\u4f7f\u7528\u8005 ID", "et": "Kasutaja ID", "he": "\u05de\u05d6\u05d4\u05d4 \u05de\u05e9\u05ea\u05de\u05e9", "ru": "ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "zh": "\u7528\u6237ID", "sr": "Korisni\u010dko ime", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u062a\u0639\u0631\u064a\u0641\u064a \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645", "id": "User ID", "lv": "Lietot\u0101ja ID", "ro": "ID utilizator", "af": "Gebruikers ID", "el": "\u0391\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7", "xh": "I-ID yomsebenzisi", "zu": "I-ID yomsebenzisi", "st": "ID ya Mosebedisi", "ca": "Identificador d'usuari" }, "attribute_sn": { "no": "Etternavn", "nn": "Etternamn", "sv": "Efternamn", "es": "Apellidos", "fr": "Nom", "de": "Nachname", "nl": "Achternaam", "lb": "Virnumm", "sl": "Priimek", "da": "Efternavn", "se": "Goargu", "hr": "Prezime", "hu": "Vezet\u00e9kn\u00e9v", "fi": "Sukunimi", "pt-br": "Sobrenome", "pt": "Nome de fam\u00edlia", "pl": "Nazwisko (Surname)", "cs": "P\u0159\u00edjmen\u00ed", "eu": "Abizenak", "tr": "Soyad\u0131", "it": "Cognome", "lt": "Pavard\u0117", "ja": "\u59d3", "zh-tw": "\u59d3", "et": "Perekonnanimi", "he": "\u05e9\u05dd \u05de\u05e9\u05e4\u05d7\u05d4", "ru": "\u0424\u0430\u043c\u0438\u043b\u0438\u044f", "zh": "\u59d3", "sr": "Prezime", "ar": "\u0627\u0633\u0645 \u0627\u0644\u0639\u0627\u0626\u0644\u0647", "id": "Nama Keluaga", "lv": "Uzv\u0101rds", "ro": "Nume de familie", "af": "Van", "el": "\u0395\u03c0\u03ce\u03bd\u03c5\u03bc\u03bf", "zu": "Isibongo", "xh": "Ifani", "st": "Difane", "ca": "Cognoms" }, "attribute_givenname": { "no": "Fornavn", "nn": "Fornamn", "sv": "F\u00f6rnamn", "es": "Nombre", "fr": "Pr\u00e9nom", "de": "Vorname", "nl": "Voornaam", "lb": "Familliennumm", "sl": "Ime", "da": "Fornavn(e)", "se": "Ovdanamma", "hr": "Ime", "hu": "Keresztn\u00e9v", "fi": "Etunimet", "pt-br": "Nome", "pt": "Nome Pr\u00f3prio", "pl": "Imi\u0119 (Given name)", "cs": "K\u0159estn\u00ed jm\u00e9no", "tr": "Verilen isim", "it": "Nome ", "lt": "Vardas", "ja": "\u540d", "zh-tw": "\u540d", "et": "Eesnimi", "he": "\u05e9\u05dd \u05e4\u05e8\u05d8\u05d9", "ru": "\u0418\u043c\u044f", "zh": "\u540d", "sr": "Ime", "ar": "\u0627\u0644\u0627\u0633\u0645", "id": "Nama", "lv": "V\u0101rds", "ro": "Prenume", "eu": "Izena", "af": "Voornaam", "el": "\u038c\u03bd\u03bf\u03bc\u03b1", "xh": "Igama elinikiweyo", "zu": "Igama lokuzalwa", "st": "Lebitso le fanweng", "ca": "Nom" }, "attribute_cn": { "no": "Fullt navn", "nn": "Fullt namn", "sv": "Fullst\u00e4ndigt namn", "es": "Nombre com\u00fan (CN)", "fr": "Nom usuel", "de": "Voller Name", "nl": "Algemene naam", "lb": "Allgem\u00e9ngen Numm", "sl": "Ime in priimek", "da": "Kaldenavn", "se": "Olles namma", "hr": "Ime i prezime", "hu": "Teljes n\u00e9v", "fi": "K\u00e4ytt\u00f6nimi", "pt-br": "Nome Comum (CN)", "pt": "Nome completo", "pl": "Nazwa (Common name)", "cs": "Cel\u00e9 jm\u00e9no (CN)", "tr": "Ortak ad", "it": "Nome completo", "lt": "Pilnas vardas", "ja": "\u4e00\u822c\u540d", "zh-tw": "\u5e38\u7528\u540d\u5b57", "he": "\u05e9\u05dd \u05e8\u05d5\u05d5\u05d7 ", "ru": "\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f", "et": "\u00dcldnimi", "zh": "\u5e38\u7528\u540d\u5b57", "sr": "Ime i Prezime", "ar": "\u0623\u0633\u0645\u0627\u0621 \u0627\u062e\u0631\u064a", "id": "Common Name", "lv": "V\u0101rds", "ro": "Nume comun", "eu": "Izen arrunta (CN)", "af": "Algemene naam", "el": "\u039a\u03bf\u03b9\u03bd\u03cc \u03cc\u03bd\u03bf\u03bc\u03b1 (CN)", "zu": "Igama elivamile", "xh": "Igama eliqhelekileyo", "st": "Lebitso le tlwaelehileng", "ca": "Nom comú (CN)" }, "attribute_mail": { "no": "E-post", "nn": "Epostadresse", "sv": "E-postadress", "es": "Correo electr\u00f3nico", "fr": "Courriel", "de": "Emailadresse", "nl": "E-mail", "lb": "E-mail", "sl": "Elektronski naslov", "da": "Emailadresse", "se": "Elektrovnnala\u0161 poasta\u010dijuhus", "hr": "Elektroni\u010dka adresa", "hu": "E-mail", "fi": "S\u00e4hk\u00f6posti", "pt-br": "E-mail", "pt": "E-mail", "pl": "E-mail", "cs": "Email", "eu": "Posta", "tr": "Posta", "it": "Mail", "lt": "El.pa\u0161tas", "ja": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9", "zh-tw": "Email", "et": "E-post", "he": "\u05d3\u05d5\u05d0\u05e8", "ru": "\u041f\u043e\u0447\u0442\u0430", "zh": "\u90ae\u7bb1", "sr": "Elektronska adresa", "ar": "\u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f\u064a", "id": "Mail", "lv": "Pasts", "ro": "Mail", "af": "E-pos", "el": "Email", "zu": "Imeyili", "xh": "Iposi", "st": "Poso", "ca": "Adreça de correu electrònic" }, "attribute_mobile": { "no": "Mobiltelefon", "nn": "Mobiltelefon", "sv": "Mobiltelefon", "es": "Tel\u00e9fono m\u00f3vil", "fr": "Mobile", "de": "Mobiltelefon", "nl": "Mobiel", "lb": "GSM Nummer", "sl": "Mobilni telefon", "da": "Telefonnummer (mobil)", "se": "M\u00e1tketelefovdna", "hr": "Broj mobilnog telefona", "hu": "Mobil", "fi": "K\u00e4nnykk\u00e4", "pt-br": "Celular", "pt": "Telem\u00f3vel", "pl": "Telefon kom\u00f3rkowy (Mobile)", "cs": "Mobil", "eu": "Mugikorra", "tr": "Cep telefonu numaras\u0131", "it": "Cellulare", "lt": "Mobiliojo numeris", "ja": "\u643a\u5e2f\u96fb\u8a71", "zh-tw": "\u624b\u6a5f", "et": "Mobiil", "he": "\u05e0\u05d9\u05d9\u05d3", "ru": "\u041c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439", "zh": "\u624b\u673a", "sr": "Broj mobilnog telefona", "ar": "\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062a\u0641 \u0627\u0644\u0633\u064a\u0627\u0631", "id": "Handphone", "lv": "Mobilais telefons", "ro": "Mobil", "af": "Selfoon", "el": "\u039a\u03b9\u03bd\u03b7\u03c4\u03cc \u03c4\u03b7\u03bb\u03ad\u03c6\u03c9\u03bd\u03bf", "zu": "Imobhayili", "xh": "Imobhayili", "st": "E tsamayang", "ca": "Telèfon mòbil" }, "attribute_preferredlanguage": { "no": "Foretrukket spr\u00e5k", "nn": "F\u00f8rsteval for spr\u00e5k eller m\u00e5lform", "sv": "\u00d6nskv\u00e4rt spr\u00e5k", "es": "Idioma preferido", "fr": "Langue pr\u00e9f\u00e9r\u00e9e", "de": "Bevorzugte Sprache", "nl": "Voorkeurstaal", "lb": "Lieblingssprooch", "sl": "\u017delen jezik", "da": "Foretrukket sprog (evt. flere)", "se": "Vuostta\u0161v\u00e1lljejuvvon giella dehe giellah\u00e1pmi", "hr": "Primarni jezik", "hu": "Els\u0151dleges nyelv", "fi": "Ensisijainen kieli", "pt-br": "Linguagem preferida", "pt": "Idioma", "pl": "Preferowany j\u0119zyk (Preferred language)", "cs": "Preferovan\u00fd jazyk", "tr": "Tercih edilen dil", "it": "Lingua preferita", "lt": "Kalba", "ja": "\u8a00\u8a9e", "zh-tw": "\u559c\u597d\u8a9e\u8a00", "et": "Eelistatud keel", "he": "\u05e9\u05e4\u05d4 \u05de\u05d5\u05e2\u05d3\u05e4\u05ea", "ru": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u044f\u0437\u044b\u043a", "zh": "\u9996\u9009\u8bed\u8a00", "sr": "Preferirani jezik", "ar": "\u0627\u0644\u0644\u063a\u0629 \u0627\u0644\u0645\u0641\u0636\u0644\u0629", "id": "Pilihan Bahasa", "lv": "V\u0113lam\u0101 valoda", "ro": "Limba preferat\u0103", "eu": "Hizkuntza lehenetsia", "af": "Taal voorkeur", "el": "\u03a0\u03c1\u03bf\u03c4\u03b9\u03bc\u03ce\u03bc\u03b5\u03bd\u03b7 \u03b3\u03bb\u03ce\u03c3\u03c3\u03b1", "xh": "Ulwimi olukhethayo", "zu": "Ulimi oluncanyelwayo", "st": "Puo e kgethwang", "ca": "Idioma preferit" }, "attribute_noredupersonnin": { "no": "F\u00f8dselsnummer", "nn": "F\u00f8dselsnummer", "sv": "Officiellt personnummer eller intermimspersonnummer", "es": "N\u00famero de la Seguridad Social", "fr": "Num\u00e9ro de s\u00e9curit\u00e9 sociale", "de": "Norwegische Personenkennziffer", "nl": "Burgerservicenummer", "lb": "Sozialvers\u00ebcherungsnummer", "sl": "Mati\u010dna \u0161tevilka", "da": "CPR-nummer", "se": "Riegadannummir", "hr": "Broj\u010dani identifikator osobe", "hu": "T\u00e1rsadalombiztos\u00edt\u00e1si azonos\u00edt\u00f3 sz\u00e1m", "fi": "Henkil\u00f6tunnus", "pt-br": "N\u00famero de identifica\u00e7\u00e3o atribu\u00eddo pelas autoridades p\u00fablicas", "pt": "N\u00famero de Identifica\u00e7\u00e3o atribu\u00eddo por autoridades p\u00fablicas", "pl": "Numer to\u017csamo\u015bci wydany przez administracj\u0119 publiczn\u0105", "cs": "Identifika\u010dn\u00ed k\u00f3d p\u0159id\u011blen\u00fd ve\u0159ejnou autoritou", "tr": "Kamu yetkilileri taraf\u0131ndan belirlenmi\u015f kimlik numaras\u0131", "it": "Numero di identit\u00e0 assegnato dall'autorit\u00e0 pubblica", "lt": "Valstyb\u0117s institucij\u0173 priskirtas tapatyb\u0117s numeris", "ja": "\u516c\u958b\u8a8d\u8a3c\u5c40\u306b\u3088\u3063\u3066\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u8b58\u5225\u756a\u53f7", "zh-tw": "\u8eab\u5206\u8b49\u5b57\u865f", "he": "\u05de\u05e1\u05e4\u05e8 \u05de\u05d6\u05d4\u05d4 \u05e9\u05e0\u05d9\u05ea\u05df \u05e2\u05dc \u05d9\u05d3\u05d9 \u05d4\u05e8\u05e9\u05d5\u05d9\u05d5\u05ea \u05d4\u05e6\u05d9\u05d1\u05d5\u05e8\u05d9\u05d5\u05ea", "ru": "\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440, \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043e\u0440\u0433\u0430\u043d\u0430\u043c\u0438 \u0433\u043e\u0441\u0443\u0434\u0430\u0440\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0432\u043b\u0430\u0441\u0442\u0438", "et": "Isikukood", "zh": "\u8eab\u4efd\u8bc1\u53f7\u7801", "sr": "Jedinstveni brojni identifikator osobe", "ar": "\u0627\u0644\u0631\u0642\u0645 \u0627\u0644\u062a\u0639\u0631\u064a\u0641\u064a \u0627\u0644\u0645\u0639\u064a\u0646 \u0645\u0646 \u0642\u0628\u0644 \u0627\u0644\u0633\u0644\u0637\u0627\u062a \u0627\u0644\u0639\u0627\u0645\u0629 ", "id": "Identity number assigned by public authorities", "lv": "Publisko autorit\u0101\u0161u pie\u0161\u0137irtais identit\u0101tes numurs", "ro": "Num\u0103r de identitate atribuit de autorit\u0103\u021bi publice", "eu": "Gizarte-segurantzako zenbakia", "af": "Identiteitsnommer", "el": "\u0391\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03b1\u03c0\u03cc \u03b4\u03b7\u03bc\u03cc\u03c3\u03b9\u03b1 \u03b1\u03c1\u03c7\u03ae", "xh": "Inombolo yesazisi eyabelwe ngamagunya oluntu", "zu": "Inombolo kamazisi eyabelwe amagunya omphakathi", "st": "Nomoro ya boitsebiso e abilwe ke bolaodi ba puso", "ca": "Número de la Seguretat Social" }, "attribute_schachomeorganization": { "no": "Unik ID for organisasjon", "nn": "Unik ID for organisasjon", "sv": "Dom\u00e4nnamn f\u00f6r organisationen", "es": "Identificador \u00fanico de la organizaci\u00f3n de origen", "fr": "Identifiant unique de l'organisation de rattachement", "de": "Domain-Name der Heimorganisation", "nl": "Unieke Organisatie ID", "lb": "Eendeiteg Heemorganisatiouns ID", "sl": "ID doma\u010de organizacije", "da": "Hjemmeorganisationens entydige ID (dom\u00e6nenavn)", "hr": "Oznaka mati\u010dne ustanove", "hu": "Saj\u00e1t int\u00e9zm\u00e9ny domain neve", "fi": "Organisaation domain-nimi", "pt-br": "Nome de dom\u00ednio da organiza\u00e7\u00e3o principal", "pt": "Nome de dom\u00ednio da Organiza\u00e7\u00e3o de origem", "pl": "Nazwa organizacji macierzystej", "cs": "Jm\u00e9no organizace", "tr": "Ana kurulu\u015f alan ad\u0131", "it": "Nome del dominio della propria organizzazione", "lt": "Organizacijos domenas", "ja": "\u7d44\u7e54\u5185\u30c9\u30e1\u30a4\u30f3", "zh-tw": "\u6240\u5c6c\u7684\u7d44\u7e54\u7db2\u57df\u540d\u7a31", "et": "Koduorganisatsiooni domeen", "he": "\u05e9\u05dd \u05d4\u05de\u05ea\u05d7\u05dd \u05e9\u05dc \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u0414\u043e\u043c\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u9996\u9875\u7ec4\u7ec7\u7684\u57df\u540d", "ar": "\u0627\u0633\u0645 \u0627\u0644\u0646\u0637\u0627\u0642 \u0627\u0644\u0645\u062e\u0635\u0635 \u0644\u0644\u0645\u0646\u0638\u0645\u0629\u0627\u0644\u0627\u0645\\\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0627\u0645 ", "id": "Home organization domain name", "lv": "Organiz\u0101cijas domeins", "sr": "Domen mati\u010dne institucije", "ro": "Njumele de domeniu pentru institu\u021bia de origine", "eu": "Jatorrizko erakundearen domeinu izena", "af": "Tuis Organisasie domein naam", "el": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03c0\u03b5\u03c1\u03b9\u03bf\u03c7\u03ae\u03c2 (domain) \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "zu": "Igama lesizinda senhlangano yasekhaya", "xh": "Igama ledomeyini yombutho wekhaya", "st": "Lebitso la domeine ya khampani", "ca": "Identificador únic de l’organització principal" }, "attribute_organisationname": { "no": "Navn p\u00e5 organisasjon", "nn": "Namn p\u00e5 organisasjon", "sv": "Namn p\u00e5 organisationen", "es": "Nombre de la organizaci\u00f3n", "fr": "R\u00f4les pour ce service", "de": "Name der Organisation", "nl": "Organisatienaam", "lb": "Organisatiounsnumm", "sl": "Ime organizacije", "da": "Hjemmeorganisationens kaldenavn", "se": "Organisa\u0161uvdna", "hr": "Naziv ustanove", "hu": "Szervezet neve", "fi": "Organisaation nimi", "pt-br": "Nome da Organiza\u00e7\u00e3o", "pt": "Nome da Organiza\u00e7\u00e3o", "pl": "Nazwa organizacji (Organization name)", "cs": "Jm\u00e9no organizace", "eu": "Erakundearen izena", "tr": "Kurulu\u015f ad\u0131", "it": "Nome dell'organizzazione", "lt": "Organizacijos pavadinimas", "ja": "\u7d44\u7e54\u540d", "zh-tw": "\u7d44\u7e54\u540d\u7a31", "et": "Organisatsiooni nimi", "he": "\u05e9\u05dd \u05d0\u05d9\u05e8\u05d2\u05d5\u05df", "ru": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u540d\u79f0", "sr": "Naziv mati\u010dne institucije", "ar": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0646\u0638\u0645\u0629\u0627\u0644\u0627\u0645\\\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0627\u0645", "id": "Organization name", "lv": "Organiz\u0101cijas nosaukums", "ro": "Denumirea institu\u021biei", "af": "Organisasie naam", "el": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "xh": "Igama lombutho", "zu": "Igama lenhlangano", "st": "Lebitso la khampani", "ca": "Nom de l'organització" }, "attribute_edupersonentitlement": { "no": "Rettighet", "nn": "URI som viser til eit sett av rettar til spesifikke ressursar", "sv": "Roll(er) i aktuell tj\u00e4nst", "es": "Derecho relativo al servicio", "fr": "Appartenance \u00e0 un groupe", "de": "Berechtigung", "nl": "Recht", "lb": "Berechtegung", "sl": "Upravi\u010denost do storitve", "da": "Specifik rolle i forhold til tjenesten", "se": "URI mii \u010dilge dihto vuoigatvuo\u0111a dihto ressurssaide", "hr": "Pripadnost grupi", "hu": "Ezekre a szolg\u00e1ltat\u00e1sokra jogosult", "fi": "Organisaationoikeudet", "pt-br": "Titularidade sobre o servi\u00e7o", "pt": "Direitos oferecidos pela organiza\u00e7\u00e3o de origem", "pl": "Uprawnienie dotycz\u0105ce serwisu", "cs": "Pr\u00e1vo ke slu\u017eb\u011b", "tr": "Servise g\u00f6re yetki", "it": "Qualifica rispetto al servizio", "lt": "Teis\u0117s susij\u0119 su paslauga", "ja": "\u30b5\u30fc\u30d3\u30b9\u306b\u95a2\u3059\u308b\u8cc7\u683c", "zh-tw": "\u95dc\u65bc\u670d\u52d9\u7684\u6b0a\u5229", "he": "\u05d0\u05d9\u05e9\u05d5\u05e8 \u05d4\u05e7\u05e9\u05d5\u05e8 \u05dc\u05e9\u05d9\u05e8\u05d5\u05ea", "ru": "\u041f\u0440\u0430\u0432\u043e \u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u0443\u0433", "et": "Volitused selle teenuse suhtes", "zh": "\u5173\u4e8e\u670d\u52a1\u7684\u6743\u5229", "sr": "Prava i privilegije korisnika na sistemu", "ar": "\u0627\u0633\u062a\u062d\u0642\u0627\u0642\u0627\u062a \u0627\u0644\u062e\u062f\u0645\u0629", "lv": "Pilnvaras attiec\u012bb\u0101 uz servisu", "id": "Hak mengenai layanan ini", "ro": "Drepturi relativ la acest serviciu", "eu": "Zerbitzuari dagokion eskubidea", "af": "Reg mbt. die diens", "el": "\u0394\u03b9\u03ba\u03b1\u03b9\u03ce\u03bc\u03b1\u03c4\u03b1 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1", "zu": "Ilungelo eliphathelene nesevisi", "xh": "Ilungelo ngokuphathelele inkonzo", "st": "Thuo bakeng sa tshebeletso", "ca": "Drets relatiu al servei" }, "attribute_edupersonscopedaffiliation": { "no": "Gruppetilh\u00f8righet", "nn": "Rolle hos organisasjonen ", "sv": "Grupptillh\u00f6righet", "es": "Grupo", "fr": "R\u00f4les pour ce service", "de": "Organisationszugeh\u00f6rigkeit bei der Heimorganisation", "nl": "Groep", "lb": "Gruppen Zougeh\u00e9iregket", "sl": "Vloga v organizaciji", "da": "Gruppemedlemskab", "se": "Rolla diehto organisa\u0161uvnnas, dehe dihto domenas.", "hr": "Povezanost s mati\u010dnom ustanovom", "hu": "Saj\u00e1t int\u00e9zm\u00e9nyhez val\u00f3 viszony", "fi": "Henkil\u00f6n rooli kotiorganisaatiossa", "pt-br": "Filia\u00e7\u00e3o na organiza\u00e7\u00e3o principal", "pt": "Afilia\u00e7\u00e3o com a organiza\u00e7\u00e3o de origem (com contexto)", "pl": "Przynale\u017cno\u015b\u0107 w macierzystej organizacji", "cs": "Vztah k domovks\u00e9 organizaci", "tr": "Ba\u011fl\u0131 olunan kurulu\u015fla ba\u011flant\u0131", "it": "Affiliazione nella propria organizzazione", "lt": "S\u0105saja su organizacija", "ja": "\u7d44\u7e54\u5185\u8077\u7a2e", "zh-tw": "\u6240\u5c6c\u55ae\u4f4d\u7d44\u7e54\u4e4b\u806f\u7d61\u65b9\u5f0f", "he": "\u05e9\u05d9\u05d9\u05db\u05d5\u05ea \u05d1\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u0427\u043b\u0435\u043d\u0441\u0442\u0432\u043e \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "et": "Rollid koduorganisatsioonis", "zh": "\u5bb6\u5ead\u8054\u7edc\u5730\u5740", "sr": "Povezanost sa institucijom sa domenom", "ar": "\u0627\u0644\u0648\u0636\u0639 \u0623\u0648 \u0627\u0644\u0648\u0638\u064a\u0641\u0629 \u0628\u0627\u0644\u0645\u0646\u0638\u0645\u0629\u0627\u0644\u0627\u0645\\\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0627\u0645", "lv": "Amats organiz\u0101cij\u0101", "id": "Afiliasi di organisasi asal", "ro": "Afiliere \u00een cadrul institu\u021biei de origine", "eu": "Afiliazioa jatorrizko erakundean", "af": "Affiliasie by Tuis organisasie", "el": "\u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 \u03b1\u03bd\u03ac \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03ae \u03c0\u03b5\u03c1\u03b9\u03bf\u03c7\u03ae (administrative domain)", "zu": "Indima enhlanganweni yasekhaya", "xh": "Indima kumbutho wasekhaya", "st": "Kamano khampaning ya habo", "ca": "Afiliació a l’organització principal" }, "attribute_edupersontargetedid": { "no": "Persistent anonym ID", "nn": "Persistent anonym ID", "sv": "Varaktig anonym identitet i aktuell tj\u00e4nst", "es": "ID an\u00f3nimo persistente", "fr": "Identifiant persistant anonyme", "de": "Persistente pseudonyme ID", "nl": "Persistente anonieme ID", "lb": "Persistent anonym ID", "sl": "Trajni anonimni ID", "da": "Pseudonymt bruger-ID", "hr": "Trajni anonimni identifikator", "hu": "\u00c1lland\u00f3 anonim azonos\u00edt\u00f3", "fi": "Pseudonyymi-identiteetti", "pt-br": "Apelido persistente ID", "pt": "Identifica\u00e7\u00e3o persistente tipo pseud\u00f3nimo", "cs": "Perzistent\u00ed pseudoanonymn\u00ed ID", "tr": "Kal\u0131c\u0131 takma ad\u0131 ID", "it": "Pseudonimo identificativo persistente", "lt": "Nuolatinio pseudonimo ID", "ja": "\u6c38\u7d9a\u7684\u533f\u540dID", "zh-tw": "\u6c38\u4e45\u6027\u533f\u540d ID", "he": "\u05de\u05d6\u05d4\u05d4 \u05de\u05e9\u05ea\u05de\u05e9 \u05d2\u05dc\u05d5\u05d1\u05dc\u05d9", "ru": "ID \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c\u0430", "et": "P\u00fcsiv pseudon\u00fc\u00fcmne ID", "zh": "\u6301\u7eed\u7684\u533f\u540dID", "sr": "Trajni anonimni identifikator", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u0639\u0627\u0631 ", "pl": "Trwa\u0142y anonimowy identyfikator", "lv": "Past\u0101v\u012bgs pseidon\u012bma ID", "id": "Persistent pseudonymous ID", "ro": "ID pseudonim persistent", "eu": "Goitizen ID etengabea", "af": "Aanhoudende anonieme ID", "el": "\u0391\u03b4\u03b9\u03b1\u03c6\u03b1\u03bd\u03ad\u03c2 \u03b1\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03bc\u03b1\u03ba\u03c1\u03ac\u03c2 \u03b4\u03b9\u03ac\u03c1\u03ba\u03b5\u03b9\u03b1\u03c2", "zu": "Isibizo esingashintshi esiqondene nesevisi", "xh": "Igama elingelolakhe elingatshintshiyo elingqale kwinkonzo", "st": "ID e phehellang ya lebitso la boiqapelo", "ca": "Identificació anònima persistent" }, "attribute_pairwise_id": { "de": "Service-spezifische pseudonyme ID bei der Heimorganisation", "ca": "Identificació aònima específica del servei a l'organització principal" }, "attribute_edupersonprincipalname": { "no": "Personlig ID hos organisasjonen", "nn": "Brukarnamn hos din organisasjon", "sv": "Anv\u00e4ndaridentitet vid din organisationen", "es": "Identificador \u00fanico de la persona en su organizaci\u00f3n de origen", "fr": "Nom de l'utilisateur dans l'organisation de rattachement", "de": "Pers\u00f6nliche ID bei der Heimorganisation", "nl": "Persoons ID bij organisatie", "lb": "Haaptnumm bei der Heemorganisatioun", "sl": "ID uporabnika na doma\u010di organizaciji", "da": "Bruger-ID hos hjemmeorganisationen", "se": "Feide-namma", "hr": "Korisni\u010dka oznaka", "hu": "\u00c1lland\u00f3 azonos\u00edt\u00f3 a saj\u00e1t int\u00e9zm\u00e9nyben", "fi": "Henkil\u00f6n universaali nimi", "pt-br": "Diretor da organiza\u00e7\u00e3o principal", "pt": "Nome de utilizador na organiza\u00e7\u00e3o de origem", "cs": "Jm\u00e9no nad\u0159\u00edzen\u00e9ho", "tr": "Ki\u015finin ba\u011fl\u0131 oldu\u011fu kurulu\u015ftaki as\u0131l ad\u0131", "it": "Nome identificativo (principal name) nella propria organizzazione", "lt": "Asmens pagrindinis vardas organizacijoje", "ja": "\u6c38\u7d9a\u7684\u5229\u7528\u8005\u540d", "zh-tw": "\u500b\u4eba\u65bc\u6240\u5c6c\u7d44\u7e54\u7684\u6c38\u4e45\u540d\u5b57", "he": "\u05d4\u05e9\u05dd \u05d4\u05e2\u05d9\u05e7\u05e8\u05d9 \u05d1\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u0418\u043c\u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044f \u0432 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "et": "Isiku p\u00f5hinimi koduasutuses", "zh": "\u4eba\u7684\u4e3b\u8981\u5728\u5bb6\u4e2d\u7ec4\u7ec7\u7684\u540d\u79f0", "sr": "Jedinstveni identifikator osobe", "ar": "\u0623\u0644\u0627\u0633\u0645 \u0628\u0627\u0644\u0645\u0646\u0638\u0645\u0629 \u0627\u0644\u0627\u0645\\\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0627\u0645 ", "pl": "G\u0142\u00f3wna nazwa u\u017cytkownika w instytucji macierzystej", "lv": "Priek\u0161nieka v\u0101rds", "id": "Nama kepala pada organisasi asal", "ro": "Numele de identificare a persoanei la institu\u021bia de origine (de forma nume_utilizator@domeniu.ro)", "eu": "Jatorrizko erakundean pertsonak duen izen nagusia", "af": "Persoonlike ID by tuis organisasie", "el": "\u0391\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03c3\u03c4\u03bf\u03bd \u03bf\u03b9\u03ba\u03b5\u03af\u03bf \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03cc", "xh": "Igama elingundoqo lomntu kwinkampani yekhaya", "zu": "Igama eliyinhloko lomuntu enhlanganweni yasekhaya", "st": "Lebitso la sehlooho la motho khampaning ya habo", "ca": "Identificador \u00fanic de la persona a l'organitzaci\u00f3 principal" }, "attribute_edupersonuniqueid": { "zh-tw": "\u500b\u4eba\u7121\u6cd5\u91cd\u65b0\u8a2d\u7f6e\uff0c\u65bc\u6240\u5c6c\u7d44\u7e54\u7684\u6c38\u4e45\u533f\u540d ID", "el": "\u039c\u03cc\u03bd\u03b9\u03bc\u03bf, \u03b1\u03b4\u03b9\u03b1\u03c6\u03b1\u03bd\u03ad\u03c2 \u03b1\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03cc \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03c3\u03c4\u03bf\u03bd \u03bf\u03b9\u03ba\u03b5\u03af\u03bf \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03cc", "zu": "I-ID yesibizo ephikelelayo, engakwazi ukwabelwa kabusha yomuntu yenhlangano yasekhaya", "xh": "I-ID yomntu enganakuphinda yabelwe, ebhalwe ngegama lobuxoki eqhubekayo kwinkampani yekhaya", "st": "ID ya boiqapelo le phehellang, e sa ajweng botjha ya motho ya khampani ya lapeng", "ca": "Identificació anònima persistent i no reasignable de la persona a l'organització principal" }, "attribute_subject_id": { "de": "Pseudonyme ID bei der Heimorganisation", "ca": "Identificació pseudònima en l'organització principal" }, "attribute_edupersonorcid": { "zh-tw": "ORCID \u7814\u7a76\u8005\u8b58\u5225\u78bc", "el": "\u0391\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03b9\u03c3\u03c4\u03b9\u03ba\u03ac \u03b5\u03c1\u03b5\u03c5\u03bd\u03b7\u03c4\u03ae ORCID", "af": "ORCID identifiseerder", "zu": "Isihlonzi se-ORCID", "xh": "Isazisi se-ORCID", "st": "Ditsebahatsi tsa mofuputsi tsa ORCID", "ca": "Identificador d'investigador ORCID" }, "attribute_o": { "no": "Navn p\u00e5 organisasjon", "nn": "Namn p\u00e5 organisasjon", "sv": "Namn p\u00e5 organisationen", "es": "Nombre de la organizaci\u00f3n", "fr": "R\u00f4les pour ce service", "de": "Name der Organisation", "nl": "Organisatie naam", "lb": "Organisatiounsnumm", "sl": "Ime organizacije", "da": "Hjemmeorganisationens kaldenavn", "hr": "Naziv mati\u010dne ustanove", "hu": "Szervezet neve", "fi": "Organisaation nimi", "pt-br": "Nome da Organiza\u00e7\u00e3o (O)", "pt": "Nome da organiza\u00e7\u00e3o", "pl": "Nazwa organizacji (Organization name)", "cs": "Jm\u00e9no organizace", "eu": "Erakundearen izena", "tr": "Organizasyon ad\u0131", "it": "Nome dell'organizzazione", "lt": "Organizacijos pavadinimas", "ja": "\u6240\u5c5e\u7d44\u7e54", "zh-tw": "\u7d44\u7e54\u540d\u7a31", "et": "Organisatsiooni nimi", "he": "\u05e9\u05dd \u05d0\u05d9\u05e8\u05d2\u05d5\u05df", "ru": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u540d\u79f0", "sr": "Naziv mati\u010dne institucije", "ar": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0646\u0638\u0645\u0629", "lv": "Organiz\u0101cijas nosaukums", "id": "Nama organisasi", "ro": "Denumirea institu\u021biei", "af": "Organisasie naam", "el": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "zu": "Igama lenhlangano", "xh": "Igama lombutho", "st": "Lebitso la khampani", "ca": "Nom de l'organització" }, "attribute_dc": { "no": "Navneledd (DC)", "nn": "Namneledd (DC)", "sv": "Dom\u00e4nnamnskomponent", "es": "Componente de dominio (DC)", "de": "Domain-Komponente", "nl": "Domeincomponent", "lb": "Domain Komponent", "sl": "Domenska komponenta (DC)", "da": "Dom\u00e6nekomponent", "hr": "Domenska komponenta (DC)", "hu": "Domain \u00f6sszetev\u0151 (DC)", "fi": "Domain-osio", "pt-br": "Componente do Dom\u00ednio (DC)", "pt": "Componente de dom\u00ednio", "pl": "Sk\u0142adnik nazwy domenowej (DC)", "cs": "Dom\u00e9na (DC)", "tr": "Alan bile\u015feni", "fr": "Fragment de domaine (DC)", "it": "Componente di dominio (DC)", "lt": "Domeno komponentas", "ja": "\u30c9\u30e1\u30a4\u30f3\u540d", "zh-tw": "\u7db2\u57df Domain component (DC)", "et": "Domeeni komponent (DC)", "he": "\u05de\u05e8\u05db\u05d9\u05d1 \u05de\u05ea\u05d7\u05dd (DC)", "ru": "\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043e\u043c\u0435\u043d\u0430 (DC)", "zh": "Opened the web browser with tabs saved from the previous session.\u57df\u7ec4\u4ef6\uff08DC\uff09", "sr": "Domenska komponenta (DC)", "ar": "\u0645\u0643\u0648\u0646\u0627\u062a \u0627\u0644\u0646\u0637\u0627\u0642", "lv": "Dom\u0113ns (DC)", "id": "Domain component(DC)", "ro": "Componenta de domeniu (DC)", "eu": "Domeinuaren osagaia (DC)", "af": "Domein komponent (DC)", "el": "\u03a3\u03c5\u03c3\u03c4\u03b1\u03c4\u03b9\u03ba\u03cc \u03a4\u03bf\u03bc\u03ad\u03b1 (DC)", "zu": "Ingxenye yesizinda (I-DC)", "xh": "Ikhomponenti yedomeyin (DC)", "st": "Karolwana ya domeine (DC)", "ca": "Component de domini (DC)" }, "attribute_displayname": { "no": "Navn som normalt vises", "nn": "Namn slik det normalt blir vist fram", "sv": "Visningsnamn", "es": "Nombre para mostrar", "de": "Anzeigename", "nl": "Weergavenaam", "lb": "Ugewisenen Numm", "sl": "Prikazno ime", "da": "Visningsnavn", "hr": "Mre\u017eno ime", "hu": "Megjelen\u00edthet\u0151 n\u00e9v", "fi": "N\u00e4ytt\u00f6nimi", "pt-br": "Nome a ser mostrado", "pt": "Nome de apresenta\u00e7\u00e3o", "pl": "Nazwa wy\u015bwietlana (Display name)", "cs": "Jm\u00e9no k zobrazen\u00ed", "tr": "G\u00f6r\u00fcnt\u00fclenen isim", "fr": "Nom pour affichage", "it": "Nome da visualizzare", "lt": "Rodomas vardas", "ja": "\u8868\u793a\u540d", "zh-tw": "\u986f\u793a\u540d\u7a31", "et": "Kuvatav nimi", "he": "\u05d4\u05e8\u05d0\u05d4 \u05e9\u05dd", "ru": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f", "zh": "\u663e\u793a\u540d\u79f0", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 ", "lv": "Par\u0101d\u0101mais v\u0101rds", "id": "Nama yang ditampilkan", "sr": "Ime za prikaz", "ro": "Nume afi\u0219at", "eu": "Bistaratzeko izena", "af": "Vertoon naam", "el": "\u0395\u03bc\u03c6\u03b1\u03bd\u03b9\u03b6\u03cc\u03bc\u03b5\u03bd\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1", "zu": "Igama lesibonisi", "xh": "Igama lomboniso", "st": "Lebitso le bontshwang", "ca": "Nom a mostrar" }, "attribute_facsimiletelephonenumber": { "no": "Faksnummer", "nn": "Faksnummer", "sv": "Faxnummer", "es": "N\u00famero de fax", "de": "Faxnummer", "nl": "Faxnummer", "lb": "Fax Nummer", "sl": "Fax", "da": "Faxnummer", "hr": "Broj telefaksa", "hu": "Fax", "fi": "Faksinumero", "pt-br": "N\u00famero do Fax", "pt": "N\u00famero de Fax", "pl": "Numer Faksu (Fax number)", "cs": "Fax", "eu": "Fax-zenbakia", "tr": "Faks numaras\u0131", "fr": "Num\u00e9ro de fax", "it": "Numero di fax", "lt": "Fakso numeris", "ja": "Fax\u756a\u53f7", "zh-tw": "\u50b3\u771f\u865f\u78bc", "et": "Faksinumber", "he": "\u05de\u05e1' \u05e4\u05e7\u05e1", "ru": "\u041d\u043e\u043c\u0435\u0440 \u0444\u0430\u043a\u0441\u0430", "zh": "\u4f20\u771f\u53f7\u7801", "sr": "Fax broj", "ar": "\u0631\u0642\u0645 \u0627\u0644\u0641\u0627\u0643\u0633", "lv": "Fakss", "id": "No Fax", "ro": "Num\u0103r de fax", "af": "Faksnommer", "el": "Fax", "zu": "Inombolo yefeksi", "xh": "Inombolo yefeksi", "st": "Nomoro ya fekse", "ca": "Número de fax" }, "attribute_homephone": { "no": "Hjemmetelefon", "nn": "Heimetelefon", "sv": "Hemtelefon", "es": "Tel\u00e9fono de su domicilio", "de": "Private Telefonnummer", "nl": "Thuistelefoon", "lb": "Haustelefon", "sl": "Doma\u010da telefonska \u0161tevilka", "da": "Telefonnummer (privat)", "hr": "Ku\u0107ni telefonski broj", "hu": "Otthoni telefon", "fi": "Kotipuhelin", "pt-br": "Telefone fixo", "pt": "Telefone de resid\u00eancia", "pl": "Telefon domowy (Home telephone)", "cs": "Telefon dom\u016f", "eu": "Etxeko telefonoa", "tr": "Ev telefonu", "fr": "T\u00e9l\u00e9phone personnel", "it": "Telefono", "lt": "Nam\u0173 telefo nr.", "ja": "\u96fb\u8a71\u756a\u53f7", "zh-tw": "\u4f4f\u5bb6\u96fb\u8a71", "et": "Kodune telefon", "he": "\u05d8\u05dc\u05e4\u05d5\u05df \u05d1\u05d1\u05d9\u05ea", "ru": "\u0414\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u0442\u0435\u043b\u0435\u0444\u043e\u043d", "zh": "\u5bb6\u5ead\u7535\u8bdd", "sr": "Ku\u0107ni telefonski broj", "ar": "\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062a\u0641 \u0627\u0644\u0645\u0646\u0632\u0644\u064a", "lv": "Telefons", "id": "Telepon rumah", "ro": "Telefon acas\u0103", "af": "Tuistelefoon", "el": "\u03a4\u03b7\u03bb\u03ad\u03c6\u03c9\u03bd\u03bf \u03bf\u03b9\u03ba\u03af\u03b1\u03c2", "xh": "Umnxeba wasekhaya", "zu": "Ucingo lwasekhaya", "st": "Founu ya lapeng", "ca": "Telèfon fix particular" }, "attribute_homepostaladdress": { "no": "Postadresse hjemme", "nn": "Postadresse heime", "sv": "Hemadress", "es": "Direcci\u00f3n de su domicilio", "de": "Privatanschrift", "nl": "Werkadres", "lb": "Adress", "sl": "Doma\u010di naslov", "da": "Privatadresse", "hr": "Ku\u0107na po\u0161tanska adresa", "hu": "Otthoni levelez\u00e9si c\u00edm", "fi": "Kodin postiosoite", "pt-br": "Endere\u00e7o residencial", "pt": "Morada de redid\u00eancia", "pl": "Domowy address pocztowy", "cs": "Adresa dom\u016f", "tr": "Ev posta adresi", "fr": "Adresse postale personnelle", "it": "Indirizzo postale", "lt": "Nam\u0173 adresas", "ja": "\u4f4f\u6240", "zh-tw": "\u4f4f\u5bb6\u5730\u5740", "et": "Kodune postiaadress", "he": "\u05db\u05ea\u05d5\u05d1\u05ea \u05d3\u05d5\u05d0\u05e8 \u05d1\u05d1\u05d9\u05ea", "ru": "\u0414\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441", "zh": "\u5bb6\u5ead\u90ae\u653f\u5730\u5740", "sr": "Ku\u0107na po\u0161tanska adresa", "ar": "\u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f\u064a", "lv": "Pasta adrese", "id": "Alamat pos rumah", "ro": "Adresa po\u0219tal\u0103 de acas\u0103", "eu": "Etxeko helbidea", "af": "Tuis posadres", "el": "\u03a4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b9\u03ba\u03ae \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03bf\u03b9\u03ba\u03af\u03b1\u03c2", "zu": "Ikheli leposi lasekhaya", "xh": "Idilesi yeposi yasekhaya", "st": "Aterese ya lapeng ya poso", "ca": "Adreça particular" }, "attribute_jpegphoto": { "no": "JPEG-foto", "nn": "Foto p\u00e5 JPEG-format", "sv": "JPEG-bild", "es": "Fotograf\u00eda en JPEG", "de": "JPEG Foto", "nl": "JPEG-foto", "lb": "Photo am JPEG Format", "sl": "JPEG Slika", "da": "JPEG-foto", "hr": "Slika u JPEG formatu", "hu": "Fot\u00f3 JPEG form\u00e1tumban", "fi": "JPEG kuva", "pt-br": "Foto JPEG", "pt": "Foto JPEG", "pl": "Fotografia JPEG", "cs": "Foto JPEG", "eu": "JPEG argazkia", "tr": "JPEG foto\u011fraf", "fr": "Photo JPEG", "it": "Foto JPEG", "lt": "JPEG nuotrauka", "ja": "JPEG\u5199\u771f", "zh-tw": "JPEG \u5716\u7247", "et": "JPEG-foto", "he": "\u05ea\u05de\u05d5\u05e0\u05d4", "ru": "\u0424\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JPEG", "zh": "JPEG\u56fe\u7247", "sr": "Slika osobe", "ar": "\u0635\u0648\u0631\u0629 (JPEG)", "lv": "JPEG fotogr\u0101fija", "id": "Foto JPEG", "ro": "Fotografie JPEG", "af": "JPEG Foto", "el": "\u03a6\u03c9\u03c4\u03bf\u03b3\u03c1\u03b1\u03c6\u03af\u03b1 \u03c3\u03b5 \u03bc\u03bf\u03c1\u03c6\u03ae JPEG", "xh": "Ifoto ye-JPEG", "zu": "Isithombe se-JPEG", "st": "Foto ya JPEG", "ca": "Fotografia en JPEG" }, "attribute_l": { "no": "Sted", "nn": "Stad", "sv": "Plats", "es": "Localidad", "de": "Ort", "nl": "Plaats", "lb": "Uertschaft", "sl": "Kraj", "da": "Sted", "hr": "Mjesto (lokalitet)", "hu": "Telep\u00fcl\u00e9s", "fi": "Paikkakunta", "pt-br": "Localidade", "pt": "Localidade", "pl": "Locality", "cs": "Lokalita", "tr": "B\u00f6lge", "fr": "Lieu", "it": "Localit\u00e0", "lt": "Vietov\u0117", "ja": "\u5730\u57df", "zh-tw": "\u5340\u57df", "he": "\u05d0\u05d9\u05d6\u05d5\u05e8", "ru": "\u0420\u0430\u0439\u043e\u043d", "et": "Asukoht", "zh": "\u4f4d\u7f6e", "sr": "Lokacija(Mesto)", "ar": "\u0627\u0644\u0645\u062d\u0644\u064a\u0629", "lv": "Atra\u0161an\u0101s vieta", "id": "Lokalitas", "ro": "Localitate", "eu": "Herria", "af": "Ligging", "el": "\u03a4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1", "zu": "Indawo", "xh": "Indawo", "st": "Tulo", "ca": "Localitat" }, "attribute_labeleduri": { "no": "URI med valgfri tilleggskommentar", "nn": "URI med valfri tilleggskommentar", "sv": "Hemsida", "es": "URI etiquetado", "de": "URI mit zus\u00e4tzlicher Kennzeichnung", "nl": "URI", "lb": "Beschr\u00ebfteten URI", "sl": "Ozna\u010den URI", "da": "Labeled URI", "hr": "URI adresa", "hu": "Honlap c\u00edm", "fi": "Kotisivu", "pt-br": "URI rotulado", "pt": "P\u00e1gina web", "pl": "Labeled URI", "cs": "URI", "tr": "Etiketlenen URI", "fr": "URI", "it": "Etichetta URI", "lt": "\u017dym\u0117tasis URI", "ja": "URI", "zh-tw": "\u6a19\u7c64\u7db2\u5740", "he": "\u05e1\u05d9\u05d5\u05d5\u05d2 URI", "ru": "\u041c\u0430\u0440\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 URI (LabeledURI)", "et": "Sildistatud URI", "zh": "\u6807\u7b7eURI", "sr": "URI adresa", "ar": "URI \u0623\u0633\u0645 ", "lv": "URI nosaukums", "id": "Berlabel URL", "ro": "URI etichetat", "eu": "URI etiketatua", "af": "URI", "el": "\u0395\u03c0\u03b9\u03c3\u03b7\u03bc\u03b1\u03c3\u03bc\u03ad\u03bd\u03b1 URI", "xh": "I-URI eneleyibheli", "zu": "I-URI Enelebula", "st": "Ya Leibole ya URI", "ca": "URI etiquetat" }, "attribute_ou": { "no": "Organisasjonsenhet", "nn": "Organisasjonseining", "sv": "Organisationsenhet", "es": "Unidad organizativa", "de": "Organisationseinheit", "nl": "Afdeling", "lb": "Organisatiounseenheet", "sl": "Oddelek", "da": "Organisatorisk enhed", "hr": "Organizacijska jedinica", "hu": "Szervezeti egys\u00e9g", "fi": "Organisaation yksikk\u00f6", "pt-br": "Unidade Organizacional (OU)", "pt": "Unidade organizacional", "pl": "Jednostka organizacyjna (Organizational unit)", "cs": "Organiza\u010dn\u00ed jednotka", "tr": "Organizasyonel birim", "fr": "Section", "it": "Unit\u00e0 organizzativa", "lt": "Organizacijos skyrius", "ja": "\u7d44\u7e54\u5358\u4f4d", "zh-tw": "\u7d44\u7e54\u55ae\u4f4d", "et": "All\u00fcksus", "he": "\u05d9\u05d7\u05d9\u05d3\u05d4 \u05d1\u05d0\u05e8\u05d2\u05d5\u05df", "ru": "\u041f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u5355\u4f4d", "sr": "Organizaciona jedinica", "ar": "\u0627\u0644\u0648\u062d\u062f\u0629", "lv": "Organiz\u0101cijas vien\u012bba", "id": "Organizational unit", "ro": "Unitate organiza\u021bional\u0103", "eu": "Antolamendu-unitatea", "af": "Organisasie eenheid", "el": "\u039f\u03c1\u03b3\u03b1\u03bd\u03c9\u03c4\u03b9\u03ba\u03ae \u03bc\u03bf\u03bd\u03ac\u03b4\u03b1", "zu": "Iyunithi yenhlangano", "xh": "Iyunithi yombutho", "st": "Yuniti ya khampani", "ca": "Unitat organitzativa" }, "attribute_postaladdress": { "no": "Postadresse", "nn": "Postadresse", "sv": "Postadress", "es": "Direcci\u00f3n postal", "de": "Anschrift", "nl": "Adres", "lb": "Adress", "sl": "Po\u0161tni naslov", "da": "Adresse", "hr": "Po\u0161tanska adresa", "hu": "Levelez\u00e9si c\u00edm", "fi": "Postiosoite", "pt-br": "Endere\u00e7o", "pt": "Morada", "pl": "Adres pocztowy (Postal address)", "cs": "Po\u0161tovn\u00ed adresa", "eu": "Posta-helbidea", "tr": "Posta adresi", "fr": "Adresse postale", "it": "Indirizzo postale", "lt": "Adresas", "ja": "\u4f4f\u6240", "zh-tw": "\u90f5\u5bc4\u5730\u5740", "et": "Postiaadress", "he": "\u05db\u05ea\u05d5\u05d1\u05ea \u05d3\u05d5\u05d0\u05e8", "ru": "\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441", "zh": "\u90ae\u653f\u5730\u5740", "sr": "Po\u0161tanska adresa", "ar": "\u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f\u064a \u0644\u0644\u0645\u0646\u0638\u0645\u0629", "lv": "Pasta adrese", "id": "Alamat pos", "ro": "Adresa po\u0219tal\u0103", "af": "Posadres", "el": "\u03a4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b9\u03ba\u03ae \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7", "xh": "Idilesi yeposi", "zu": "Ikheli leposi", "st": "Aterese ya poso", "ca": "Adreça postal" }, "attribute_postalcode": { "no": "Postnummer", "nn": "Postnummer", "sv": "Postkod", "es": "C\u00f3digo postal", "de": "Postleitzahl", "nl": "Postcode", "lb": "Postleitzuel", "sl": "Po\u0161tna \u0161tevilka", "da": "Postnummer", "hr": "Broj po\u0161te", "hu": "Ir\u00e1ny\u00edt\u00f3sz\u00e1m", "fi": "Postinumero", "pt-br": "CEP", "pt": "C\u00f3digo Postal", "pl": "Kod pocztowy", "cs": "Po\u0161tovn\u00ed k\u00f3d PS\u010c", "eu": "Posta-kodea", "tr": "Posta kodu", "fr": "Code postal", "it": "CAP", "lt": "Pa\u0161to kodas", "ja": "\u90f5\u4fbf\u756a\u53f7", "zh-tw": "\u90f5\u905e\u5340\u865f", "et": "Postiindeks", "he": "\u05de\u05d9\u05e7\u05d5\u05d3", "ru": "\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441", "zh": "\u90ae\u653f\u7f16\u7801", "sr": "Po\u0161tanski broj", "ar": "\u0627\u0644\u0631\u0645\u0632 \u0627\u0644\u0628\u0631\u064a\u062f\u064a", "lv": "Pasta kods", "id": "Kode pos", "ro": "Cod po\u0219tal", "af": "Poskode", "el": "\u03a4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b9\u03ba\u03cc\u03c2 \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2", "zu": "Ikhodi yeposi", "xh": "Ikhowudi yeposi", "st": "Khoutu ya poso", "ca": "Codi Postal" }, "attribute_postofficebox": { "no": "Postboks", "nn": "Postboks", "sv": "Box", "es": "C\u00f3digo postal", "de": "Postfach", "nl": "Postbus", "lb": "Postschl\u00e9issfach", "sl": "Po\u0161tni predal", "da": "Postboks", "hr": "Broj po\u0161tanskog pretinca", "hu": "Postafi\u00f3k", "fi": "Postilokero", "pt-br": "Caixa Postal", "pt": "Apartado", "pl": "Skrzynka pocztowa (Post office box)", "cs": "Postbox", "eu": "Posta-bulegoko ontzia", "tr": "Posta kutusu", "fr": "Boite postale", "it": "Casella postale", "lt": "Pa\u0161to d\u0117\u017eut\u0117s nr.", "ja": "\u30aa\u30d5\u30a3\u30b9\u30dc\u30c3\u30af\u30b9\u30dd\u30b9\u30c8", "zh-tw": "\u90f5\u653f\u4fe1\u7bb1", "et": "Postkast", "he": "\u05ea\u05d0 \u05d3\u05d5\u05d0\u05e8", "ru": "\u0410\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u044f\u0449\u0438\u043a", "zh": "\u90ae\u653f\u4fe1\u7bb1", "sr": "Broj po\u0161tanskog sandu\u010deta", "ar": "\u0627\u0644\u0635\u0646\u062f\u0648\u0642 \u0627\u0644\u0628\u0631\u064a\u062f\u064a", "lv": "Pasta kaste", "id": "PO Box", "ro": "Cutie po\u0219tal\u0103", "af": "Posbus", "el": "\u03a4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b9\u03ba\u03ae \u03b8\u03c5\u03c1\u03af\u03b4\u03b1", "zu": "Ibhokisi lehhovisi leposi", "xh": "Ibhokisi yaseposini", "st": "Lebokose la poso", "ca": "Apartat de correus" }, "attribute_street": { "no": "Gate", "nn": "Gateadresse", "sv": "Gata", "es": "Calle", "de": "Stra\u00dfe", "nl": "Straat", "lb": "Strooss", "sl": "Ulica", "da": "Gade", "hr": "Ulica", "hu": "Utca", "fi": "Katu", "pt-br": "Rua", "pt": "Rua", "pl": "Ulica (Street)", "cs": "Ulice", "eu": "Kalea", "tr": "Sokak", "fr": "Rue", "it": "Via", "lt": "Gatv\u0117", "ja": "\u756a\u5730", "zh-tw": "\u8857", "et": "T\u00e4nav", "he": "\u05e8\u05d7\u05d5\u05d1", "ru": "\u0423\u043b\u0438\u0446\u0430", "zh": "\u8857\u9053", "sr": "Ulica i broj", "ar": "\u0627\u0644\u0634\u0627\u0631\u0639", "lv": "Iela", "id": "Jalan", "ro": "Strada", "af": "Straat", "el": "\u039f\u03b4\u03cc\u03c2", "xh": "Istrato", "zu": "Umgwaqo", "st": "Seterata", "ca": "Carrer" }, "attribute_telephonenumber": { "no": "Telefon", "nn": "Telefon", "sv": "Telefonnummer", "es": "N\u00famero de tel\u00e9fono", "de": "Telefonnummer", "nl": "Telefoonnummer", "lb": "Telefonsnummer", "sl": "Telefonska \u0161tevilka", "da": "Telefonnummer", "hr": "Broj telefona", "hu": "Telefonsz\u00e1m", "fi": "Puhelinnumero", "pt-br": "N\u00famero de Telefone", "pt": "Telefone", "pl": "Numer telefonu (Telephone number)", "cs": "Telefon", "eu": "Telefono zenbakia", "tr": "Telefon numaras\u0131", "fr": "Num\u00e9ro de t\u00e9l\u00e9phone", "it": "Numero di telefono", "lt": "Telefono nr.", "ja": "\u96fb\u8a71\u756a\u53f7", "zh-tw": "\u96fb\u8a71\u865f\u78bc", "et": "Telefoninumber", "he": "\u05de\u05e1\u05e4\u05e8 \u05d8\u05dc\u05e4\u05d5\u05df", "ru": "\u041d\u043e\u043c\u0435\u0440 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430", "zh": "\u7535\u8bdd\u53f7\u7801", "sr": "Telefonski broj", "ar": "\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062a\u0641", "lv": "Telefons", "id": "No Telepon", "ro": "Num\u0103r de telefon", "af": "Telefoon nommer", "el": "\u03a4\u03b7\u03bb\u03ad\u03c6\u03c9\u03bd\u03bf", "zu": "Inombolo yocingo", "xh": "Inombolo yomnxeba", "st": "Nomoro ya founu", "ca": "Número de telèfon" }, "attribute_eduorghomepageuri": { "no": "Organisasjonens hjemmeside", "nn": "Organisasjonen si heimeside (URL)", "sv": "Organisationens hemsida", "es": "P\u00e1gina de su organizaci\u00f3n", "de": "Homepage der Organisation", "nl": "Organisatie homepage", "lb": "Organisatiouns Websait", "sl": "Spletna stran organizacije", "da": "Hjemmeside", "hr": "Web stranice ustanove", "hu": "Szervezet weboldala", "fi": "Organisaation kotisivu", "pt-br": "Site da organiza\u00e7\u00e3o", "pt": "P\u00e1gina web da organiza\u00e7\u00e3o de origem", "pl": "Strona domowa organizacji", "cs": "URL organizace", "tr": "Kurumsal websayfas\u0131", "fr": "Site web institutionnel", "it": "Homepage della propria organizzazione", "lt": "Organizacijos svetain\u0117", "ja": "\u7d44\u7e54\u306e\u30db\u30fc\u30e0\u30da\u30fc\u30b8", "zh-tw": "\u7d44\u7e54\u9996\u9801", "et": "Organisatsiooni koduleht", "he": "\u05d3\u05e3-\u05d1\u05d9\u05ea \u05e9\u05dc \u05d4\u05d0\u05d9\u05e8\u05d2\u05d5\u05df", "ru": "\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u7684\u9996\u9875", "sr": "URL adresa institucije", "ar": " \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0635\u0641\u062d\u0629 \u0627\u0644\u0627\u0644\u0643\u062a\u0631\u0648\u0646\u064a\u0629 \u0644\u0644\u0645\u0646\u0638\u0645\u0629", "lv": "Organiz\u0101cijas m\u0101jas lapa", "id": "Homepage organisasi", "ro": "Pagina web a institutu\u021biei", "eu": "Erakundearen hasiera-orria", "af": "Organisasie tuisblad", "el": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b1\u03c1\u03c7\u03b9\u03ba\u03ae\u03c2 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1\u03c2 \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "xh": "Ikhasi lekhaya Lenkampani", "zu": "Ikhasi lasekhaya lenhlangano", "st": "Leqephe la lapeng la khampani", "ca": "Pàgina principal de l'organització" }, "attribute_eduorglegalname": { "no": "Foretaksnavn", "nn": "Formelt namn p\u00e5 organisasjonen", "sv": "Organisationens legala namn", "es": "Nombre legal de su organizaci\u00f3n", "de": "Name der K\u00f6rperschaft", "nl": "Organisatie naam", "lb": "Numm vun der Organisatioun", "sl": "Naziv organizacije", "da": "Organisationens officielle navn", "hr": "Slu\u017ebeni naziv ustanove", "hu": "Szervezet hivatalos neve", "fi": "Organisaation virallinen nimi", "pt-br": "Nome legal da Organiza\u00e7\u00e3o", "pt": "Nome legal da organiza\u00e7\u00e3o de origem", "pl": "Zarejestrowana nazwa organizacji", "cs": "Pln\u00e9 jm\u00e9no organizace", "tr": "Organizasyonu'un resmi ad\u0131", "fr": "Nom l\u00e9gal de l'institution", "it": "Nome legale della propria organizzazione", "lt": "Organizacijos juridinis pavadinimas", "ja": "\u7d44\u7e54\u306e\u6b63\u5f0f\u540d\u79f0", "zh-tw": "\u7d44\u7e54\u5168\u929c", "et": "Organisatsiooni ametlik nimetus", "he": "\u05d4\u05e9\u05dd \u05d4\u05e8\u05e9\u05de\u05d9 \u05e9\u05dc \u05d4\u05d0\u05d9\u05e8\u05d2\u05d5\u05df", "ru": "\u042e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u7684\u6cd5\u5b9a\u540d\u79f0", "sr": "Zvani\u010dni naziv institucije", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0642\u0627\u0646\u0648\u0646\u064a \u0644\u0644\u0645\u0646\u0638\u0645\u0629", "lv": "Organiz\u0101cijas juridiskais nosaukums", "id": "Nama legal Organisasi", "ro": "Denumirea legal\u0103 a institu\u021biei", "eu": "Erakundearen izen legala", "af": "Wettige naam", "el": "\u0395\u03c0\u03af\u03c3\u03b7\u03bc\u03b7 \u03b5\u03c0\u03c9\u03bd\u03c5\u03bc\u03af\u03b1 \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "zu": "Igama elisemthethweni lenhlangano", "xh": "Igama elisemthethweni lenkampani", "st": "Lebitso la molao la khampani", "ca": "Nom legal de l'organització" }, "attribute_edupersonnickname": { "no": "Kallenavn", "nn": "Kallenamn", "sv": "Smeknamn", "es": "Alias", "de": "Spitzname", "nl": "Bijnaam", "lb": "Sp\u00ebtznumm", "sl": "Vzdevek", "da": "Kaldenavn", "hr": "Nadimak", "hu": "Becen\u00e9v", "fi": "Kutsumanimi", "pt-br": "Apelido", "pt": "Alcunha", "pl": "Ksywka (Nickname)", "cs": "P\u0159ezd\u00edvka", "eu": "Ezizena", "tr": "Takma ad", "fr": "Pseudonyme", "it": "Soprannome (nick)", "lt": "Slapyvardis", "ja": "\u30cb\u30c3\u30af\u30cd\u30fc\u30e0", "zh-tw": "\u66b1\u7a31", "et": "H\u00fc\u00fcdnimi", "he": "\u05db\u05d9\u05e0\u05d5\u05d9", "ru": "\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c", "zh": "\u6635\u79f0", "sr": "Nadimak", "ar": "\u0627\u0644\u0643\u0646\u064a\u0629", "lv": "Niks", "id": "Nama panggilan", "ro": "Porecl\u0103", "af": "Bynaam", "el": "\u03a8\u03b5\u03c5\u03b4\u03ce\u03bd\u03c5\u03bc\u03bf \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7", "xh": "Isiteketiso", "zu": "Isidlaliso", "st": "Lebitso la boswaswi", "ca": "Sobrenom" }, "attribute_edupersonorgdn": { "no": "Entydig navn (DN) for brukerens vertsorganisasjon", "nn": "Eintydig namn (DN) til heimeorganisasjon for brukaren", "sv": "LDAP-pekare (DN) till personens organisation", "es": "DN de su organizaci\u00f3n origen", "de": "Distinguished name (DN) der Organisation", "nl": "Distinguished name (DN) van de organisatie van de persoon", "lb": "Distinguished name (DN) of person's home organization", "sl": "Ime doma\u010de organizacije (DN)", "da": "Din hjemmeorganisations 'distinguished name' (DN)", "hr": "Jedinstveni naziv (DN) korisnikove mati\u010dne ustanove", "hu": "A felhaszn\u00e1l\u00f3 munkahely\u00e9nek azonos\u00edt\u00f3 neve (DN-je)", "fi": "DN-osio organisaation nimest\u00e4", "pt-br": "Nome distinto (DN) da sua organiza\u00e7\u00e3o principal", "pt": "DN da organiza\u00e7\u00e3o de origem", "pl": "Distinguished name (DN) macierzystej organizacji osoby", "cs": "U\u017eivatelsk\u00e9 jm\u00e9no p\u0159id\u011blen\u00e9 organizac\u00ed", "tr": "Ki\u015finin ba\u011fl\u0131 oldu\u011fu kurulu\u015fun belirgin ad\u0131", "fr": "Nom unique (DN) de l'institution d'origine", "it": "Distinguished name (DN) dell'organizzazione ", "lt": "Asmens organizacijos atpa\u017einimo vardas", "ja": "\u7d44\u7e54\u8b58\u5225\u540d", "zh-tw": "\u500b\u4eba\u6240\u5c6c\u7d44\u7e54 Distinguished name (DN)", "he": "\u05e9\u05dd \u05de\u05d6\u05d4\u05d4 (DN) \u05e9\u05dc \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u041e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f (DN) \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u4eba\u7684\u5bb6\u5ead\u7ec4\u7ec7\u7684\u5206\u8fa8\u540d\u79f0\uff08DN\uff09", "sr": "Jedinstveni naziv (DN) korisnikove mati\u010dne institucije", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0645\u0645\u064a\u0632 \u0644\u0644\u0645\u0646\u0638\u0645\u0629 \u0631\u0628 \u0627\u0644\u0639\u0645\u0644", "et": "Koduorganisatsiooni unikaalne nimi (DN)", "lv": "Organiz\u0101cijas v\u0101rds (DN)", "id": "Distinguished name (DN) of person's home organization", "ro": "Nume distincitv (DN) al institu\u021bie de origine a persoanei", "eu": "Pertsonaren jatorrizko erakundearen izen osatua (DN)", "af": "Kenmerkende naam (DN) van die person se tuisorganisasie", "el": "\u0394\u03b9\u03b1\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 (DN) \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "xh": "Igama elahlukileyo (DN) lenkampani yekhaya yomntu", "zu": "Igama elihloniphekile (I-DN) lenhlangano yasekhaya yomuntu", "st": "Lebitso le kgethehileng (DN) la khampani ya habo motho", "ca": "Nom distingit (DN) de l'organització principal de la persona" }, "attribute_edupersonorgunitdn": { "no": "Entydig navn (DN) for brukerens organisasjonsenhet", "nn": "Eintydig namn (DN) til organisasjonseining for brukaren", "sv": "LDAP-pekare (DN) till personens organisationsenhet", "es": "DN de la Unidad Organizativa (OU) de su organizaci\u00f3n origen", "de": "Distinguished name (DN) der Organisationseinheit", "nl": "Distinguished name (DN) van de afdeling van de persoon", "lb": "Distinguished name (DN) of the person's home organizational unit", "sl": "Ime oddelka doma\u010de organizacije (DN)", "da": "Din organisatoriske enheds 'distinguished name' (DN)", "hr": "Jedinstveni naziv (DN) korisnikove organizacijske jedinice", "hu": "A felhaszn\u00e1l\u00f3 szervezeti egys\u00e9g azonos\u00edt\u00f3 neve (DN-je)", "fi": "DN-osio organisaatioyksik\u00f6n nimest\u00e4", "pt-br": "Nome distinto (DN) da sua unidade organizacional principal", "pt": "DN da unidade org\u00e2nica na organiza\u00e7\u00e3o de origem", "pl": "Distinguished name (DN) macierzystej jednostki organizacyjnej osoby", "cs": "U\u017eivatelsk\u00e9 jm\u00e9no p\u0159id\u011blen\u00e9 organiza\u010dn\u00ed jednotkou", "tr": "Ki\u015finin ba\u011fl\u0131 oldu\u011fu birimin belirgin ad\u0131", "fr": "Nom unique (DN) de la section d'origine", "it": "Distinguished name (DN) dell'unit\u00e0 organizzativa della persona", "lt": "Asmens organizacijos skyriaus atpa\u017einimo vardas", "ja": "\u7d44\u7e54\u5358\u4f4d\u8b58\u5225\u540d", "zh-tw": "\u500b\u4eba\u6240\u5c6c\u55ae\u4f4d Distinguished name (DN)", "he": "\u05e9\u05dd \u05de\u05d6\u05d4\u05d4 (DN) \u05e9\u05dc \u05d4\u05d9\u05d7\u05d9\u05d3\u05d4 \u05d1\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u041e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f (DN) \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u4eba\u7684\u5bb6\u7ec4\u7ec7\u5355\u4f4d\u7684\u8fa8\u522b\u540d\u79f0\uff08DN\uff09", "sr": "Jedinstveni naziv (DN) korisnikove organizacione jedinice", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0645\u0645\u064a\u0632 \u0644\u0644\u0648\u062d\u062f\u0629 \u0628\u0627\u0644\u0645\u0646\u0638\u0645\u0629 \u0631\u0628 \u0627\u0644\u0639\u0645\u0644", "et": "Koduorganisatsiooni all\u00fcksuse unikaalne nimi (DN)", "lv": "Organiz\u0101cijas vien\u012bbas v\u0101rds (DN)", "id": "Distinguished name (DN) of the person's home organizational unit", "ro": "Nume distincitv (DN) al unit\u0103\u021bii organiza\u021bionale de origine a persoanei", "eu": "Pertsonaren jatorrizko erakundeko antolamendu-unitatearen izen osatua (DN)", "af": "Kenmerkende naam (DN) van die persoon se organisatoriese afdeling", "el": "\u0394\u03b9\u03b1\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 (DN) \u03bf\u03b9\u03ba\u03b5\u03af\u03b1\u03c2 \u03bf\u03c1\u03b3\u03b1\u03bd\u03c9\u03c4\u03b9\u03ba\u03ae\u03c2 \u03bc\u03bf\u03bd\u03ac\u03b4\u03b1\u03c2", "xh": "Igama elahlukileyo (DN) leyunithi yenkampani yekhaya yomntu", "zu": "Igama elihloniphekile (I-DN) leyunithi yenhlangano yasekhaya yomuntu", "st": "Lebitso le kgethehileng (DN) la yuniti ya khampani ya habo motho", "ca": "Nom distingit (DN) de la unitat organitzativa (OU) de l'organització principal de la persona" }, "attribute_edupersonprimaryaffiliation": { "no": "Prim\u00e6r tilknytning til organisasjon", "nn": "Prim\u00e6rtilknyting til organisasjonen", "sv": "Prim\u00e4r anknytning", "es": "Afiliaci\u00f3n primaria", "de": "Prim\u00e4re Organisationszugeh\u00f6rigkeit", "nl": "Primaire relatie", "lb": "Haapt Zougeh\u00e9iregkeet", "sl": "Primarna vloga", "da": "Prim\u00e6r tilknytning", "hr": "Temeljna povezanost s ustanovom", "hu": "Els\u0151dleges viszony", "fi": "Ensisijainen suhde organisaatioon", "pt-br": "Filia\u00e7\u00e3o Prim\u00e1ria", "pt": "Afilia\u00e7\u00e3o principal com a organiza\u00e7\u00e3o de origem", "pl": "G\u0142\u00f3wna przynale\u017cno\u015b\u0107 (Primary affiliation)", "cs": "Hlavn\u00ed p\u0159\u00edslu\u0161nost", "tr": "\u00d6ncelikli ba\u011flant\u0131", "fr": "Affiliation primaire", "it": "Affiliazione primaria", "lt": "Pirmin\u0117 s\u0105saja", "ja": "\u4e3b\u6240\u5c5e", "zh-tw": "\u4e3b\u8981\u9023\u7d61\u65b9\u5f0f", "he": "\u05d4\u05e9\u05ea\u05d9\u05d9\u05db\u05d5\u05ea \u05e2\u05d9\u05e7\u05e8\u05d9\u05ea", "ru": "\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u043b\u0435\u043d\u0441\u0442\u0432\u043e", "et": "Peamine kuuluvus", "zh": "\u4e3b\u8981\u7684\u8054\u7cfb\u65b9\u5f0f", "sr": "Primarna povezanost sa institucijom", "ar": "\u0627\u0644\u0648\u0638\u064a\u0641\u0629 \u0627\u0644\u0627\u0633\u0627\u0633\u064a\u0629", "lv": "Pamatdarba amats", "id": "Afiliasi utama", "ro": "Afiliere primar\u0103", "eu": "Lehen afiliazioa", "af": "Prim\u00eare affiliasie", "el": "\u039a\u03cd\u03c1\u03b9\u03b1 \u03b9\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1", "xh": "Indima eyintloko", "zu": "Indima eyinhloko", "st": "Kamano ya motheo", "ca": "Afiliació primària" }, "attribute_noreduorgnin": { "no": "Organisasjonsnummer", "nn": "Organisasjonsnummer", "sv": "Organisationsnummer", "es": "N\u00famero de la organizaci\u00f3n", "de": "Firmennummer nach dem Norwegischen Firmenregister", "nl": "Organisatie nummer", "lb": "Organisatiounsnummer", "sl": "Organizacijska \u0161tevilka", "da": "CVR-nummer", "hr": "Broj\u010dani identifikator ustanove", "hu": "Szervezeti sz\u00e1m", "fi": "Organisaation numero", "pt-br": "N\u00famero Organizacional", "pt": "N\u00famero de Organiza\u00e7\u00e3o", "pl": "Numer organizacji", "cs": "\u010cislo organizace", "tr": "Kurumsal numara", "fr": "Immatriculation de l'institution", "it": "Numero organizzativo", "lt": "Organizacijos numeris", "ja": "\u7d44\u7e54\u756a\u53f7", "zh-tw": "\u7d44\u7e54\u865f\u78bc", "he": "\u05de\u05e1\u05e4\u05e8 \u05d0\u05d9\u05e8\u05d2\u05d5\u05e0\u05d9", "ru": "\u041d\u043e\u043c\u0435\u0440 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u7ec4\u7ec7\u53f7\u7801", "sr": "Jedinstveni brojni identifikator institucije", "ar": "\u0627\u0644\u0631\u0642\u0645 \u0628\u0627\u0644\u0645\u0646\u0638\u0645\u0629", "lv": "Organiz\u0101cijas re\u0123istr\u0101cijas numurs", "id": "Nomor Organisasi", "et": "Registrikood", "ro": "Num\u0103r organiza\u021bional", "eu": "Erakundearen zenbakia", "af": "Organisasie nommer", "el": "\u0391\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd", "zu": "Inombolo yenhlangano", "xh": "Inombolo yenkampani", "st": "Nomoro ya khampani", "ca": "Número de l’organització" }, "attribute_noredupersonbirthdate": { "no": "F\u00f8dselsdato", "nn": "F\u00f8dselsdato", "sv": "F\u00f6delsedata", "es": "Fecha de nacimiento", "de": "Geburtsdatum", "nl": "Geboortedatum", "lb": "Gebuertsdaag", "sl": "Datum rojstva", "da": "F\u00f8dselsdato", "hr": "Datum ro\u0111enja", "hu": "Sz\u00fclet\u00e9si d\u00e1tum", "fi": "Syntym\u00e4aika", "pt-br": "Data de Nascimento", "pt": "Data de nascimento", "pl": "Data urodzenia (Date of birth)", "cs": "Datum narozeni", "eu": "Jaioteguna", "tr": "Do\u011fum tarihi", "fr": "Date de naissance", "it": "Data di nascita", "lt": "Gimimo data", "ja": "\u751f\u5e74\u6708\u65e5", "zh-tw": "\u751f\u65e5", "et": "S\u00fcnniaeg", "he": "\u05ea\u05d0\u05e8\u05d9\u05da \u05dc\u05d9\u05d3\u05d4", "ru": "\u0414\u0430\u0442\u0430 \u0440\u043e\u0436\u0434\u0435\u043d\u0438\u044f", "zh": "\u751f\u65e5", "sr": "Datum ro\u0111enja", "ar": "\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0645\u064a\u0644\u0627\u062f", "lv": "Dzim\u0161anas datums", "id": "Tanggal lahir", "ro": "Data na\u0219terii", "af": "Geboorte datum", "el": "\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b3\u03ad\u03bd\u03bd\u03b7\u03c3\u03b7\u03c2", "zu": "Usuku lokuzalwa", "xh": "Umhla wokuzalwa", "st": "Letsatsi la tswalo", "ca": "Data de naixement" }, "attribute_noredupersonlin": { "no": "Lokalt ID-nummer", "nn": "Lokalt brukarnummer (ansattnummer, studentnummer, elevnummer osb)", "sv": "Lokal identifierare", "es": "N\u00famero de identificaci\u00f3n local", "de": "Lokale Kennummer", "nl": "Identiteitsnummer", "lb": "Identit\u00e9itsnummer", "sl": "Vpisna \u0161tevilka", "da": "Lokalt identifikationsnummer", "hr": "Lokalni broj\u010dani identifikator osobe u ustanovi (LOCAL_NO)", "hu": "Helyi azonos\u00edt\u00f3 sz\u00e1m", "fi": "Henkil\u00f6numero", "pt-br": "N\u00famero de Identifica\u00e7\u00e3o Local", "pt": "N\u00famero de Identifica\u00e7\u00e3o local", "pl": "Local identity number", "cs": "Lok\u00e1ln\u00ed identifika\u010dn\u00ed k\u00f3d", "tr": "Yerel kimlik numaras\u0131", "fr": "Immatriculation territoriale", "it": "Numero identificativo locale", "lt": "Vietinis tapatyb\u0117s numeris", "ja": "\u652f\u90e8ID", "zh-tw": "\u672c\u5730\u8eab\u5206\u8b49\u5b57\u865f", "he": "\u05de\u05e1\u05e4\u05e8 \u05d6\u05d4\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9", "ru": "\u041c\u0435\u0441\u0442\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440", "et": "Kohalik isikukood", "zh": "\u672c\u5730\u8eab\u4efd\u53f7\u7801", "sr": "Lokalni brojni identifikator osobe", "ar": "\u0631\u0642\u0645 \u0627\u0644\u0647\u0648\u064a\u0629 \u0627\u0644\u0645\u062d\u0644\u064a", "lv": "Personas kods", "id": "Nomor identitas lokal", "ro": "Num\u0103r de identificare local", "eu": "Tokiko zenbaki identifikatzailea", "af": "Identiteitsnommer", "el": "\u0391\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2", "zu": "Inombolo kamazisi yasendaweni", "xh": "Inombolo yesazisi yasekuhlaleni", "st": "Nomoro ya boitsebiso ya lehae", "ca": "Número d'identitat local" }, "attribute_manager": { "no": "Overordnet", "nn": "Overordna", "sv": "Chef", "es": "Gestor", "de": "Manager\/in", "nl": "Manager", "lb": "Manager", "sl": "Mened\u017eer", "da": "Manager", "hr": "Voditelj", "hu": "Manager", "fi": "Manager", "pt-br": "Administrador", "pt": "Respons\u00e1vel hier\u00e1rquico", "pl": "Menad\u017cer (Manager)", "cs": "Mana\u017eer", "tr": "Y\u00f6netici", "fr": "Gestionnaire", "it": "Manager", "lt": "Vadovas", "ja": "\u7ba1\u7406\u8005", "zh-tw": "\u7ba1\u7406\u54e1", "he": "\u05de\u05e0\u05d4\u05dc", "ru": "\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439", "et": "Juhataja", "zh": "\u7ba1\u7406\u5458", "sr": "Rukovodilac", "ar": "\u0627\u0644\u0645\u062f\u064a\u0631", "lv": "Priek\u0161nieks", "id": "Manager", "ro": "Director\/Manager", "eu": "Kudeatzailea", "af": "Bestuurder", "el": "\u0394\u03b9\u03b1\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 (DN) \u03b4\u03b9\u03b1\u03c7\u03b5\u03b9\u03c1\u03b9\u03c3\u03c4\u03ae", "xh": "Umanejala", "zu": "Umphathi", "st": "Mookamedi", "ca": "Gestor" }, "attribute_userpassword": { "no": "Hash av brukerens passord", "nn": "Passord for brukaren (lagra som hash-verdi)", "sv": "Anv\u00e4ndarens l\u00f6senordshash", "es": "Clave o contrase\u00f1a y m\u00e9todo de encriptaci\u00f3n utilizado", "de": "Passwort Hash des Benutzers", "nl": "Password hash", "sl": "Uporabnikovo zgo\u0161\u010deno geslo", "da": "Hash-v\u00e6rdi af brugerens kodeord", "hr": "Kriptirana zaporka", "hu": "A felhaszn\u00e1l\u00f3 jelszava (k\u00f3dolva)", "fi": "K\u00e4ytt\u00e4j\u00e4n salasanatiiviste", "pt": "Senha do utilizador", "pl": "Zakodowane has\u0142o u\u017cytkownika", "cs": "U\u017eivatelsk\u00e9 heslo (hash)", "tr": "Kullan\u0131c\u0131n\u0131n \u015fifre karmas\u0131", "fr": "Mot de passe chiffr\u00e9", "it": "Hash della password utente", "lt": "Naudotojo slapta\u017eod\u017eio mai\u0161a", "ja": "\u30d1\u30b9\u30ef\u30fc\u30c9\u30cf\u30c3\u30b7\u30e5", "zh-tw": "\u4f7f\u7528\u8005\u5bc6\u78bc (hash)", "et": "Kasutaja paroolir\u00e4si", "he": "\u05d4\u05d2\u05d9\u05d1\u05d5\u05d1 \u05e9\u05dc \u05e1\u05d9\u05e1\u05de\u05ea \u05d4\u05de\u05e9\u05ea\u05de\u05e9", "ru": "\u0425\u044d\u0448 \u043f\u0430\u0440\u043e\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "pt-br": "Hash da Senha do Usu\u00e1rio", "zh": "\u7528\u6237\u5bc6\u7801\u7684HASH\u503c", "sr": "He\u0161 vrednost korisnikove lozinke", "ar": "\u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "lv": "Paroles jauc\u0113jsumma (hash)", "id": "Hash password user", "ro": "Parola utilizatorului \u00een format hash<\/i>", "eu": "Erabiltzailearen pasahitzaren hash-a", "af": "Gebruikerswagwoord", "el": "\u039a\u03c1\u03c5\u03c0\u03c4\u03bf\u03b3\u03c1\u03b1\u03c6\u03b7\u03bc\u03ad\u03bd\u03bf\u03c2 \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2", "xh": "Iheshi yephaswedi yomsebenzisi", "zu": "Uheshi wephasiwedi yomsebenzisi", "st": "Hesh ya phasewete ya mosebedisi", "ca": "Clau o contrasenya i mètode d'encriptació utilitzat" }, "attribute_edupersonprimaryorgunitdn": { "no": "Entydig navn for organisasjonsenheten som brukeren prim\u00e6rt er tilknyttet", "nn": "Eintydig namn (DN) til prim\u00e6r organisasjonseining for personen", "sv": "LDAP-pekare (DN) till personens pim\u00e4ra organisationsenhet", "es": "Distinguished name (DN) de la entrada del directorio que representa el identificador primario de la Unidad Organizativa.", "de": "Distinguished name (DN) der prim\u00e4ren Organisationseinheit", "nl": "Distinguished name (DN) van de organisatie hoofdafdeling waartoe de persoon behoort", "sl": "Ime (DN) oddelka v doma\u010di organizaciji", "da": "Prim\u00e6r enhed\/institution", "hr": "Jedinstveni naziv (DN) korisnikove primarne organizacijske jedinice", "hu": "A szem\u00e9ly els\u0151dleges szervezeti egys\u00e9g\u00e9nek azonos\u00edt\u00f3 neve (DN-je)", "pt": "DN da unidade org\u00e2nica", "cs": "Jm\u00e9no hlavn\u00ed organiza\u010dn\u00ed jednotky", "tr": "Ki\u015finin \u00f6ncelikli Kurumsal Birimi'nin belirgin ad\u0131", "fr": "Nom unique (DN) de la section d'origine", "it": "Distinguished name (DN) dell'unit\u00e0 organizzativa della persona", "lt": "Asmens pirminio organizacijos skyriaus atpa\u017einimo vardas", "ja": "\u4e3b\u8981\u7d44\u7e54\u5358\u4f4d\u8b58\u5225\u540d", "zh-tw": "\u500b\u4eba\u4e3b\u8981\u7d44\u7e54\u55ae\u4f4d Distinguished name (DN)", "he": "\u05e9\u05dd \u05de\u05d6\u05d4\u05d4 (DN) \u05e9\u05dc \u05d4\u05d9\u05d7\u05d9\u05d3\u05d4 \u05d4\u05e2\u05d9\u05e7\u05e8\u05d9\u05ea \u05d1\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea", "ru": "\u041e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f (DN) \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438", "zh": "\u4eba\u7684\u4e3b\u8981\u7ec4\u7ec7\u5355\u4f4d\u7684\u8fa8\u522b\u540d\u79f0\uff08DN\uff09", "sr": "Jedinstveni naziv (DN) korisnikove primarne organizacione jedinice", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0645\u0645\u064a\u0632 \u0644\u0644\u0648\u062d\u062f\u0629 \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629 \u0628\u0627\u0644\u0645\u0646\u0638\u0645\u0629 \u0631\u0628 \u0627\u0644\u0639\u0645\u0644", "pl": "Nazwa osoby w jednostce organizacyjnej", "et": "Peamise all\u00fcksuse unikaalne nimi (DN)", "lv": "Personas pamata organiz\u0101cijas vien\u012bbas v\u0101rds (DN)", "id": "Distinguished name (DN) of person's primary Organizational Unit", "ro": "Nume distincitv (DN) al unit\u0103\u021bii organiza\u021bionale primare a persoanei", "eu": "Pertsonaren antolamendu-unitatearen izen osatua (DN)", "af": "Kenmerkende naam (DN) van die persoon se prim\u00eare organisatoriese afdeling", "el": "\u0394\u03b9\u03b1\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 (DN) \u03ba\u03cd\u03c1\u03b9\u03b1\u03c2 \u03bf\u03c1\u03b3\u03b1\u03bd\u03c9\u03c4\u03b9\u03ba\u03ae\u03c2 \u03bc\u03bf\u03bd\u03ac\u03b4\u03b1\u03c2", "xh": "Igama elahlukileyo (DN) leYunithi Yenkampani yokuqala yomntu", "zu": "Igama elihloniphekile (I-DN) Leyunithi Yenhlangano eyinhloko yomuntu", "st": "Lebitso le kgethehileng (DN) la Yuniti ya Khampani ya Motheo ya habo motho", "ca": "Nom distingit (DN) de l'entrada del directori que representa l'identificador" }, "attribute_schacuserprivateattribute": { "no": "Private informasjonselement", "nn": "Private informasjonselement", "sv": "Information om vilka attribut som har skyddsbehov", "es": "Elementos de informaci\u00f3n privada", "de": "Private Informationselemente", "nl": "Priv\u00e9 informatie-elementen", "sl": "Zasebni informacijski elementi", "da": "Private informationselementer", "hu": "V\u00e9dett adatokat tartalmaz\u00f3 attrib\u00fatumok", "pt": "Elementos privados de informa\u00e7\u00e3o", "pl": "Poufne atrybuty", "cs": "Priv\u00e1tn\u00ed informa\u010dn\u00ed elementy", "tr": "\u00d6zel bilgi elemanlar\u0131", "fr": "\u00c9l\u00e9ments d'informations priv\u00e9es", "hr": "Postavke privatnosti", "it": "Elementi informativi privati", "lt": "Priva\u010dios informacijos elementai", "ja": "\u500b\u4eba\u60c5\u5831\u8981\u7d20", "zh-tw": "\u500b\u4eba\u8cc7\u6599", "et": "Privaatandmete elemendid", "he": "\u05e8\u05db\u05d9\u05d1\u05d9 \u05d4\u05de\u05d9\u05d3\u05e2 \u05d4\u05d0\u05d9\u05e9\u05d9", "ru": "\u042d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043b\u0438\u0447\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438", "zh": "\u4e2a\u4eba\u8d44\u6599", "sr": "Privatni atribut", "ar": "\u0648\u062d\u062f\u0627\u062a \u0627\u0644\u062a\u0639\u0631\u064a\u0641 \u0627\u0644\u062e\u0627\u0635\u0629", "lv": "Priv\u0101t\u0101s inform\u0101cijas elementi", "id": "Elemen-elemen informasi personal", "ro": "Informa\u021bii private", "eu": "Informazio pribatuaren elementuak", "fi": "Yksil\u00f6iv\u00e4t tunnisteet", "af": "Private informasie elemente", "el": "\u0391\u03c0\u03cc\u03c1\u03c1\u03b7\u03c4\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03ac \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1", "zu": "Izingxenye zolwazi oluyimfihlo", "xh": "Iimpawu zenkcazelo yangasese", "st": "Dielemente tsa tlhahisoleseding ya poraefete", "ca": "Elements d'informació privada" }, "attribute_noredupersonlegalname": { "no": "Folkeregistrert navn", "nn": "Namn registrert i Folkeregisteret", "sl": "Uradno ime", "sv": "Officiellt (legalt) namn", "fr": "\u00c9tat civil", "hr": "Slu\u017ebeni naziv", "da": "Officielt navn", "it": "Nome legale", "es": "Nombre legal", "lt": "Juridinis vardas", "ja": "\u6b63\u5f0f\u540d\u79f0", "nl": "Offici\u00eble naam", "de": "Offizeller Name", "zh-tw": "\u6b63\u5f0f\u540d\u5b57", "he": "\u05e9\u05dd \u05e8\u05e9\u05de\u05d9", "ru": "\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435", "zh": "\u6b63\u5f0f\u540d\u79f0", "ar": "\u0627\u0644\u0627\u0633\u0645 \u0627\u0644\u0634\u0631\u0639\u064a", "pl": "Formalna nazwa u\u017cytkownika", "et": "Ametlik nimi", "hu": "Hivatalos n\u00e9v (noreduperson)", "lv": "Juridiskais nosaukums", "id": "Nama legal", "sr": "Pravno ime", "cs": "Pr\u00e1vn\u00ed jm\u00e9no", "ro": "Nume legal", "eu": "Izen legala", "fi": "Virallinen nimi", "af": "Wettige naam", "el": "\u0395\u03c0\u03af\u03c3\u03b7\u03bc\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1", "xh": "Igama elisemthethweni", "zu": "Igama elisemthethweni", "st": "Lebitso la molao", "ca": "Nom legal" }, "attribute_edupersonassurance": { "no": "Tillitsniv\u00e5 for autentisering", "nn": "Tillitsniv\u00e5 for autentisering", "sv": "Identitetens tillf\u00f6rlitlighetsprofil", "sl": "Stopnja zanesljivosti", "fr": "Profil d'assertion d'identit\u00e9", "hr": "Uskla\u0111enost sa standardima za\u0161tite korisni\u010dkih podataka", "da": "Tillidsniveau for autentificering", "it": "Profilo di garanzia sull'identit\u00e0", "lt": "Tapatyb\u0117s tikrumo profilis", "es": "Identificador del perfil de garant\u00eda", "nl": "Identiteitsverzekeringsprofiel", "ja": "\u8b58\u5225\u5b50\u4fdd\u8a3c\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb", "de": "Identity Assurance Profil", "zh-tw": "\u8eab\u5206\u9a57\u8b49\u6587\u4ef6", "he": "\u05e4\u05e8\u05d5\u05e4\u05d9\u05dc \u05d4\u05d1\u05d8\u05d7\u05ea \u05d6\u05d4\u05d5\u05ea", "ru": "\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0430", "et": "Identiteedi tagamise profiil", "zh": "\u53ef\u9760\u9a8c\u8bc1\u914d\u7f6e\u6587\u4ef6", "sr": "Visina pouzdanosti davaoca digitalnih identiteta", "ar": "\u0647\u0648\u064a\u0629 \u0627\u0644\u0636\u0645\u0627\u0646", "lv": "Apraksts, k\u0101 at\u0161\u0137irt cilv\u0113ku no robota", "id": "Profil penjamin identitas", "cs": "Poskytovatel identifika\u010dn\u00edho profilu", "ro": "Profilul de asigurare a identit\u0103\u021bii", "eu": "Bermearen profilaren identifikatzailea", "af": "Identiteitsversekerings profiel", "el": "\u0395\u03c0\u03af\u03c0\u03b5\u03b4\u03bf \u03b1\u03be\u03b9\u03bf\u03c0\u03b9\u03c3\u03c4\u03af\u03b1\u03c2 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2", "zu": "Iphrofayela yokuqinisekisa umazisi", "xh": "Iprofayile yokuqinisekisa isazisi", "st": "Profaele ya tiisetso ya boitsebiso", "ca": "Identificador del perfil de garantia" }, "attribute_ismemberof": { "es": "Membres\u00eda a grupos", "ru": "\u0427\u043b\u0435\u043d\u0441\u0442\u0432\u043e \u0432 \u0433\u0440\u0443\u043f\u043f\u0435", "fi": "Ryhm\u00e4n j\u00e4senyys", "zh-tw": "\u7fa4\u7d44\u6210\u54e1", "nl": "Groepslidmaatschap", "da": "Gruppemedlemsskab", "af": "Groeplidmaatskap", "el": "\u03a3\u03c5\u03bc\u03bc\u03b5\u03c4\u03bf\u03c7\u03ae \u03c3\u03b5 \u03bf\u03bc\u03ac\u03b4\u03b5\u03c2", "xh": "Ubulungu beqela", "zu": "Ubulungu beqembu", "st": "Botho ba sehlopha", "ca": "Pertinença al grup" } } simplesamlphp-1.19.1/dictionaries/status.translation.json0000644000000000000000000006257014042503475022425 0ustar rootroot{ "header_saml20_sp": { "no": "SAML 2.0 SP Demo Eksempel", "nn": "Demonstrasjon av SAML 2.0 SP", "sv": "SAML 2.0 SP demoexempel", "es": "Ejemplo de SAML 2.0 SP", "fr": "Exemple de d\u00e9monstration de SP SAML 2.0", "de": "SAML 2.0 SP Demo Beispiel", "nl": "SAML 2.0 SP Demo", "sl": "SAML 2.0 SP Demo primer", "da": "SAML 2.0 tjenesteudbyder-demo", "hr": "Primjer SAML 2.0 davatelja usluge", "hu": "SAML 2.0 SP pr\u00f3ba p\u00e9lda", "fi": "SAML 2.0 SP esimerkki", "pt-br": "SAML 2.0 SP Exemplo", "pt": "Exemplo de demonstra\u00e7\u00e3o do SP SAML 2.0", "pl": "Przyk\u0142adowe Demo SAML 2.0 SP", "cs": "SAML 2.0 SP Demo", "eu": "SAML 2.0 SP Adibidea", "tr": "SAML 2.0 SP Demo \u00d6rne\u011fi", "it": "Demo di SAML 2.0 SP", "lt": "SAML 2.0 SP Demonstracin\u0117s versijos Pavyzdys", "ja": "SAML 2.0 SP \u30c7\u30e2\u4f8b", "zh-tw": "SAML 2.0 SP Demo \u7bc4\u4f8b", "et": "SAML 2.0 SP demon\u00e4ide", "he": "\u05d4\u05d3\u05d2\u05de\u05ea \u05d3\u05d5\u05d2\u05de\u05d4 \u05dc\u05e1\"\u05e9 \u05de\u05e1\u05d5\u05d2 SAML 2.0", "zh": "SAML 2.0 SP\u6f14\u793a\u6848\u4f8b", "ar": "\u0627\u0633\u062a\u0639\u0631\u0627\u0636 \u0645\u062b\u0627\u0644 \u0644 SAML 2.0 SP", "lv": "SAML 2.0 SP demonstr\u0101cijas piem\u0113rs", "id": "Contoh Demo SAML 2.0 SP", "sr": "SAML 2.0 SP Demo Primer", "ro": "Exemplu demonstrativ de furnizor de servicii SAML 2.0", "ru": "\u0414\u0435\u043c\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 SAML 2.0 SP", "el": "\u0394\u03bf\u03ba\u03b9\u03bc\u03b1\u03c3\u03c4\u03b9\u03ba\u03cc\u03c2 \u03a0\u03b1\u03c1\u03bf\u03c7\u03ad\u03b1\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd SAML 2.0", "zu": "Isampula Ledemo Ye-SAML 2.0 SP", "xh": "Umzekelo weDemo we-SAML 2.0 SP", "st": "Mohlala wa Pontsho wa SAML 2.0 SP", "ca": "Exemple de demostració SAML 2.0 SP" }, "header_shib": { "no": "Shibboleth Demo", "nn": "Demonstrasjon av Shibboleth", "sv": "Shibboleth demoexempel", "es": "Ejemplo Shibboleth", "fr": "Exemple de d\u00e9monstration de Shibboleth", "de": "Shibboleth Demo", "nl": "Shibboleth demo", "sl": "Shibboleth demo primer", "da": "Shibboleth-demo", "hr": "Shibboleth primjer", "hu": "Shibboleth pr\u00f3ba", "fi": "Shibboleth esimerkki", "pt-br": "Shibboleth Demo", "pt": "Exemplo de demonstra\u00e7\u00e3o do SP Shibboleth 1.3", "pl": "Demo Shibboleth", "cs": "Shibboleth demo", "eu": "Shibboleth Adibidea", "tr": "Shibboleth demo", "it": "Demo di Shibboleth", "lt": "Shibboleth demonstracin\u0117 versija", "ja": "Shibboleth \u30c7\u30e2", "zh-tw": "Shibboleth Demo", "et": "Shibbolethi demo", "he": "\u05d4\u05d3\u05d2\u05de\u05d4 \u05dc- Shibboleth", "zh": "Shibboleth\u6f14\u793a", "ar": "\u0627\u0633\u062a\u0639\u0631\u0627\u0636 Shibboleth", "lv": "Shibboleth demo", "id": "Demo Shibboleth", "sr": "Shibboleth Demo", "ro": "Demo Shibboleth", "ru": "Shibboleth \u0434\u0435\u043c\u043e", "el": "\u0394\u03bf\u03ba\u03b9\u03bc\u03b1\u03c3\u03c4\u03b9\u03ba\u03cc\u03c2 \u03a0\u03b1\u03c1\u03bf\u03c7\u03ad\u03b1\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd Shibboleth", "xh": "Idemo ye-Shibboleth", "zu": "Idemo ye-Shibboleth", "st": "Pontsho ya Shibboleth", "ca": "Exemple de demostració Shibboleth" }, "header_diagnostics": { "no": "SimpleSAMLphp diagnostikk", "nn": "Feils\u00f8king av SimpleSAMLphp", "sv": "SimpleSAMLphp diagnostik ", "es": "Diagn\u00f3stico SimpleSAMLphp", "fr": "Diagnostics SimpleSAMLphp", "de": "SimpleSAMLphp Diagnose", "nl": "SimpleSAMLphp controle", "sl": "SimpleSAMLphp diagnostika", "da": "SimpleSAMLphp diagnostik", "hr": "SimpleSAMLphp dijagnostika", "hu": "SimpleSAMLphp hibakeres\u00e9s", "fi": "SimpleSAMLphp diagnostiikka", "pt-br": "Diagn\u00f3sticos do SimpleSAMLphp", "pt": "Diagn\u00f3sticos do SimpleSAMLphp", "pl": "Diagnostyka SimpleSAMLphp", "cs": "SimpleSAMLphp diagnostika", "eu": "SimpleSAMLphp Diagnostikoa", "tr": "SimpleSAMLphp Kontroller", "it": "Diagnostici di SimpleSAMLphp", "lt": "SimpleSAMLphp Diagnostika", "ja": "SimpleSAMLphp \u8a3a\u65ad", "zh-tw": "SimpleSAMLphp \u8a3a\u65b7", "et": "SimpleSAMLphp diagnostika", "he": "\u05d0\u05d9\u05d1\u05d7\u05d5\u05df SimpleSAMLphp", "zh": "SimpleSAMLphp \u8bca\u65ad", "ar": "\u062a\u0634\u062e\u064a\u0635 SimpleSAMLphp", "lv": "SimpleSAMLphp diagnostika", "id": "Diagnostik SimpleSAMLphp", "sr": "SimpleSAMLphp Dijagnostika", "ro": "Diagnostic SimpleSAMLphp", "ru": "\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 SimpleSAMLphp", "el": "\u0394\u03b9\u03b1\u03b3\u03bd\u03c9\u03c3\u03c4\u03b9\u03ba\u03ac SimpleSAMLphp", "zu": "Ukuhlonzwa Kwe-SimpleSAMLphp", "xh": "Uhlalutyo lwe-SimpleSAMLphp", "st": "Dimanollo tsa SimpleSAMLphp", "ca": "Diagnòstic SimpleSAMLphp" }, "some_error_occurred": { "no": "En feil har oppst\u00e5tt", "nn": "Ein feilsituasjon oppsto", "sv": "Ett fel har intr\u00e4ffat", "es": "Se produjo un error", "fr": "Une erreur est survenue", "de": "Es ist ein Fehler aufgetreten", "nl": "Er is een fout opgetreden", "sl": "Pri\u0161lo je do napake!", "da": "En fejl opstod.", "hr": "Pojavila se gre\u0161ka", "hu": "Hiba t\u00f6rt\u00e9nt", "fi": "Virhe", "pt-br": "Ocorreu algum erro", "pt": "Ocorreu um erro", "pl": "Wystapi\u0142 jaki\u015b b\u0142\u0105d", "cs": "Nalezena chyba", "eu": "Errore bat jazo da", "tr": "Hata olu\u015ftu", "it": "Si \u00e8 verificato un errore", "lt": "\u012evyko tam tikra klaida", "ja": "\u5e7e\u3064\u304b\u306e\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f", "zh-tw": "\u6709\u932f\u8aa4\u767c\u751f", "et": "Ilmnes mingi t\u00f5rge", "he": "\u05d4\u05ea\u05e8\u05d7\u05e9\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4", "zh": "\u67d0\u4e9b\u9519\u8bef\u53d1\u751f\u4e86", "ar": "\u0644\u0642\u062f \u062d\u062f\u062b \u062e\u0637\u0627 \u0645\u0627", "lv": "Notikusi k\u013c\u016bda", "id": "Beberapa error telah terjadi", "sr": "Desila se gre\u0161ka", "ro": "A ap\u0103rut o eroare", "ru": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430", "el": "\u03a3\u03c5\u03bd\u03ad\u03b2\u03b7 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1", "zu": "Kuvele iphutha elithile", "xh": "Kwenzeke impazamo ethile", "st": "Ho na le phoso e etsahetseng", "ca": "S'ha produït un error" }, "intro": { "no": "Hei, dette er en statusside p\u00e5 SimpleSAMLphp. Her kan du se om sesjonen din er timet ut, hvor lenge det er til den timer ut og attributter som er knyttet til din sesjon.", "nn": "Hei, dette er statussida for SimpleSAMLphp. Her kan du sj\u00e5 om sesjonen din er gyldig, kor lenge han varer og du kan sj\u00e5 alle attributt som blir brukte i sesjonen din.", "sv": "Detta \u00e4r stutussidan f\u00f6r SimpleSAMLphp. H\u00e4r kan du se om sessions giltig har g\u00e5tt ut, hur l\u00e4nge det dr\u00f6jer innan den g\u00e5r ut samt alla attribut som tillh\u00f6r sessionen.", "es": "Hola, esta es la p\u00e1gina de estado de SimpleSAMLphp. Desde aqu\u00ed puede ver si su sesi\u00f3n ha caducado, cuanto queda hasta que lo haga y todos los atributos existentes en su sesi\u00f3n.", "fr": "Bonjour, vous \u00eates sur la page de statut de SimpleSAMLphp. Vous pouvez consulter ici le temps restant sur votre session, ainsi que les attributs qui y sont attach\u00e9s.", "de": "Hallo, das ist die Statusseite von SimpleSAMLphp. Hier k\u00f6nnen Sie sehen, ob Ihre Sitzung ausgelaufen ist, wie lange die Sitzung noch g\u00fcltig ist und alle Attribute Ihrer Sitzung.", "nl": "Dit is de overzichtspagina van SimpleSAMLphp. Hier kunt u zien of uw sessie nog geldig is, hoe lang het nog duurt voordat deze verloopt, en u kunt alle attributen bekijken die aanwezig zijn in deze sessie.", "sl": "\u017divjo! To je statusna stran SimpleSAMLphp, ki omogo\u010da pregled nad trajanjem va\u0161e trenutne seje in atributi, ki so povezani z njo.", "da": "Dette er statussiden for SimpleSAMLphp. Du kan se om din session er udl\u00f8bet, hvor lang tid der er til at den udl\u00f8ber, samt alle \u00f8vrige oplysninger om din session.", "hr": "Ovo je stranica s prikazom aktualnog stanja Single Sign-On sjednice. Na ovoj stranici mo\u017eete vidjeti je li vam istekla sjednica, koliko \u0107e jo\u0161 dugo va\u0161a sjednica trajati te sve atribute koji su vezani uz va\u0161u sjednicu.", "hu": "\u00dcdv\u00f6z\u00f6lj\u00fck, ez a SimpleSAMLphp st\u00e1tus oldala. Itt l\u00e1thatja, ha lej\u00e1rt a munkamenete, mikor l\u00e9pett be utolj\u00e1ra \u00e9s a munkamenethez tartoz\u00f3 attrib\u00fatumokat.", "fi": "T\u00e4m\u00e4 on SimpleSAMLphp:n statussivu. N\u00e4et onko istuntosi voimassa, kauanko se on voimassa ja kaikki istuuntosi liitetyt attribuutit.", "pt-br": "Ol\u00e1, esta \u00e9 a p\u00e1gina de status SimpleSAMLphp. Aqui voc\u00ea pode ver \u00e9 se a sua sess\u00e3o expirou, o tempo que dura at\u00e9 ele expirar e todos os atributos que est\u00e3o anexados \u00e0 sua sess\u00e3o.", "pt": "Est\u00e1 na p\u00e1gina de status do SimpleSAMLphp. Aqui poder\u00e1 consultar informa\u00e7\u00f5es sobre a sua sess\u00e3o: o tempo de expira\u00e7\u00e3o e os seus atributos.", "pl": "Hej, to jest status strony SimpleSAMLphp. Tutaj mo\u017cesz zaboaczy\u0107, czy Twoja sesja jest nadal aktywna, jak d\u0142ugo pozosta\u0142o czasu do zako\u0144czenia sesji i wszystkie atrybuty, kt\u00f3re zosta\u0142y za\u0142\u0105czone do sesji.", "cs": "V\u00edtejte na informa\u010dn\u00ed str\u00e1nce. Zde uvid\u00edte, pokud vypr\u0161elo va\u0161e sezen\u00ed, jak dlouho jste pry\u010d a v\u0161echny atributy p\u0159ipojen\u00e9 k va\u0161emu sezen\u00ed.", "tr": "Merhaba, bu SimpleSAMLphp durum sayfas\u0131d\u0131r. Oturumunuzun s\u00fcresinin dolup dolmad\u0131\u011f\u0131n\u0131, oturumunuzun ne kadar s\u00fcrd\u00fc\u011f\u00fcn\u00fc ve oturumunuza ait t\u00fcm bilgileri buradan g\u00f6rebilirsiniz.", "it": "Salve, questa \u00e8 la pagina di stato di SimpleSAMLphp. Qui \u00e8 possiible vedere se la sessione \u00e8 scaduta, quanto \u00e8 durata prima di scadere e tutti gli attributi ad essa collegati.", "lt": "Sveikia, \u010dia SimpleSAMLphp b\u016bsenos tinklapis. \u010cia galite pamatyti, ar J\u016bs\u0173 sesija turi laiko apribojim\u0105, kiek trunka tas laiko apribojimas bei kitus J\u016bs\u0173 sesijai priskirtus atributus.", "ja": "\u3053\u3093\u306b\u3061\u306f\u3001\u3053\u3053\u306f SimpleSAMLphp\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\u30da\u30fc\u30b8\u3067\u3059\u3002\u3053\u3053\u3067\u306f\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u6642\u9593\u3084\u30bb\u30c3\u30b7\u30e7\u30f3\u306b\u7d50\u3073\u3064\u3051\u3089\u308c\u305f\u5c5e\u6027\u60c5\u5831\u3092\u898b\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002", "zh-tw": "\u563f\uff0c\u9019\u662f SimpleSAMLphp \u72c0\u614b\u9801\uff0c\u5728\u9019\u908a\u60a8\u53ef\u4ee5\u770b\u5230\u60a8\u7684\u9023\u7dda\u662f\u5426\u903e\u6642\uff0c\u4ee5\u53ca\u9084\u6709\u591a\u4e45\u624d\u903e\u6642\uff0c\u6240\u6709\u5c6c\u6027\u503c (attributes) \u90fd\u6703\u9644\u52a0\u5728\u4f60\u7684\u9023\u7dda (session) \u88e1\u3002", "et": "Tere! See on SimpleSAMLphp olekuteave. Siit on v\u00f5imalik n\u00e4ha, kas su sessioon on aegunud, kui kaua see veel kestab ja k\u00f5iki teisi sessiooniga seotud atribuute.", "he": "\u05e9\u05dc\u05d5\u05dd, \u05d6\u05d4\u05d5 \u05d3\u05e3 \u05d4\u05de\u05e6\u05d1 \u05e9\u05dc SimpleSAMLphp. \u05db\u05d0\u05df \u05d0\u05e4\u05e9\u05e8 \u05dc\u05e8\u05d0\u05d5\u05ea \u05d0\u05dd \u05d4\u05e9\u05d9\u05d7\u05d4 \u05d4\u05d5\u05e4\u05e1\u05e7\u05d4, \u05db\u05de\u05d4 \u05d6\u05de\u05df \u05d4\u05d9\u05d0 \u05ea\u05de\u05e9\u05d9\u05da \u05e2\u05d3 \u05dc\u05d4\u05e4\u05e1\u05e7\u05ea\u05d4 \u05d5\u05db\u05dc \u05d4\u05ea\u05db\u05d5\u05e0\u05d5\u05ea \u05d4\u05de\u05e6\u05d5\u05e8\u05e4\u05d5\u05ea \u05dc\u05e9\u05d9\u05d7\u05d4.", "zh": "\u55e8\uff0c\u8fd9\u662fSimpleSAMLphp\u72b6\u6001\u9875\u3002\u8fd9\u91cc\u4f60\u53ef\u4ee5\u770b\u5230\uff0c\u5982\u679c\u60a8\u7684\u4f1a\u8bdd\u8d85\u65f6\uff0c\u5b83\u6301\u7eed\u591a\u4e45\uff0c\u76f4\u5230\u8d85\u65f6\u548c\u8fde\u63a5\u5230\u60a8\u7684\u4f1a\u8bdd\u7684\u6240\u6709\u5c5e\u6027\u3002", "ar": "\u0645\u0631\u062d\u0628\u0627\u064b \u0628\u0643\u0645 \u0641\u064a \u0635\u0641\u062d\u0629 \u062d\u0627\u0644\u0629 SimpleSAMLphp. \u064a\u0645\u0643\u0646\u0643 \u0647\u0646\u0627 \u0645\u0631\u0627\u0642\u0628\u0629 \u0648\u0642\u062a \u0627\u0646\u062a\u0647\u0627\u0621 \u062c\u0644\u0633\u062a\u0643\u060c \u0641\u062a\u0631\u0629 \u0627\u0633\u062a\u0645\u0631\u0627\u0631\u0647\u0627\u060c \u0645\u062a\u064a \u0633\u062a\u0646\u062a\u0647\u064a \u0648 \u062c\u0645\u064a\u0639 \u0627\u0644\u0633\u0645\u0627\u062a \u0627\u0644\u0645\u0631\u062a\u0628\u0637\u0629 \u0628\u0627\u0644\u062c\u0644\u0633\u0629", "lv": "\u0160\u012b ir SimpleSAMLphp statusa lapa. Te J\u016bs varat redz\u0113t vai J\u016bsu sesija ir p\u0101rtraukta, cik ilgi t\u0101 bijusi akt\u012bva un visus ar to saist\u012btos atrib\u016btus.", "id": "Hai, ini adalah halaman status dari SimpleSAMLphp. Disini anda dapat melihat jika session anda telah time out, berapa lama ia berlaku sampai time out dan semua attribut yang menempel pada session anda.", "sr": "Ovo je stranica s prikazom aktuelnog stanja va\u0161e sesije. Na ovoj stranici mo\u017eete videti je li vam je istekla sesija, koliko \u0107e jo\u0161 dugo va\u0161a sesija trajati i sve atribute koji su vezani uz va\u0161u sesiju.", "ro": "Aceasta este pagina de stare pentru SimpleSAMLphp. Aici pute\u021bi verifica dac\u0103 sesiunea dumneavoastr\u0103 a expirat, c\u00e2t timp mai este p\u00e2n\u0103 la expirarea sesiunii precum \u0219i toate atributele ata\u0219ate sesiunii dumneavoastr\u0103.", "ru": "\u042d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c SimpleSAMLphp. \u041c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0438, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0441\u0441\u0438\u0438 \u0434\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u0440\u043e\u043a\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0438 \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438.", "eu": "Kaixo, hau SimpleSAMLphp-ren egoera orria da. Hemendik ikus dezakezu zure saioa iraungi den, zenbat denbora geratzen den hau gerta dadin eta zure saioan dauden atributu guztiak.", "el": "\u03a7\u03b1\u03af\u03c1\u03b5\u03c4\u03b5, \u03b1\u03c5\u03c4\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03b7 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 SimpleSAMLphp. \u0395\u03b4\u03ce \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b5\u03af\u03c4\u03b5 \u03b1\u03bd \u03b7 \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1 \u03c3\u03b1\u03c2 \u0028\u0073\u0065\u0073\u0073\u0069\u006f\u006e\u0029 \u03ad\u03c7\u03b5\u03b9 \u03bb\u03ae\u03be\u03b5\u03b9\u002c \u03c4\u03bf \u03c7\u03c1\u03bf\u03bd\u03b9\u03ba\u03cc \u03b4\u03b9\u03ac\u03c3\u03c4\u03b7\u03bc\u03b1 \u03c0\u03bf\u03c5 \u03b4\u03b9\u03b1\u03c1\u03ba\u03b5\u03af \u03ad\u03c9\u03c2 \u03cc\u03c4\u03bf\u03c5 \u03bb\u03ae\u03be\u03b5\u03b9\u002c \u03ba\u03b1\u03b8\u03ce\u03c2 \u03ba\u03b1\u03b9 \u03cc\u03bb\u03b5\u03c2 \u03c4\u03b9\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c0\u03bf\u03c5 \u03c3\u03c5\u03bd\u03b4\u03ad\u03bf\u03bd\u03c4\u03b1\u03b9 \u03bc\u03b5 \u03c4\u03b7 \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1 \u03c3\u03b1\u03c2.", "zu": "Sawubona, leli ikhasi lesimo se-SimpleSAMLphp. Lapha ungakwazi ukubona ukuthi iseshini yakho iphelelwe isikhathi yini, ukuthi ihlala isikhathi eside kangakanani ngaphambi kokuthi iphelelwe isikhathi kanye nazo zonke izici ezihambisana neseshini yakho.", "xh": "Molo, eli likhasi lobume be-SimpleSAMLphp. Apha ungabona ukuba ngaba iseshoni yakho iphelelwe lixesha, iza kuhlala ixesha elide kangakanani ngaphambi kokuba iphelelwe nazo zonke iimpawu ezincanyathiselweyo kwiseshoni yakho.", "st": "Dumela, lena ke leqephe la boemo la SimpleSAMLphp. Mona o ka bona hore na seshene ya hao e feletswe ke nako na, hore e nka nako e kae hore e fellwe ke nako le makgabane ohle a hoketsweng sesheneng ya hao.", "ca": "Hola, aquesta és la pàgina d'estat de SimpleSAMLphp. Aquí podeu veure si la vostra sessió ha caducat, quant de temps dura fins que finalitza el temps i tots els atributs que s'adjunten a la vostra sessió." }, "validfor": { "no": "Din sesjon er gyldig i %SECONDS% sekunder fra n\u00e5.", "nn": "Din sesjon er gyldig i %SECONDS% sekund fr\u00e5 no.", "sv": "Din session \u00e4r giltig f\u00f6r %SECONDS% sekunder fr\u00e5n nu.", "es": "Su sesi\u00f3n ser\u00e1 valida durante %SECONDS% segundos.", "fr": "Votre session est encore valide pour %SECONDS% secondes.", "de": "Ihre Sitzung ist noch f\u00fcr %SECONDS% g\u00fcltig.", "nl": "Uw sessie is nog %SECONDS% seconden geldig vanaf dit moment.", "sl": "Va\u0161a trenutna seja je veljavna \u0161e %SECONDS% sekund.", "da": "Du har %SECONDS% tilbage af din session", "hr": "Va\u0161a sjednica bit \u0107e valjana jo\u0161 %SECONDS% sekundi.", "hu": "Az \u00f6n munkamenete m\u00e9g %SECONDS% m\u00e1sodpercig \u00e9rv\u00e9nyes", "fi": "Istuntosi on viel\u00e4 voimassa %SECONDS% sekuntia", "pt-br": "Sua sess\u00e3o \u00e9 v\u00e1lida por %SECONDS% segundos a partir de agora.", "pt": "A sua sess\u00e3o \u00e9 v\u00e1lida por %SECONDS% segundos.", "pl": "Twoja sesja jest jeszcze wa\u017cna przez %SECONDS% sekund", "cs": "Va\u0161e sezen\u00ed je platn\u00e9 %SECONDS% sekund od te\u010f.", "tr": "Oturumunuz, \u015fu andan itibaren %SECONDS% saniyeli\u011fine ge\u00e7erlidir.", "it": "La tua sessione \u00e8 valida per ulteriori %SECONDS% secondi.", "lt": "J\u016bs\u0173 sesija galioja %SECONDS% sekund\u017ei\u0173, skai\u010diuojant nuo \u0161io momento.", "ja": "\u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u4eca\u304b\u3089 %SECONDS% \u79d2\u9593\u6709\u52b9\u3067\u3059", "zh-tw": "\u60a8\u7684\u9023\u7dda (session) \u5f9e\u73fe\u5728\u8d77\u9084\u6709 %SECONDS% \u79d2\u6709\u6548\u3002", "et": "Sinu sessioon kehtib veel %SECONDS% sekundit.", "he": "\u05d4\u05e9\u05d9\u05d7\u05d4 \u05e9\u05dc\u05da \u05d1\u05e8\u05ea-\u05ea\u05d5\u05e7\u05e3 \u05dc\u05e2\u05d5\u05d3 %SECONDS% \u05e9\u05e0\u05d9\u05d5\u05ea \u05de\u05e2\u05db\u05e9\u05d9\u05d5.", "zh": "\u4f60\u7684\u4f1a\u8bdd\u5728%SECONDS%\u79d2\u5185\u6709\u6548", "ar": "\u0633\u062a\u0633\u062a\u0645\u0631 \u062c\u0644\u0633\u062a\u0643 \u0644\u066a\u0639\u062f\u062f \u062b\u0648\u0627\u0646\u064a\u066a \u062b\u0627\u0646\u064a\u0629 \u062a\u0628\u062f\u0623 \u0627\u0644\u0627\u0646", "lv": "Sesija ir der\u012bga %SECONDS% sekundes no \u0161\u012b br\u012b\u017ea.", "id": "Session anda valid untuk %SECONDS% detik dari sekarang.", "sr": "Va\u0161a sesija \u0107e biti validna jo\u0161 %SECONDS% sekundi.", "ro": "Sesiunea dumneavoastr\u0103 mai este valid\u0103 \u00eenc\u0103 %SECONDS%.", "ru": "\u0412\u0430\u0448\u0430 \u0441\u0435\u0441\u0441\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 %SECONDS% \u0441\u0435\u043a\u0443\u043d\u0434.", "eu": "Zure saioa %SECONDS% segundoz izango da baliagarri.", "el": "\u0391\u03c0\u03bf\u03bc\u03ad\u03bd\u03bf\u03c5\u03bd %SECONDS% \u03b4\u03b5\u03c5\u03c4\u03b5\u03c1\u03cc\u03bb\u03b5\u03c0\u03c4\u03b1 \u03bc\u03ad\u03c7\u03c1\u03b9 \u03c4\u03b7 \u03bb\u03ae\u03be\u03b7 \u03c4\u03b7\u03c2 \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1\u03c2 \u03c3\u03b1\u03c2.", "xh": "Iseshoni yakho iza kusebenza kangangemizuzu e-%SECONDS% ukususela ngoku.", "zu": "Iseshini yakho isebenza imizuzwana engu-%SECONDS% ukusuka manje.", "st": "Seshene ya hao e na le matla feela bakeng sa metsotswana e %SECONDS% ho tloha hona jwale.", "ca": "La vostra sessió és vàlida durant %SECONDS% segons des d’ara." }, "sessionsize": { "no": "Sesjons st\u00f8rrelse: %SIZE%", "nn": "Sesjonsstorleik: %SIZE%", "sv": "Sessionsstorlek: %SIZE%", "es": "Tama\u00f1o de la sesi\u00f3n: %SIZE%", "fr": "Taille de la session : %SIZE%", "de": "Gr\u00f6sse der Sitzung: %SIZE%", "nl": "Sessiegrootte: %SIZE%", "sl": "Velikost seje: %SIZE% bajtov", "da": "Sessionsst\u00f8rrelse: %SIZE%", "hr": "Veli\u010dina sjednice: %SIZE%", "hu": "Munkamenet m\u00e9rete: %SIZE%", "fi": "Istunnon koko: %SIZE%", "pt-br": "Tamanho da sess\u00e3o: %SIZE%", "pt": "Tamanho da sess\u00e3o: %SIZE%", "pl": "Rozmiar sesji: %SIZE%", "cs": "Velikost sezeni: %SIZE%", "eu": "Saioaren tamaina: %SIZE%", "tr": "Oturum b\u00fcy\u00fckl\u00fc\u011f\u00fc: %SIZE%", "it": "Dimensione della session: %SIZE%", "lt": "Sesijos trukm\u0117: %SIZE%", "ja": "\u30bb\u30c3\u30b7\u30e7\u30f3\u30b5\u30a4\u30ba: %SIZE%", "zh-tw": "Session \u5927\u5c0f: %SIZE%", "et": "Sessiooni suurus: %SIZE%", "he": "\u05d2\u05d5\u05d3\u05dc \u05e9\u05d9\u05d7\u05d4: %SIZE%", "ru": "\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u0435\u0441\u0441\u0438\u0438: %SIZE%", "zh": "Session \u5927\u5c0f: %SIZE%", "ar": "\u062d\u062c\u0645 \u0627\u0644\u062c\u0644\u0633\u0629 \u066a\u062d\u062c\u0645\u066a", "lv": "Sesijas izm\u0113rs: %SIZE%", "id": "Ukuran session: %SIZE%", "sr": "Veli\u010dina sesije: %SIZE%", "ro": "Dimensiunea sesiunii: %SIZE%", "el": "\u039c\u03ad\u03b3\u03b5\u03b8\u03bf\u03c2 \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03af\u03b1\u03c2: %SIZE%", "xh": "Ubukhulu beseshoni: %SIZE%", "zu": "Usayizi weseshini: %SIZE%", "st": "Saese ya seshene: %SIZE%", "ca": "Mida de la sessió: %SIZE%" }, "attributes_header": { "no": "Dine attributter", "nn": "Dine attributtar", "sv": "Dina attribut", "es": "Atributos", "fr": "Vos attributs", "de": "Ihre Attribute", "nl": "Uw attributen", "sl": "Va\u0161i atributi", "da": "Dine oplysninger", "hr": "Va\u0161i atributi", "hu": "Az \u00f6n attrib\u00fatumai", "fi": "Attribuuttisi", "pt-br": "Seus atributos", "pt": "Os seus atributos", "pl": "Twoje atrybuty", "cs": "Va\u0161e atributy", "eu": "Atributuak", "tr": "Bilgileriniz", "it": "I tuoi attributi", "lt": "J\u016bs\u0173 atributai", "ja": "\u5c5e\u6027", "zh-tw": "\u60a8\u7684\u5c6c\u6027", "et": "Sinu atribuudid", "he": "\u05d4\u05ea\u05db\u05d5\u05e0\u05d5\u05ea \u05e9\u05dc\u05da", "ru": "\u0412\u0430\u0448\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b", "zh": "\u4f60\u7684\u5c5e\u6027", "ar": "\u0627\u0644\u0633\u0645\u0627\u062a", "lv": "Atrib\u016bti", "id": "Attribut Anda", "sr": "Va\u0161i atributi", "ro": "Atributele dumneavoastr\u0103", "el": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2", "zu": "Izici zakho", "xh": "Iimpawu zakho", "st": "Makgabane a hao", "ca": "Els teus atributs" }, "logout": { "no": "Logg ut", "nn": "Logg ut", "sv": "Logga ut", "es": "Salir", "fr": "D\u00e9connexion", "de": "Abmelden", "nl": "Logout", "sl": "Odjava", "da": "Log ud", "hr": "Odjava", "hu": "Kil\u00e9p\u00e9s", "fi": "Uloskirjautuminen", "pt-br": "Desconectar", "pt": "Sair", "pl": "Wyloguj", "cs": "Odhl\u00e1\u0161en\u00ed", "eu": "Irten", "tr": "\u00c7\u0131k\u0131\u015f", "it": "Disconnessione", "lt": "Atsijungti", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8", "zh-tw": "\u767b\u51fa", "et": "Logi v\u00e4lja", "he": "\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea", "ru": "\u0412\u044b\u0439\u0442\u0438", "zh": "\u9000\u51fa", "ar": "\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c", "lv": "Atsl\u0113gties", "id": "Logout", "sr": "Odjava", "ro": "Deautentificare", "el": "\u0391\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7", "xh": "Phuma", "zu": "Phuma", "st": "Ho tswa", "ca": "Tancar sessió" }, "subject_header": { "es": "Identificador SAML", "ru": "\u0422\u0435\u043c\u0430 SAML", "zh-tw": "SAML \u4e3b\u984c", "nl": "SAML Subject", "da": "SAML emne", "el": "\u03a5\u03c0\u03bf\u03ba\u03b5\u03af\u03bc\u03b5\u03bd\u03bf (subject) SAML", "zu": "Isihloko Se-SAML", "xh": "Umbandela we-SAML", "st": "Taba ya SAML", "ca": "Assumpte SAML" }, "subject_notset": { "es": "sin valor", "ru": "\u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d", "zh-tw": "\u672a\u8a2d\u5b9a", "nl": "niet aanwezig", "da": "ikke angivet", "el": "\u03b4\u03b5\u03bd \u03ad\u03c7\u03b5\u03b9 \u03bf\u03c1\u03b9\u03c3\u03c4\u03b5\u03af", "xh": "ayikasetwa", "zu": "akusethiwe", "st": "ha e a setwa", "ca": "no establert" }, "subject_format": { "es": "Formato", "ru": "\u0424\u043e\u0440\u043c\u0430\u0442", "zh-tw": "\u683c\u5f0f", "nl": "Formaat", "da": "Format", "el": "\u039c\u03bf\u03c1\u03c6\u03ae (format)", "zu": "Ifomethi", "xh": "Ufomatho", "st": "Fomata", "ca": "Format" }, "authData_header": { "xh": "Ungqinisiso lweNgcombolo", "zu": "I-AuthData", "st": "AuthData", "ca": "AuthData" }, "authData_summary": { "xh": "Cofa ukuze ubone uNgqinisiso lweNgcombolo", "zu": "Qhafaza ukuze ubuke i-AuthData", "st": "Tlelika ho sheba AuthData", "ca": "Feu clic per veure AuthData" } } simplesamlphp-1.19.1/dictionaries/general.definition.json0000644000000000000000000000042614042503475022301 0ustar rootroot{ "yes": { "en": "Yes, continue" }, "no": { "en": "No, cancel" }, "remember": { "en": "Remember" }, "yes_continue": { "en": "Yes, continue" }, "no_cancel": { "en": "No, cancel" }, "service_provider": { "en": "Service Provider" } }simplesamlphp-1.19.1/dictionaries/disco.translation.json0000644000000000000000000003431514042503475022177 0ustar rootroot{ "selectidp": { "no": "Velg din identitetsleverand\u00f8r", "nn": "Vel innloggingsteneste", "sv": "V\u00e4lj din identitetsleverant\u00f6r", "es": "Seleccione su proveedor de identidad", "fr": "S\u00e9lectionnez votre fournisseur d'identit\u00e9", "de": "W\u00e4hlen Sie Ihren Identity Provider", "nl": "Kies je Identity Provider", "sl": "Izberite IdP doma\u010de organizacije", "da": "V\u00e6lg institution (identitetsudbyder)", "hr": "Odaberite autentifikacijski servis", "hu": "V\u00e1lasszon szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3t (IdP)", "fi": "Valitse identiteettill\u00e4hteesi", "pt-br": "Selecione seu provedor de identidade", "pt": "Escolha o seu fornecedor de identidade (IdP)", "pl": "wybierz swojego Dostawc\u0119 To\u017csamo\u015bci.", "cs": "Zvol sv\u00e9ho poskytovatele identity (IdP)", "eu": "Hauta ezazu zure identitate hornitzailea", "tr": "Kimlik sa\u011flay\u0131c\u0131n\u0131z\u0131 se\u00e7iniz.", "lt": "Pasirinkite savo tapatybi\u0173 tiek\u0117j\u0105", "it": "Selezionare il proprio identity provider", "ja": "\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044", "zh-tw": "\u9078\u64c7\u4f60\u7684\u8b58\u5225\u63d0\u4f9b\u8005 (IdP)", "ru": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0430\u0448\u0435\u0433\u043e identity provider", "et": "Vali oma identiteedipakkuja", "he": "\u05d1\u05d7\u05e8 \u05d0\u05ea \u05e1\u05e4\u05e7 \u05d4\u05d6\u05d4\u05d5\u05ea \u05e9\u05dc\u05da", "zh": "\u9009\u62e9\u4f60\u7684\u8eab\u4efd\u63d0\u4f9b\u8005", "ar": "\u0627\u062e\u062a\u0627\u0631 \u0645\u0648\u0642\u0639 \u0647\u0648\u064a\u062a\u0643", "id": "Pilih identity provider anda", "lv": "Izv\u0113lieties identit\u0101tes pieg\u0101d\u0101t\u0101ju", "sr": "Odaberite va\u0161eg davaoca identiteta", "ro": "Alege\u021bi furnizorul de identitate", "af": "Kies jou identiteits verskaffer", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03c6\u03bf\u03c1\u03ad\u03b1", "xh": "Khetha umboneleli wesazisi wakho", "zu": "Khetha umhlinzeki wakho kamazisi", "st": "Kgetha mofani wa boitsebiso wa hao", "ca": "Seleccioneu el vostre proveïdor d'identitat" }, "selectidp_full": { "no": "Vennligst velg hvilken identitetsleverand\u00f8r du vil bruke for \u00e5 logge inn:", "nn": "Vel innloggingsteneste (IdP) der du \u00f8nskjer \u00e5 logga inn.", "sv": "V\u00e4lj vilken identitetsleverant\u00f6r du vill logga in med:", "es": "Por favor, seleccione el proveedor de identidad que desea usar para autenticarse", "fr": "S\u00e9lectionnez le fournisseur d'identit\u00e9 aupr\u00e8s duquel vous souhaitez vous authentifier :", "de": "Bitte w\u00e4hlen Sie den Identity Provider, bei dem Sie sich authentifizieren m\u00f6chten:", "nl": "Selecteer de Identity Provider waar je wil authenticeren:", "sl": "Izberite IdP, na katerem se boste avtenticirali:", "da": "V\u00e6lg institutionen (identitetsudbyderen) hvor du vil logge ind", "hr": "Molimo odaberite servis preko kojeg se \u017eelite autentificirati:", "hu": "K\u00e9rj\u00fck, v\u00e1lassza ki azt a szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3t (IdP), ahol azonos\u00edtani k\u00edv\u00e1nja mag\u00e1t:", "fi": "Valitse identiteettil\u00e4hteesi jossa haluat kirjautua", "pt-br": "Por favor selecione o provedor de identidade ao qual deseja se autenticar", "pt": "Por favor, escolha o fornecedor de identidade (IdP) que ir\u00e1 usar para se autenticar:", "pl": "Prosz\u0119 wybra\u0107 Dostawc\u0119 To\u017csamo\u015bci, przez kt\u00f3rego chcesz si\u0119 uwierzytelni\u0107:", "cs": "Pros\u00edm zvolte sve\u00e9ho poskytovatele identity, kter\u00fd v\u00e1m dovol\u00ed se p\u0159ihl\u00e1sit", "eu": "Mesedez, non kautotu nahi duzun identifikazio hornitzailea hauta ezazu ", "tr": "L\u00fctfen, kimlik do\u011frulamas\u0131 yapaca\u011f\u0131n\u0131z kimlik sa\u011flay\u0131c\u0131y\u0131 se\u00e7iniz: ", "lt": "Pra\u0161ome pasirinkite tapatybi\u0173 tiek\u0117j\u0105, kuriame norite autentikuotis:", "it": "Si prega di selezionare l'identity provider con il quale autenticarsi:", "ja": "\u8a8d\u8a3c\u3092\u884c\u3044\u305f\u3044\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044:", "zh-tw": "\u8acb\u9078\u64c7\u60a8\u6240\u8981\u524d\u5f80\u8a8d\u8b49\u7684\u9a57\u8b49\u63d0\u4f9b\u8005\uff1a", "ru": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 identity provider, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0439\u0442\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e:", "et": "Palun vali identiteedipakkuja, mille juures soovid autentida:", "he": "\u05d1\u05d7\u05e8 \u05d0\u05ea \u05e1\u05e4\u05e7 \u05d4\u05d6\u05d9\u05d4\u05d5\u05ea \u05d0\u05dc\u05d9\u05d5 \u05d0\u05ea\u05d4 \u05e8\u05d5\u05e6\u05d4 \u05dc\u05d4\u05d9\u05d6\u05d3\u05d4\u05d5\u05ea:", "zh": "\u9009\u62e9\u4f60\u8981\u8ba4\u8bc1\u7684\u8eab\u4efd\u63d0\u4f9b\u8005", "ar": "\u0627\u062e\u062a\u0631 \u0645\u0648\u0642\u0639 \u0627\u0644\u0647\u0648\u064a\u0629 \u0627\u0644\u0630\u064a \u062a\u0631\u063a\u0628 \u0628\u062f\u062e\u0648\u0644\u0647", "id": "Silahkan pilih identity provider tempat anda ingin melakukan autentifikasi", "lv": "L\u016bdzu izv\u0113lieties identit\u0101tes pieg\u0101d\u0101t\u0101ju, pie kura v\u0113laties autentific\u0113ties:", "sr": "Molimo vas odaberite davaoca identiteta kod koga se \u017eelite autentifikovati:", "ro": "V\u0103 rug\u0103m s\u0103 alege\u021bi furnizorul de identitate pe care dori\u021bi s\u0103-l folosi\u021bi pentru autentificarea dumneavoastr\u0103:", "af": "Kies asb. jou identiteits verskaffer waar jy wil verifieer:", "el": "\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03bf\u03b9\u03ba\u03b5\u03af\u03bf \u03c6\u03bf\u03c1\u03ad\u03b1 \u03c0\u03bf\u03c5 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03b9 \u03c4\u03b7\u03bd \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03ac \u03c3\u03b1\u03c2", "zu": "Sicela ukhethe umhlinzeki kamazisi lapho ofuna ukuqinisekisa khona:", "xh": "Nceda ukhethe umboneleli wesazisi apho ufuna ukungqinisisa:", "st": "Ka kopo kgetha mofani wa boitsebiso moo o batlang ho netefatsa:", "ca": "Seleccioneu el proveïdor d’identitat on vulgueu autenticar:" }, "select": { "no": "Velg", "nn": "Vel", "sv": "V\u00e4lj", "es": "Seleccione", "fr": "S\u00e9lectionner", "de": "Auswahl", "nl": "Kies", "sl": "Izberite", "da": "V\u00e6lg", "hr": "Odaberi", "hu": "V\u00e1laszt", "fi": "Valitse", "pt-br": "Selecione", "pt": "Escolher", "pl": "Wybierz", "cs": "Zvol", "eu": "Hautatu", "tr": "Se\u00e7", "lt": "Pasirinkite", "it": "Selezionare", "ja": "\u9078\u629e", "zh-tw": "\u9078\u64c7", "ru": "\u0412\u044b\u0431\u0440\u0430\u0442\u044c", "et": "Vali", "he": "\u05d1\u05d7\u05e8", "zh": "\u9009\u62e9", "ar": "\u0627\u062e\u062a\u0627\u0631", "id": "Pilih", "lv": "Izv\u0113l\u0113ties", "sr": "Odaberi", "ro": "Selecta\u021bi", "af": "Kies", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae", "zu": "Khetha", "xh": "Khetha", "st": "Kgetha", "ca": "Seleccioneu" }, "remember": { "no": "Husk mitt valg", "nn": "Hugs mitt val", "sv": "Kom ih\u00e5g mitt val", "es": "Recordar mi elecci\u00f3n", "fr": "Retenir ce choix", "de": "Meine Auswahl merken", "nl": "Onthoud mijn keuze", "sl": "Shrani kot privzeto izbiro", "da": "Husk valget", "hr": "Zapamti moj odabir", "hu": "Eml\u00e9kezzen erre", "fi": "Muista valintani", "pt-br": "Lembrar minha escolha", "pt": "Lembrar esta escolha", "pl": "Zapami\u0119taj m\u00f3j wyb\u00f3r", "cs": "Zapamatuj moji volbu", "eu": "Nire hautaketa gogoratu", "tr": "Se\u00e7imimi hat\u0131rla", "lt": "Prisiminti pasirinkim\u0105", "it": "Ricorda la mia scelta", "ja": "\u9078\u629e\u3092\u8a18\u61b6\u3059\u308b", "zh-tw": "\u8a18\u4f4f\u6211\u7684\u9078\u64c7", "ru": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043c\u043e\u0439 \u0432\u044b\u0431\u043e\u0440", "et": "J\u00e4ta valik meelde", "he": "\u05d6\u05db\u05d5\u05e8 \u05d0\u05ea \u05d4\u05d1\u05d7\u05d9\u05e8\u05d4 \u05e9\u05dc\u05d9", "zh": "\u8bb0\u4f4f\u6211\u7684\u9009\u62e9", "ar": "\u062a\u0630\u0643\u0631 \u062e\u064a\u0627\u0631\u0627\u062a\u064a", "id": "Ingat pilihan saya", "lv": "Atcer\u0113ties manu izv\u0113li", "sr": "Zapamti moj izbor", "ro": "Memoreaz\u0103 alegerea f\u0103cut\u0103", "af": "Onthou my keuse", "el": "\u039d\u03b1 \u03b8\u03c5\u03bc\u03ac\u03c3\u03b1\u03b9 \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bc\u03bf\u03cd", "zu": "Khumbula ukukhetha kwami", "xh": "Khumbula ukhetho lwam", "st": "Hopola kgetho ya ka", "ca": "Recorda la meva elecció" }, "icon_prefered_idp": { "no": "[Foretrukket valg]", "sv": "Prioriterat val", "es": "[Opci\u00f3n preferida]", "de": "[Bevorzugte Auswahl]", "nl": "[Voorkeurskeuze]", "sl": "Prioritetna izbira", "da": "Foretrukket valg", "hu": "[K\u00edv\u00e1nt v\u00e1laszt\u00e1s]", "fi": "[Oletusvalinta]", "pt": "Escolha preferida", "pl": "Preferowany wyb\u00f3r", "tr": "[Tercih edilen se\u00e7enek]", "fr": "[Choix pr\u00e9f\u00e9r\u00e9]", "hr": "[Primarni odabir]", "nn": "Beste val", "lt": "[Rekomenduojame]", "it": "[Scelta preferita]", "ja": "[\u63a8\u5968\u3059\u308b\u9078\u629e]", "zh-tw": "[\u559c\u597d\u9078\u9805]", "ru": "[\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440]", "et": "[Eelistatud valik]", "he": "[\u05d1\u05d7\u05d9\u05e8\u05d4 \u05de\u05e2\u05d5\u05d3\u05e4\u05ea]", "pt-br": "[Op\u00e7\u00e3o preferida]", "zh": "\u9996\u9009\u9009\u9879", "ar": "\u0627\u062e\u062a\u064a\u0627\u0631\u064a \u0627\u0644\u0645\u0641\u0636\u0644", "id": "Pilihan yang disukai", "lv": "(Mana lab\u0101k\u0101 izv\u0113le)", "sr": "[Preferirani izbor]", "ro": "[Varianta preferat\u0103]", "cs": "[Preferovan\u00e1 volba]", "eu": "[Aukera gogokoena]", "af": "[Verkies]", "el": "[\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b7 \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae]", "xh": "[Ukhetho olukhethwayo]", "zu": "[Ukukhetha okuncanyelwayo]", "st": "[Kgetho e kgethwang]", "ca": "[Opció preferida]" }, "previous_auth": { "no": "Du har tidligere valg \u00e5 autentisere deg hos", "sv": "Du har tidigare valt att logga in med", "es": "Previamente eligi\u00f3 autenticarse con", "nl": "Je hebt eerder gekozen voor authenticatie bij", "sl": "Predhodnje ste se prijavljali \u017ee pri", "da": "Du har tidligere valgt at logge ind hos", "de": "Sie haben sich zu einem fr\u00fcheren Zeitpunkt entschieden, sich zu authentifizieren bei ", "fi": "Olet aikaisemmin valinnut identiteettil\u00e4hteeksesi", "pt": "Escolheu autenticar-se anteriormente em", "fr": "Pr\u00e9c\u00e9demment, vous aviez choisi de vous authentifier sur", "hr": "Prethodno ste odabrali autentifikaciju kroz", "nn": "Du har tidlegare logga inn ved", "lt": "Anks\u010diau pasirinkote autentikuotis", "it": "Precedentemente si \u00e8 scelto di autenticarsi con", "hu": "Kor\u00e1bban ezt a szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3t (IdP) v\u00e1lasztotta: ", "ja": "\u524d\u56de\u9078\u629e\u3057\u305f\u8a8d\u8a3c: ", "zh-tw": "\u60a8\u5148\u524d\u5df2\u9078\u64c7\u8a8d\u8b49\u65bc", "pl": "Poprzednio wybra\u0142e\u015b", "ru": "\u0412\u044b \u0443\u0436\u0435 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432", "et": "Varem oled valinud autentida, kasutades", "he": "\u05d1\u05e2\u05d1\u05e8 \u05d1\u05d7\u05e8\u05ea \u05dc\u05d4\u05d6\u05d3\u05d4\u05d5\u05ea \u05d1-", "pt-br": "Voc\u00ea j\u00e1 escolheu para autenticar a", "zh": "\u4f60\u5148\u524d\u9009\u62e9\u7684\u8ba4\u8bc1", "ar": "\u0642\u0645\u062a \u0633\u0627\u0628\u0642\u0627 \u0628\u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0641\u064a", "id": "Sebelumnya anda telah memilih untuk melakukan autentifikasi di ", "lv": "Iepriek\u0161 J\u016bs autentific\u0113j\u0101ties pie", "sr": "Prethodno ste izabrali da se autentifikujete kroz", "ro": "Anterior a\u021bi ales s\u0103 v\u0103 autentifica\u021bi la", "cs": "D\u0159\u00edve jste zvolil(a) ov\u011b\u0159en\u00ed u", "eu": "Lehenago, hemen kautotzea hautatu duzu", "af": "Jy het voorheen gekies om te verifieer deur:", "el": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b7 \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03c6\u03bf\u03c1\u03ad\u03b1:", "zu": "Ngaphambilini ukhethe ukuqinisekisa kokuthi", "xh": "Kwixesha elidlulileyo ukhethe ukungqinisisa ngo-", "st": "O qadile ka ho kgetha netefatso ho", "ca": "Abans heu escollit autenticar-vos a" }, "login_at": { "no": "Logg inn hos", "sv": "Logga in med", "es": "Iniciar sesi\u00f3n en", "nl": "Inloggen bij", "sl": "Prijavi se pri", "da": "Login hos", "de": "Login bei", "fi": "Kirjaudu", "pt": "Entrar em", "fr": "S'authentifier sur", "hr": "Prijavi se kroz", "nn": "Logg inn ved", "lt": "Prisijungti prie", "it": "Effettua il login con", "hu": "Bel\u00e9p\u00e9s ide:", "ja": "\u30ed\u30b0\u30a4\u30f3: ", "zh-tw": "\u767b\u5165\u81f3", "pl": "Zaloguj w", "ru": "\u0412\u043e\u0439\u0442\u0438 \u0432", "et": "Logi sisse", "he": "\u05db\u05e0\u05e1 \u05dc-", "pt-br": "Logado como", "zh": "\u767b\u5f55\u4e8e", "ar": "\u0633\u062c\u0644 \u062f\u062e\u0648\u0644\u064a \u0639\u0644\u064a", "id": "Login di", "lv": "Piesl\u0113gties pie", "sr": "Prijavi se kroz", "ro": "Autentificare la", "cs": "P\u0159ihl\u00e1\u0161en\u00ed k", "eu": "Non identifikatu", "af": "Meld aan by", "el": "\u0395\u03af\u03c3\u03bf\u03b4\u03bf\u03c2 \u0040", "zu": "Ngena kokuthi", "xh": "Ungeno ngo-", "st": "Kena ho", "ca": "Inicieu sessió a" } } simplesamlphp-1.19.1/dictionaries/logout.translation.json0000644000000000000000000014435014042503475022410 0ustar rootroot{ "title": { "no": "Utlogget", "nn": "Utlogga", "sv": "Utloggad", "es": "Sesión cerrada", "fr": "D\u00e9connect\u00e9", "de": "Abgemeldet", "nl": "Uitgelogd", "sl": "Odjavljen", "da": "Du er logget ud", "hr": "Odjavljeni ste", "hu": "Sikeres kil\u00e9p\u00e9s", "fi": "Uloskirjautunut", "pt-br": "Desconectado", "pt": "Sa\u00edda efectuada com sucesso", "pl": "Wylogowano", "cs": "Odhl\u00e1\u0161en", "eu": "Saioa itxita.", "tr": "\u00c7\u0131kt\u0131n\u0131z", "it": "Disconnesso", "lt": "Atsijungta", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8", "zh-tw": "\u767b\u51fa", "et": "Logis v\u00e4lja", "he": "\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05de\u05d4\u05de\u05e2\u05e8\u05db\u05ea", "zh": "\u9000\u51fa", "ar": "\u062e\u0631\u0648\u062c", "lv": "Atsl\u0113dzies", "id": "Log out", "sr": "Odjavljeni ste", "ro": "Ie\u0219ire din sistem (deautentificare)", "ru": "\u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0432\u044b\u0445\u043e\u0434", "af": "Afgemeld", "el": "\u0391\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2/\u03b7", "xh": "Uphumile", "zu": "Uphume ngemvume", "st": "O ntshitswe", "ca": "Desconnectat" }, "logged_out_text": { "no": "Du er n\u00e5 utlogget.", "nn": "Du har blitt logga ut. Takk for at du brukte denne tenesta.", "sv": "Du har blivit uloggad. Tack f\u00f6r att du anv\u00e4nde denna tj\u00e4nst.", "es": "Se ha cerrado la sesión.", "fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9. Merci d'avoir utilis\u00e9 ce service.", "de": "Sie wurden abgemeldet. Danke, dass Sie diesen Dienst verwendet haben.", "nl": "U bent uitgelogd. Dank u voor het gebruiken van deze dienst.", "sl": "Odjava je bila uspe\u0161na. Hvala, ker uporabljate to storitev.", "da": "Du er blevet logget ud. Tak for fordi du brugte denne tjeneste.", "hr": "Uspje\u0161no ste se odjavili.", "hu": "Sikeresen kijelentkezett. K\u00f6sz\u00f6nj\u00fck, hogy haszn\u00e1lta a szolg\u00e1ltat\u00e1st.", "fi": "Olet kirjautunut ulos", "pt-br": "Voc\u00ea foi desconectado.", "pt": "Sa\u00edda efectuada com sucesso. Obrigado por ter usado este servi\u00e7o.", "pl": "Zosta\u0142e\u015b wylogowany. Dzi\u0119kuj\u0119 za skorzystanie z serwisu.", "cs": "Jste odhl\u00e1\u0161en. D\u011bkujeme za pou\u017eit\u00ed t\u00e9to slu\u017eby.", "eu": "Saioa itxi da.", "tr": "\u00c7\u0131kt\u0131n\u0131z", "it": "Sei stato disconnesso", "lt": "J\u016bs buvote atjungtas nuo sistemos.", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u60a8\u5df2\u767b\u51fa\u3002", "et": "Sa oled v\u00e4lja logitud.", "he": "\u05d4\u05ea\u05e0\u05ea\u05e7\u05ea \u05de\u05df \u05d4\u05de\u05e2\u05e8\u05db\u05ea", "zh": "\u4f60\u5df2\u7ecf\u9000\u51fa\u4e86", "ar": "\u0644\u0642\u062f\u062e\u0631\u0648\u062c \u0644\u0642\u062f \u0642\u0645\u062a \u0628\u0627\u0644\u062e\u0631\u0648\u062c", "lv": "J\u016bs esat izg\u0101jis no sist\u0113mas.", "id": "Anda telah log out.", "sr": "Uspe\u0161no ste se odjavili.", "ro": "A\u021bi fost deautentificat", "ru": "\u0412\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "af": "Jy is afgemeld.", "el": "\u0388\u03c7\u03b5\u03c4\u03b5 \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af.", "zu": "Usuphumile.", "xh": "Uphumile.", "st": "O ntshitswe.", "ca": "Us heu desconnectat." }, "default_link_text": { "no": "G\u00e5 tilbake til SimpleSAMLphp installasjonen sin startside.", "nn": "G\u00e5 tilbake til SimpleSAMLphp installasjonssida", "sv": "\u00c5ter till installationssidan f\u00f6r SimpleSAMLphp", "es": "Volver a la p\u00e1gina de instalaci\u00f3n de SimpleSAMLphp", "fr": "Retournez \u00e0 la page d'installation de SimpleSAML.", "de": "Zur\u00fcck zur SimpleSAMLphp Installationsseite", "nl": "Ga terug naar de SimpleSAMLphp installatiepagina", "sl": "Nazaj na namestitveno stran SimpleSAMLphp", "da": "Tilbage til SimpleSAMLphp installationssiden", "hr": "Natrag na po\u010detnu stranicu SimpleSAMLphp instalacije", "hu": "Vissza a SimpleSAMLphp telep\u00edt\u0151 oldal\u00e1ra", "fi": "Palaa SimpleSAMLphp asennussivulle", "pt-br": "Voltar a instala\u00e7\u00e3o do SimpleSAMLphp", "pt": "Voltar \u00e0 p\u00e1gina de instala\u00e7\u00e3o do SimpleSAMLphp", "pl": "Wr\u00f3c do strony \"instalacja SimpleSAMLphp\"", "cs": "Zp\u00e1tky na SimpleSAMLphp instala\u010dn\u00ed str\u00e1nku", "tr": "SimpleSAMLphp kurulum sayfas\u0131na geri d\u00f6n", "it": "Torna alla pagine di installazione di SimpleSAMLphp", "lt": "Gr\u012f\u017eti atgal \u012f SimpleSAMLphp diegimo puslap\u012f", "ja": "SimpleSAMLphp\u306e\u8a2d\u5b9a\u30da\u30fc\u30b8\u306b\u623b\u308b", "zh-tw": "\u56de\u5230 SimpleSAMLphp \u5b89\u88dd\u9801\u9762", "et": "Mine tagasi SimpleSAMLphp paigalduslehek\u00fcljele", "he": "\u05d7\u05d6\u05d5\u05e8 \u05dc\u05d3\u05e3 \u05d4\u05d4\u05ea\u05e7\u05e0\u05d4 \u05e9\u05dc SimpleSAMLphp", "zh": "\u8fd4\u56deSimpleSAMLphp\u5b89\u88c5\u9875\u9762", "ar": "\u0639\u062f \u0644\u0635\u0641\u062d\u0629 \u0625\u0646\u0632\u0627\u0644 SimpleSAMLphp", "lv": "Iet atpaka\u013c uz SimpleSAMLphp instal\u0101cijas lapu", "id": "Kembali ke halaman instalasi SimpleSAMLphp", "sr": "Natrag na po\u010detnu stranicu SimpleSAMLphp instalacije", "ro": "Merge\u021bi \u00eenapoi la pagina de instalare a SimpleSAMLphp", "ru": "\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 SimpleSAMLphp", "eu": "Itzuli SimpleSAMLphp instalazio orrira ", "af": "Gaan terug na die SimpleSAMLphp installasie bladsy", "el": "\u0395\u03c0\u03b9\u03c3\u03c4\u03c1\u03bf\u03c6\u03ae \u03c3\u03c4\u03b7\u03bd \u03b1\u03c1\u03c7\u03b9\u03ba\u03ae \u03c3\u03b5\u03bb\u03af\u03b4\u03b1", "xh": "Buyela emva kwikhasi lofakelo le-SimpleSAMLphp", "zu": "Buyela emuva ekhasini lokufaka le-SimpleSAMLphp", "st": "Kgutlela leqepheng la ho instola la SimpleSAMLphp", "ca": "Torneu a la pàgina d’instal·lació de SimpleSAMLphp" }, "hold": { "no": "P\u00e5 vent", "nn": "Venter", "sv": "Vilande", "es": "En espera", "fr": "En cours", "nl": "Vastgehouden", "sl": "V teku", "da": "I k\u00f8", "hr": "Na \u010dekanju", "hu": "Felf\u00fcggesztve", "pt": "Em espera", "pl": "W zawieszeniu", "cs": "\u010cek\u00e1m", "tr": "Beklemede", "de": "In der Wartschleife", "fi": "Odota", "lt": "Pra\u0161ome palaukti", "it": "In attesa", "ja": "\u4fdd\u7559", "zh-tw": "\u4fdd\u7559", "et": "Ootel", "he": "\u05d1\u05d4\u05e9\u05e2\u05d9\u05d9\u05d4", "pt-br": "Aguardando", "zh": "\u4fdd\u6301", "ar": "\u0628\u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 ", "lv": "Aptur\u0113ts", "id": "Ditahan", "sr": "Na \u010dekanju", "ro": "\u00cen a\u0219teptare", "ru": "\u0412 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f", "eu": "Itxaroten", "af": "Hou die verbinding", "el": "\u03a3\u03b5 \u03b1\u03bd\u03b1\u03bc\u03bf\u03bd\u03ae", "xh": "Ibanjiwe", "zu": "Imisiwe", "st": "Tshwarisitswe", "ca": "En espera" }, "completed": { "no": "Fullf\u00f8rt", "nn": "Ferdig", "sv": "Klar", "es": "Terminado", "fr": "Fait", "de": "abgeschlossen", "nl": "Voltooid", "sl": "Dokon\u010dano", "da": "F\u00e6rdig", "hr": "Zavr\u0161eno", "hu": "Befejezve", "fi": "Valmis", "pt": "Completa", "pl": "Zako\u0144czono", "cs": "Dokon\u010deno", "tr": "Tamamland\u0131", "lt": "Atlikta", "it": "Completato", "ja": "\u5b8c\u4e86\u3057\u307e\u3057\u305f", "zh-tw": "\u5b8c\u6210", "et": "L\u00f5petatud", "he": "\u05d4\u05e1\u05ea\u05d9\u05d9\u05dd", "pt-br": "Completado", "zh": "\u5b8c\u6210", "ar": "\u0627\u0643\u062a\u0645\u0644", "lv": "Pabeigts", "id": "Selesai", "sr": "Zavr\u0161eno", "ro": "Terminat", "ru": "\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e", "eu": "Amaitua", "af": "Voltooid", "el": "\u039f\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5", "xh": "Igqityiwe", "zu": "Kuqedile", "st": "E phethilwe", "ca": "Completat" }, "progress": { "no": "Logger ut...", "nn": "Loggar ut...", "sv": "Loggar ut...", "es": "Cerrando la sesi\u00f3n...", "fr": "D\u00e9connexion...", "de": "Abmeldung l\u00e4uft...", "nl": "Uitloggen...", "sl": "Odjavljanje...", "da": "Logger ud...", "hr": "Odjava u tijeku...", "hu": "Kijelentkez\u00e9s...", "fi": "Kirjautuu ulos...", "pt": "A sair...", "pl": "Wylogowywanie...", "cs": "Odhla\u0161uji...", "eu": "Saioa ixten...", "tr": "\u00c7\u0131k\u0131yor", "lt": "Atjungiama...", "it": "Disconnessione...", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u4e2d\u2026", "zh-tw": "\u767b\u51fa\u4e2d...", "et": "V\u00e4lja logimine...", "he": "\u05de\u05ea\u05e0\u05ea\u05e7 \u05de\u05d4\u05de\u05e2\u05e8\u05db\u05ea...", "pt-br": "Saindo do servi\u00e7o...", "zh": "\u6b63\u5728\u9000\u51fa", "ar": "\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c", "lv": "Atsl\u0113g\u0161an\u0101s...", "id": "Log out...", "sr": "Odjava u toku...", "ro": "Deautentificare ...", "ru": "\u0412\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b...", "af": "Besig om af te meld?", "el": "\u0393\u03af\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7...", "zu": "Iyaphuma...", "xh": "Iyaphuma...", "st": "E a tswa...", "ca": "Tancant la sessió..." }, "failed": { "no": "Utlogging feilet", "nn": "Utlogging feila", "sv": "Utloggning misslyckades", "es": "El cierre de sesi\u00f3n ha fallado", "fr": "\u00c9chec de la d\u00e9connexion", "de": "Abmeldung fehlgeschlagen", "nl": "Uitloggen mislukt", "sl": "Odjava je spodletela.", "da": "Logout fejlede", "hr": "Odjava nije uspjela", "hu": "Kijelentkez\u00e9s nem siker\u00fclt", "fi": "Uloskirjautuminen ep\u00e4onnistunut", "pt": "Sa\u00edda falhada", "pl": "Wyst\u0105pi\u0142 b\u0142ad podczas wylogowania", "cs": "Odhla\u0161en\u00ed selhalo", "tr": "\u00c7\u0131k\u0131\u015f ba\u015far\u0131lamad\u0131", "lt": "Atsijungimas nepavyko", "it": "Disconnessione fallita", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u306b\u5931\u6557\u3057\u307e\u3057\u305f", "zh-tw": "\u767b\u51fa\u5931\u6557", "et": "V\u00e4lja logimine eba\u00f5nnestus", "he": "\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4", "pt-br": "Falha ao sair do servi\u00e7o", "zh": "\u9000\u51fa\u5931\u8d25", "ar": "\u062a\u0633\u062c\u064a\u0644 \u062e\u0631\u0648\u062c \u0641\u0627\u0634\u0644", "lv": "Atsl\u0113g\u0161an\u0101s neizdev\u0101s", "id": "Log out gagal", "sr": "Odjava nije uspela", "ro": "Deautentificarea a e\u0219uat", "ru": "\u0412\u044b\u0445\u043e\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e", "eu": "Saioa ixteko prozesuak huts egin du", "af": "Afmelding misluk", "el": "\u0397 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5", "xh": "Ukuphuma kusilele", "zu": "Ukuphuma kuhlulekile", "st": "Ho tswa ho hlolehile", "ca": "Ha fallat el tancament de sessió" }, "return": { "no": "Tilbake til tjenesten", "nn": "G\u00e5 tilbake til tenesta", "sv": "\u00c5ter till tj\u00e4nsten", "es": "Volver al servicio", "fr": "Retour au service", "de": "Zum Dienst zur\u00fcckkehren", "nl": "Terug naar service", "sl": "Vrni se nazaj na storitev.", "da": "Tilbage til service", "hr": "Povratak u aplikaciju", "hu": "Vissza a szolg\u00e1ltat\u00e1shoz", "fi": "Palaa palveluun", "pt": "Regressar ao servi\u00e7o", "pl": "Powr\u00f3t do serwisu", "cs": "Zp\u00e1tky na slu\u017ebu", "eu": "Itzuli zerbitzura", "tr": "Servise geri d\u00f6n", "lt": "Gr\u012f\u017eti \u012f paslaug\u0105", "it": "Ritornare al servizio", "ja": "\u30b5\u30fc\u30d3\u30b9\u3078\u623b\u308b", "zh-tw": "\u56de\u5230\u670d\u52d9", "et": "Tagasi teenuse juurde", "he": "\u05d7\u05d6\u05e8\u05d4 \u05dc\u05e9\u05e8\u05d5\u05ea", "pt-br": "Retornar ao servi\u00e7o", "zh": "\u8fd4\u56de\u81f3\u670d\u52a1", "ar": "\u0639\u062f \u0644\u0644\u062e\u062f\u0645\u0629", "lv": "Atgriezties pie servisa", "id": "Kembali ke layanan", "sr": "Povratak u aplikaciju", "ro": "\u00centoarcere la serviciu", "ru": "\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043b\u0443\u0436\u0431\u0435", "af": "Terug na diens", "el": "\u0395\u03c0\u03b9\u03c3\u03c4\u03c1\u03bf\u03c6\u03ae \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1", "xh": "Buyela kwinkonzo", "zu": "Buyela kusevisi", "st": "E kgutlela tshebeletsong", "ca": "Tornar al servei" }, "success": { "no": "Du har nå logget ut fra alle tjenestene listet ovenfor.", "nn": "Du er ferdig utlogga fr\u00e5 alle tenestene", "sv": "Du har loggat ut fr\u00e5n alla nedanst\u00e5ende tj\u00e4nster.", "es": "Ha cerrado las sesiones de todos los servicios listados m\u00e1s arriba", "fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9 avec succ\u00e8s des services list\u00e9s ci dessus", "de": "Sie haben sich erfolgreich von allen obenstehenden Diensten abgemeldet.", "nl": "Je bent succesvol uitgelogd van de bovenvermelde services.", "sl": "Uspe\u0161no ste se odjavili z vseh na\u0161tetih storitev.", "da": "Du har logget ud fra alle overn\u00e6vnte services. ", "hr": "Uspje\u0161no ste se odjavili iz svih gore navedenih servisa.", "hu": "Sikeresen kijelentkezett az fent felsorolt \u00f6sszes alkalmaz\u00e1sb\u00f3l.", "fi": "Olet onnistuneesti kirjautunut ulos kaikista yll\u00e4 listatuista palveluista.", "pt": "Saiu com sucesso de todos os servi\u00e7os listados em cima.", "pl": "Zosta\u0142e\u015b pomy\u015blnie wylogowany ze wszystkich powy\u017cszych serwis\u00f3w.", "cs": "\u00dasp\u011b\u0161n\u011b jste se odhl\u00e1sili z n\u00e1sleduj\u00edc\u00edch slu\u017eeb.", "tr": "Yukar\u0131da listelenen t\u00fcm servislerden ba\u015far\u0131yla \u00e7\u0131kt\u0131n\u0131z.", "lt": "J\u016bs s\u0117kmingai buvote atjungtas nuo vis\u0173 \u017eemiau i\u0161vardint\u0173 paslaug\u0173.", "it": "Sei stato disconnesso da tutti i servizi sopra elencati.", "ja": "\u4e0a\u8a18\u306e\u5168\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u60a8\u5df2\u7d93\u6210\u529f\u767b\u51fa\u4e86\u5217\u8868\u4e2d\u6240\u6709\u670d\u52d9\u3002", "et": "Sa oled k\u00f5igist \u00fclal loetletud teenustest edukalt v\u00e4lja logitud.", "he": "\u05d4\u05ea\u05e0\u05ea\u05e7\u05ea \u05d1\u05d4\u05e6\u05dc\u05d7\u05d4 \u05de\u05db\u05dc \u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd \u05d4\u05db\u05ea\u05d5\u05d1\u05d9\u05dd \u05dc\u05de\u05e2\u05dc\u05d4", "pt-br": "Voc\u00ea saiu com sucesso de todos os servi\u00e7os listados acima.", "zh": "\u4f60\u6210\u529f\u7684\u9000\u51fa\u4e86\u4e0a\u9762\u5217\u8868\u4e2d\u7684\u670d\u52a1", "ar": "\u062a\u0633\u062c\u064a\u0644 \u062e\u0631\u0648\u062c \u0646\u0627\u062c\u062d \u0645\u0646 \u062c\u0645\u064a\u0639 \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0623\u0639\u0644\u0627\u0647 ", "lv": "J\u016bs esat sekm\u012bgi atsl\u0113dzies un augst\u0101k uzskait\u012btajiem servisiem.", "id": "Anda telah berhasil log out dari semua layanan yang tercantuh diatas.", "sr": "Uspe\u0161no ste se odjavili iz svih gore navedenih servisa.", "ro": "A\u021bi fost deautentificat de la toate serviciile enumerate mai sus.", "ru": "\u0412\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0441\u043b\u0443\u0436\u0431 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435.", "eu": "Hemen adierazten den zerrendako zerbitzu guztietako saioak zuzen itxi dira", "af": "Jy het suksesvol afgemeld.", "el": "\u0388\u03c7\u03b5\u03c4\u03b5 \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af \u03bc\u03b5 \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1 \u03b1\u03c0\u03cc \u03cc\u03bb\u03b5\u03c2 \u03c4\u03b9\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2 \u03c0\u03bf\u03c5 \u03b1\u03bd\u03b1\u03c6\u03ad\u03c1\u03bf\u03bd\u03c4\u03b1\u03b9 \u03c0\u03b1\u03c1\u03b1\u03c0\u03ac\u03bd\u03c9.", "xh": "Uphume ngokuyimpumelelo kuzo zonke iinkonzo ezidweliswe ngasentla.", "zu": "Uphume ngempumelelo kuwo wonke amasevisi abhalwe ngenhla.", "st": "O tswile ka katleho ditshebeletsong tsohle tse thathamisitsweng ka hodimo mona.", "ca": "Heu sortit correctament de tots els serveis esmentats anteriorment." }, "loggedoutfrom": { "no": "Du er n\u00e5 logget ut fra %SP%.", "nn": "Du er ferdig utlogga fr\u00e5 %SP%.", "sv": "Du har nu loggat ut fr\u00e5n %SP%.", "es": "Ha cerrado correctamente la sesión en %SP%.", "fr": "Vous avez \u00e9t\u00e9 d\u00e9connect\u00e9 de %SP%.", "de": "Sie wurden nun erfolgreich von %SP% abgemeldet", "nl": "Je bent nu succesvol uitgelogd van %SP%.", "sl": "Uspe\u0161no ste se odjavili s ponudnika storitev: %SP%", "da": "Du er nu logget ud fra %SP%.", "hu": "Sikeresen kil\u00e9pett a(z) %SP% szolg\u00e1ltat\u00e1sb\u00f3l", "fi": "Olet kirjautunut ulos palvelusta %SP%.", "pt": "Saiu com sucesso de %SP%.", "pl": "Zosta\u0142e\u015b pomy\u015blnie wylogowany z %SP%.", "cs": "Zah\u00e1jil jste glob\u00e1ln\u00ed odhl\u00e1\u0161en\u00ed<\/strong> z slu\u017eby %REQUESTERNAME%<\/strong>. Glob\u00e1ln\u00ed odhl\u00e1\u0161en\u00ed znamen\u00e1, \u017ee budete odhl\u00e1\u0161en z v\u0161ech n\u00e1sleduj\u00edc\u00ed slu\u017eeb.", "tr": "%SP%'den ba\u015far\u0131yla \u00e7\u0131kt\u0131n\u0131z.", "it": "Adesso sei correttamente disconnesso da %SP%", "hr": "Uspje\u0161no ste odjavljeni iz %SP%.", "lt": "J\u016bs s\u0117kmingai buvote atjungtas i\u0161 %SP%.", "ja": "\u3042\u306a\u305f\u306f %SP% \u304b\u3089\u306e\u30ed\u30b0\u30a2\u30a6\u30c8\u306b\u6210\u529f\u3057\u307e\u3057\u305f\u3002", "zh-tw": "\u60a8\u5df2\u6210\u529f\u5f9e %SP% \u767b\u51fa\u3002", "et": "Sa oled n\u00fc\u00fcd edukalt v\u00e4lja logitud teenusest %SP%.", "he": "%SP%-\u05e0\u05d5\u05ea\u05e7\u05ea \u05d1\u05d4\u05e6\u05dc\u05d7\u05d4 \u05de", "pt-br": "Voc\u00ea est\u00e1 saiu com sucesso de %SP%.", "zh": "\u4f60\u5df2\u6210\u529f\u4ece%SP%\u9000\u51fa", "ar": "\u0644\u0642\u062f \u062e\u0631\u062c\u062a \u0628\u0646\u062c\u0627\u062d \u0645\u0646 %SP%", "lv": "J\u016bs esat sekm\u012bgi atsl\u0113dzies no %SP%.", "id": "Sekarang anda telah sukses log out dari %SP%.", "sr": "Uspe\u0161no ste odjavljeni iz %SP%.", "ro": "A\u021bi fost deautentificat din %SP%.", "ru": "\u0412\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u0441\u043b\u0443\u0436\u0431\u044b %SP%.", "eu": "%SP% saioa zuzen itxi da.", "af": "Jy is suksesvol afgemeld van %SP% af.", "el": "\u0388\u03c7\u03b5\u03c4\u03b5 \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af \u03bc\u03b5 \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1 \u03b1\u03c0\u03cc \u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 %SP%.", "xh": "Ngoku uphume ngokuyimpumelelo kwi-%SP%.", "zu": "Usuphume ngempumelelo kokuthi %SP%.", "st": "Jwale o ntshitswe ka katleho ho %SP%.", "ca": "S’ha tancat la sessió amb èxit de %SP%." }, "also_from": { "no": "Du er ogs\u00e5 logget inn p\u00e5 disse tjenestene:", "nn": "Du er i tillegg logga inn p\u00e5 desse tenestene:", "sv": "Du \u00e4r \u00e4ven inloggad i f\u00f6ljande tj\u00e4nster:", "es": "Tambi\u00e9n est\u00e1 autenticado en los siguientes servicios:", "fr": "Vous \u00eates actuellement connect\u00e9 aux services suivants:", "de": "Sie sind auch auf diesen Diensten angemeldet:", "nl": "Je bent ook ingelogd bij deze diensten:", "sl": "Prijavljeni ste v naslednje storitve:", "da": "Du er ogs\u00e5 logget ud fra disse services:", "hu": "Ezen alkalmaz\u00e1sokban van m\u00e9g bejelentkezve:", "fi": "Olet kirjautunut seuraaviin palveluihin:", "pt": "Est\u00e1 tamb\u00e9m autenticado nos seguintes servi\u00e7os:", "pl": "Jeste\u015b tak\u017ce zalogowany w nastepuj\u0105cych serwisach:", "cs": "Jste je\u0161te p\u0159ihl\u00e1\u0161en na tyto slu\u017eby:", "tr": "Ayr\u0131ca \u015fu servislere giri\u015f yapt\u0131n\u0131z:", "it": "Attualmente sei anche connesso ai seguenti servizi:", "hr": "Tako\u0111er ste prijavljeni u sljede\u0107im servisima:", "lt": "J\u016bs taip pat esate prisijung\u0119s prie:", "ja": "\u3042\u306a\u305f\u306f\u307e\u3060\u3053\u308c\u3089\u306e\u30b5\u30fc\u30d3\u30b9\u306b\u30ed\u30b0\u30a4\u30f3\u3057\u3066\u3044\u307e\u3059:", "zh-tw": "\u60a8\u540c\u6642\u4e5f\u767b\u5165\u4e86\u9019\u4e9b\u670d\u52d9\uff1a", "et": "Sa oled sisse logitud ja nendesse teenustesse:", "he": "\u05d0\u05ea\u05d4 \u05de\u05d7\u05d5\u05d1\u05e8 \u05d2\u05dd \u05dc\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd \u05d4\u05d1\u05d0\u05d9\u05dd:", "pt-br": "Voc\u00ea tamb\u00e9m est\u00e1 logado nestes servi\u00e7os:", "zh": "\u4f60\u540c\u65f6\u767b\u5f55\u8fd9\u4ee5\u4e0b\u8fd9\u4e9b\u670d\u52a1", "ar": "\u0644\u0642\u062f \u0642\u0645\u062a \u0628\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0644\u062e\u062f\u0645\u0627\u062a ", "lv": "J\u016bs esat piesl\u0113dzies ar\u012b pie \u0161iem servisiem:", "id": "Anda juga telah log out dari layanan berikut: ", "sr": "Tako\u0111e ste prijavljeni u slede\u0107im servisima:", "ro": "Sunte\u021bi autentificat \u0219i la urm\u0103toarele servicii:", "ru": "\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043b\u0443\u0436\u0431\u0430\u043c:", "eu": "Zerbitzu hauetan ere kautotuta zaude:", "af": "Jy is ook by di\u00e9 dienste aangemeld:", "el": "\u0395\u03af\u03c3\u03c4\u03b5 \u03b5\u03c0\u03af\u03c3\u03b7\u03c2 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ad\u03c2 \u03c4\u03b9\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2:", "zu": "Ungenile futhi kulawa masevisi:", "xh": "Kananjalo ungene kwezi nkonzo:", "st": "Hape o kene ditshebeletsong tsena:", "ca": "També heu iniciat la sessió en aquests serveis:" }, "logout_all_question": { "no": "Vil du logge ut fra alle tjenestene ovenfor?", "nn": "Vil du logga ut fr\u00e5 alle tenestene?", "sv": "Vill du logga ut fr\u00e5n alla ovanst\u00e5ende tj\u00e4nster?", "es": "\u00bfDesea cerrar las sesiones de todos los servicios que se muestran m\u00e1s arriba?", "fr": "Voulez vous r\u00e9ellement terminer les connexions \u00e0 tout ces services?", "de": "Wollen Sie sich von allen obenstehenden Diensten abmelden?", "nl": "Wil je uitloggen van alle bovenvermelde diensten?", "sl": "Ali se \u017eelite odjaviti z vseh na\u0161tetih storitev?", "da": "Vil du logge ud fra alle ovenst\u00e5ende services?", "hu": "Ki akar jelentkezni az \u00f6sszes fenti alkalmaz\u00e1sb\u00f3l?", "pt": "Deseja sair de todos os servi\u00e7os listados em cima?", "pl": "Czy chcesz zosta\u0107 wylogowany z powy\u017cszych serwis\u00f3w?", "cs": "Chcete se odhl\u00e1sit ze v\u0161ech t\u011bchto slu\u017eeb?", "eu": "Goian agertzen diren zerbitzu guztietako saioak itxi nahi al dituzu?", "tr": "Yukar\u0131daki t\u00fcm servislerden \u00e7\u0131kmak istiyor musunuz?", "it": "Vuoi disconnetterti da tutti i servizi qui sopra riportati?", "fi": "Haluatko uloskirjautua edell\u00e4mainituista palveluista?", "hr": "\u017delite li se odjaviti iz svih gore navedenih servisa?", "lt": "Ar norite atsijungti nuo vis\u0173 \u017eemiau i\u0161vardint\u0173 paslaug\u0173?", "ja": "\u4e0a\u8a18\u306e\u5168\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3059\u304b?", "zh-tw": "\u662f\u5426\u767b\u51fa\u4e0a\u8ff0\u6240\u6709\u670d\u52d9\uff1f", "et": "Kas sa soovid k\u00f5igist \u00fclal loetletud teenustest v\u00e4lja logida?", "he": "\u05d4\u05d0\u05dd \u05d0\u05ea\u05d4 \u05e8\u05d5\u05e6\u05d4 \u05dc\u05d4\u05ea\u05e0\u05ea\u05e7 \u05de\u05db\u05dc \u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd \u05d4\u05de\u05d5\u05d6\u05db\u05e8\u05d9\u05dd \u05dc\u05de\u05e2\u05dc\u05d4?", "pt-br": "Voc\u00ea quer sair de todos os servi\u00e7os acima?", "zh": "\u4f60\u60f3\u540c\u65f6\u4ece\u4e0a\u9762\u7684\u8fd9\u4e9b\u670d\u52a1\u4e2d\u9000\u51fa\u5417\uff1f", "ar": "\u0647\u0644 \u062a\u0631\u063a\u0628 \u0628\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0645\u0646 \u062c\u0645\u064a\u0639 \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0623\u0639\u0644\u0627\u061f", "lv": "Vai v\u0113laties atsl\u0113gties no visiem uzskait\u012btajiem servisiem?", "id": "Apakah anda ingin logout dari semua layanan diatas ?", "sr": "\u017delite li se odjaviti iz svih gore navedenih servisa?", "ro": "Dori\u021bi s\u0103 v\u0103 deautentifica\u021bi de la toate serviciile de mai sus ?", "ru": "\u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0432\u0441\u0435\u0445 \u0441\u043b\u0443\u0436\u0431, \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435?", "af": "Wil jy van alle bogenoemde dienste afmeld?", "el": "\u0395\u03c0\u03b9\u03b8\u03c5\u03bc\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03b1\u03c0\u03cc \u03cc\u03bb\u03b5\u03c2 \u03c4\u03b9\u03c2 \u03c0\u03b1\u03c1\u03b1\u03c0\u03ac\u03bd\u03c9 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2\u003b", "xh": "Ngaba ufuna ukuphuma kuzo zonke iinkonzo ezingasentla?", "zu": "Ingabe ufuna ukuphuma kuwo wonke amasevisi angenhla?", "st": "Na o batla ho tswa ditshebeletsong tsohle tse ka hodimo moo?", "ca": "Voleu sortir de tots els serveis següents?" }, "logout_all": { "no": "Ja, alle tjenestene over", "nn": "Ja, logg ut fr\u00e5 alle", "sv": "Ja, alla tj\u00e4nster", "es": "S\u00ed, de todos los servicios", "fr": "Oui, de tous les services", "de": "Ja, alle Dienste", "nl": "Ja, alle diensten", "sl": "Da, odjavi me z vseh storitev", "da": "Ja, alle services", "hu": "Igen, minden alkalmaz\u00e1sb\u00f3l", "fi": "Kyll\u00e4, kaikista palveluista", "pt": "Sim, todos os servi\u00e7os", "pl": "Tak, wszystkie serwisy", "cs": "Ano, v\u0161echny slu\u017eby", "eu": "Bai, zerbitzu guztiak", "tr": "Evet, t\u00fcm servisler.", "it": "Si, da tutti i servizi", "hr": "Da, iz svih servisa", "lt": "Taip, vis\u0173 paslaug\u0173", "ja": "\u306f\u3044\u3001\u5168\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3059", "zh-tw": "\u662f\uff0c\u767b\u51fa\u6240\u6709\u670d\u52d9", "et": "Jah, k\u00f5igist teenustest", "he": "\u05db\u05df, \u05db\u05dc \u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd", "pt-br": "Sim, todos os servi\u00e7os", "zh": "\u662f\u7684\uff0c\u6240\u6709\u7684\u670d\u52a1", "ar": "\u0646\u0639\u0645 \u0645\u0646 \u062c\u0645\u064a\u0639 \u0627\u0644\u062e\u062f\u0645\u0627\u062a", "lv": "J\u0101, no visiem", "id": "Ya, semua layanan", "sr": "Da, iz svih servisa", "ro": "Da, toate serviciile", "ru": "\u0414\u0430, \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043b\u0443\u0436\u0431", "af": "Ja, alle dienste", "el": "\u039d\u03b1\u03b9, \u03cc\u03bb\u03b5\u03c2 \u03c4\u03b9\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2", "zu": "Yebo, wonke amasevisi", "xh": "Ewe, zonke iinkonzo", "st": "E, ditshebeletso tsohle", "ca": "Sí, tots els serveis" }, "logout_only": { "no": "Nei, bare %SP%", "nn": "Nei, logg berre ut fr\u00e5 %SP%", "sv": "Nej, endast %SP%", "es": "No, s\u00f3lo de %SP%", "fr": "Non, seulement de %SP%", "de": "Nein, nur %SP%", "nl": "Nee, alleen %SP%", "sl": "Ne, odjavi me samo z naslednjega %SP%", "da": "Nej, kun %SP%", "hu": "Nem, csak innen: %SP%", "fi": "Ei, vain %SP%", "pt": "N\u00e3o, apenas %SP%", "pl": "Nie, tylko %SP%", "cs": "Ne, jen %SP%", "eu": "Ez, %SPS bakarrik", "tr": "Hay\u0131r, sadece %SP%", "it": "No, solo da %SP%", "hr": "Ne, samo iz %SP%", "lt": "Ne, tik %SP%", "ja": "\u3044\u3044\u3048\u3001%SP% \u306e\u307f\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3059", "zh-tw": "\u5426\uff0c\u53ea\u767b\u51fa %SP%", "et": "Ei, ainult %SP%", "he": "\u05dc\u05d0, \u05e8\u05e7 %SP%", "pt-br": "N\u00e3o, apenas de %SP%", "zh": "\u4e0d\uff0c\u4ec5%SP%", "ar": "\u0644\u0627 \u0645\u0646 %SP% \u0641\u0642\u0637", "lv": "N\u0113, tikai %SP%", "id": "Tidak, hanya %SP%", "sr": "Ne, samo iz %SP%", "ro": "Nu, doar %SP%", "ru": "\u041d\u0435\u0442, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u043b\u0443\u0436\u0431\u044b %SP%", "af": "Nee, net %SP%", "el": "\u038c\u03c7\u03b9, \u03bc\u03cc\u03bd\u03bf \u03b1\u03c0\u03cc \u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 %SP%", "zu": "Cha, ku-%SP% kuphela", "xh": "Hayi, kuphela %SP%", "st": "Tjhe, %SP% feela", "ca": "No, només %SP%" }, "incapablesps": { "no": "En eller flere av tjenestene du er logget inn p\u00e5 st\u00f8tter ikke logout<\/i>. Lukk nettleseren, dersom du \u00f8nsker \u00e5 logge ut fra disse tjenestene.", "nn": "Ei eller fleire av tenestene du er innlogga p\u00e5 st\u00f8tter ikkje utlogging<\/i>. Lukk weblesaren din for \u00e5 sikra at alle sesjonar blir lukka", "sv": "En eller flera av tj\u00e4nsterna du \u00e4r inloggad i kan inte hantera utloggning<\/i>. F\u00f6r att s\u00e4kerst\u00e4lla att du inte l\u00e4ngre \u00e4r inloggad i n\u00e5gon tj\u00e4nst ska du st\u00e4nga din webbl\u00e4sare<\/i>.", "es": "Uno o m\u00e1s de los servicios en los que est\u00e1 autenticado no permite desconexi\u00f3n<\/i>. Para asegurarse de que todas sus sesiones se cierran, se le recomienda que cierre su navegador<\/i>.", "fr": "Un ou plusieurs des services auxquels vous \u00eates connect\u00e9 ne g\u00e8rent pas la d\u00e9connexion<\/i>. Pour terminer les sessions sur ces services, vous devrez fermer votre navigateur<\/i>.", "de": "Einer oder mehrere Dienste an denen Sie angemeldet sind, unterst\u00fctzen keine Abmeldung<\/i>. Um sicherzustellen, dass Sie abgemeldet sind, schlie\u00dfen Sie bitte Ihren Webbrowser<\/i>.", "nl": "Een of meer diensten waarop je bent inlogd hebben geen ondersteuning voor uitloggen<\/i>. Om er zeker van te zijn dat al je sessies zijn be\u00ebindigd, kun je het beste je webbrowser afsluiten<\/i>.", "sl": "Ena ali ve\u010d storitev, v katere ste prijavljeni, ne omogo\u010da odjave<\/i>. Odjavo iz teh storitev izvedete tako, da zaprete spletni brskalnik<\/i>.", "da": "En eller flere services som du er logget ind hos underst\u00f8tter ikke log ou<\/i>. For at sikre at alle dine forbindelser er lukket, bedes du lukke din browser<\/i>.", "hu": "Egy vagy t\u00f6bb alkalmaz\u00e1s nem t\u00e1mogatja a kijelenkez\u00e9st<\/i>. Hogy biztos\u00edtani lehessen, hogy nem maradt bejelentkezve, k\u00e9rj\u00fck, l\u00e9pjen ki a b\u00f6ng\u00e9sz\u0151b\u0151l!<\/i>", "pt": "Um ou mais dos servi\u00e7os onde se encontra autenticado n\u00e3o suporta(m) a sa\u00edda<\/i>. Para garantir que todas as sess\u00f5es s\u00e3o encerradas, dever\u00e1 encerrar o seu navegador Web<\/i>.", "pl": "Jeden lub wi\u0119cej serwis\u00f3w , w kt\u00f3rych jeste\u015b zalogowany nie obs\u0142uguje procesu wylogowania<\/i>. W celu upewnienia si\u0119, \u017ce wszystkie sesje s\u0105 zako\u0144czone, zalecane jest aby\u015b zamkn\u0105\u0142 przegl\u0105dark\u0119<\/i>", "cs": "Jedna, nebo v\u00edce slu\u017eeb, do kter\u00fdch jste p\u0159ihla\u0161en, nepodporuje odhla\u0161en\u00ed. Pokud se chcete odhl\u00e1sit, mus\u00edte ukon\u010dit v\u00e1\u0161 webov\u00fd prohl\u00ed\u017ee\u010d.", "tr": "Giri\u015f yapt\u0131\u011f\u0131n\u0131z bir yada daha fazla servis \u00e7\u0131k\u0131\u015f\u0131 desteklemiyor<\/i>. T\u00fcm oturumlar\u0131n\u0131z\u0131n kapat\u0131ld\u0131\u011f\u0131ndan emin olmak i\u00e7in, taray\u0131c\u0131n\u0131z\u0131 kapatman\u0131z<\/i> \u00f6nerilir.", "it": "Uno o più servizi a cui sei connesso non supportano la disconnessione<\/i>. Per assicurarsi di chiudere tutte le sessioni si consiglia di chiudere il browser<\/i>", "fi": "Yksi tai useampi palvelu johon olet kirjautunut ei tue uloskirjautumista<\/i>. Varmistaaksesi, ett\u00e4 kaikki istuntosi sulkeutuvat, olet velvollinen sulkemaan web-selaimesi<\/i>.", "hr": "Jedan ili vi\u0161e servisa na koje ste prijavljeni ne podr\u017eava odjavljivanje<\/i>. Da biste bili sigurni da su sve va\u0161e sjednice zavr\u0161ene, preporu\u010damo da zatvorite web preglednik<\/i>.", "lt": "Viena ar daugiau paslaug\u0173, prie kuri\u0173 esate prisijung\u0119s nepalaiko atsijungimo<\/i>. Siekiant u\u017etikrinti s\u0117kming\u0105 darbo pabaig\u0105, rekomenduojame u\u017edaryti nar\u0161ykl\u0119<\/i>.", "ja": "\u30ed\u30b0\u30a2\u30a6\u30c8\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u306a\u3044<\/i>\u4e00\u3064\u4ee5\u4e0a\u306e\u30b5\u30fc\u30d3\u30b9\u306b\u30ed\u30b0\u30a4\u30f3\u4e2d\u3067\u3059\u3002\u78ba\u5b9f\u306b\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u7d42\u4e86\u3055\u305b\u308b\u306b\u306f\u3001WEB\u30d6\u30e9\u30a6\u30b6\u3092\u9589\u3058\u308b<\/i>\u4e8b\u3092\u63a8\u5968\u3057\u307e\u3059\u3002", "zh-tw": "\u60a8\u767b\u5165\u7684\u670d\u52d9\u4e2d\u6709\u4e00\u500b\u6216\u4ee5\u4e0a\u4e0d\u652f\u63f4\u767b\u51fa<\/i>\u3002\u70ba\u78ba\u4fdd\u60a8\u7684\u6240\u6709\u9023\u7dda\u7686\u5df2\u95dc\u9589\uff0c\u5efa\u8b70\u60a8\u95dc\u9589\u700f\u89bd\u5668<\/i>\u3002", "et": "\u00dcks v\u00f5i mitu teenust, millesse oled sisselogitud ei toeta v\u00e4lja logimise<\/i>. Selleks, et olla kindel k\u00f5igi sessioonide l\u00f5petamises soovitame sulgeda k\u00f5ik brauseri aknad<\/i>.", "he": "\u05d0\u05d7\u05d3 \u05d0\u05d5 \u05d9\u05d5\u05ea\u05e8 \u05de\u05df \u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd \u05e9\u05d0\u05ea\u05d4 \u05de\u05d7\u05d5\u05d1\u05e8 \u05d0\u05dc\u05d9\u05d4\u05dd \u05dc\u05d0 \u05ea\u05d5\u05de\u05db\u05d9\u05dd \u05d1\u05d4\u05ea\u05e0\u05ea\u05e7\u05d5\u05ea<\/i> .\u05db\u05d3\u05d9 \u05dc\u05d5\u05d5\u05d3\u05d0 \u05e9\u05d4\u05ea\u05e0\u05ea\u05e7\u05ea \u05de\u05db\u05dc \u05d4\u05e9\u05d9\u05e8\u05d5\u05ea\u05d9\u05dd \u05de\u05de\u05d5\u05dc\u05e5 \u05e9\u05ea\u05e1\u05d2\u05d5\u05e8 \u05d0\u05ea \u05d4\u05d3\u05e4\u05d3\u05e4\u05df<\/i>", "pt-br": "Um ou mais dos servi\u00e7os que voc\u00ea est\u00e1 conectado n\u00e3o suportam logout.<\/i> Para garantir que todas as suas sess\u00f5es ser\u00e3o fechadas, incentivamos voc\u00ea a fechar seu navegador<\/i>.", "zh": "\u4e00\u4e2a\u6216\u591a\u4e2a\u4f60\u5df2\u767b\u5f55\u7684\u670d\u52a1\u4e0d\u652f\u6301\u9000\u51fa<\/i>\uff0c\u8bf7\u786e\u8ba4\u4f60\u6240\u6709sessions\u5df2\u5173\u95ed\uff0c\u6211\u4eec\u9f13\u52b1\u4f60 \u5173\u95ed\u6d4f\u89c8\u5668<\/i>", "ar": "\u0648\u0627\u062d\u062f\u0629 \u0627\u0648 \u0627\u0643\u062b\u0631 \u0645\u0646 \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0627\u0644\u062a\u064a \u0642\u0645\u062a \u0628\u062a\u0633\u062c\u064a\u0644 \u062f\u062e\u0648\u0644\u0643 \u0628\u0647\u0627 \u0644\u0627 \u062a\u062f\u0639\u0645 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c. \u0644\u0644\u062a\u0623\u0643\u062f \u0645\u0646 \u0627\u0646 \u062c\u0645\u064a\u0639 \u0635\u0641\u062d\u0627\u062a\u0643 \u0642\u062f \u062a\u0645 \u0625\u063a\u0644\u0627\u0642\u0647\u0627 \u0642\u0645 \u0628\u0625\u063a\u0644\u0627\u0642 \u0645\u062a\u0635\u0641\u062d\u0643", "lv": "Viens vai vair\u0101ki J\u016bsu izmantotie servisi neatbalsta atsl\u0113g\u0161anos<\/i>. Lai aizv\u0113rtu visas sesijas, aizveriet savu interneta p\u0101rl\u016bku<\/i>.", "id": "Satu atau beberapa layanan yang anda telah login tidak mendukung logout<\/i>.Untuk meyakinkan semua session anda ditutup, anda disarankan untuk menutup web browser anda<\/i>.", "sr": "Jedan ili vi\u0161e servisa na koje ste prijavljeni ne podr\u017eava odjavljivanje<\/i>. Da biste bili sigurni da su sve va\u0161e sesije zavr\u0161ene, preporu\u010dujemo da zatvorite web pretra\u017eiva\u010d<\/i>.", "ro": "Unul sau mai multe servicii \u00een care sunte\u021bi autentificat nu suport\u0103 deautentificare<\/i>. Pentru a fi sigur c\u0103 toate sesiunile sunt \u00eenchise, v\u0103 rug\u0103m s\u0103 \u00eenchide\u021bi browser-ul<\/i>.", "ru": "\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043b\u0443\u0436\u0431\u044b, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b, \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0436\u0438\u0432\u0430\u044e\u0442 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/i>. \u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u0441\u0441\u0438\u0439, \u0437\u0430\u043a\u0440\u043e\u0439\u0442\u0435 \u0432\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/i>.", "eu": "Kautotuta zauden zerbitzu bat edo batzuk ez dute uzten saioa ixten<\/i>. Zure saio guztiak ixten direla ziurtatzeko, zure nabigatzaileko leiho guztiak ixtea<\/i> gomendatzen da.", "af": "Een of meerdere dienste waarby jy aangemeld het, ondersteun nie afmelding nie<\/i>. Om seker te wees datal jou sessies afgesluit word, is dit beter om jou webblaaier toe te maak<\/i>.", "el": "\u039c\u03af\u03b1 \u03ae \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2 \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03bf\u03c0\u03bf\u03af\u03b5\u03c2 \u03b5\u03af\u03c3\u03c4\u03b5 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2\u002f\u03b7 \u03b4\u03b5\u03bd \u03c5\u03c0\u03bf\u03c3\u03c4\u03b7\u03c1\u03af\u03b6\u03bf\u03c5\u03bd \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u002e \u0393\u03b9\u03b1 \u03c4\u03bf \u03ba\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf \u03cc\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03b9\u03ce\u03bd \u03c3\u03b1\u03c2 (sessions), \u03c3\u03b1\u03c2 \u03c3\u03c5\u03bd\u03b9\u03c3\u03c4\u03bf\u03cd\u03bc\u03b5 \u03bd\u03b1 \u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03c4\u03b5<\/i> \u03c4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c0\u03bb\u03bf\u03ae\u03b3\u03b7\u03c3\u03b7\u03c2 (web browser).", "zu": "Isevisi eyodwa noma ngaphezulu ongene kuyo ayikusekeli ukuphuma. Ukuze wenze isiqiniseko sokuthi wonke amaseshini akho avaliwe, ukhuthazwa ukuthi uvale isiphequluli sakho sewebhu.", "xh": "Inkonzo enye okanye ezingakumbi ongeneyo kuzo azikuxhasi ukuphuma. Ukuqinisekisa zonke iiseshoni zakho zivaliwe, ukhuthazwa uvale ibhrawuza yewebhu.", "st": "E le nngwe kapa ho feta ya ditshebeletso tseo o keneng ho tsona ha e tshehetse ho tswa. Ho netefatsa hore diseshene tsohle tsa hao di kwetswe, o kgothaletswa ho kwala sebadi sa webo sa hao.", "ca": "Un o més dels serveis que heu accedit a no admeten tancar la sessió<\/i>. Per assegurar-vos que totes les vostres sessions estan tancades, us animem a tancar el vostre navegador web<\/i>." }, "no": { "no": "Nei", "nn": "Nei", "sv": "Nej", "es": "No", "fr": "Non", "de": "Nein", "nl": "Nee", "sl": "Ne", "da": "Nej", "hu": "Nem", "fi": "Ei", "pt": "N\u00e3o", "pl": "Nie", "cs": "Ne", "eu": "Ez", "tr": "Hay\u0131r", "it": "No", "hr": "Ne", "lt": "Ne", "ja": "\u3044\u3044\u3048", "zh-tw": "\u5426", "et": "Ei", "he": "\u05dc\u05d0", "pt-br": "N\u00e3o", "zh": "\u4e0d", "ar": "\u0644\u0627", "lv": "N\u0113", "id": "Tidak", "sr": "Ne", "ro": "Nu", "ru": "\u041d\u0435\u0442", "af": "Nee", "el": "\u038c\u03c7\u03b9", "xh": "Hayi", "zu": "Cha", "st": "Tjhe", "ca": "No" }, "logging_out_from": { "sl": "Odjava iz naslednjih storitev:", "da": "Du logger ud af f\u00f8lgende services:", "pt": "A sair dos servi\u00e7os seguintes:", "sv": "Loggar ut fr\u00e5n f\u00f6ljande tj\u00e4nster:", "no": "Logger ut fra f\u00f8lgende tjenester:", "nn": "Logger ut fr\u00e5 f\u00f8lgende tenester:", "de": "Melde Sie von den folgenden Diensten ab:", "hr": "Odjavljujete se iz sljede\u0107ih servisa:", "fr": "D\u00e9connexion des services suivants :", "lt": "Vyksta atjungimas nuo \u0161i\u0173 paslaug\u0173:", "it": "Disconnessione in corso dai seguenti servizi:", "es": "Cerrando las sesiones de los siguientes servicios:", "hu": "Kil\u00e9p\u00e9s az al\u00e1bbi szolg\u00e1ltat\u00e1sokb\u00f3l:", "ja": "\u4ee5\u4e0b\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u3089\u30ed\u30b0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f:", "nl": "Uitloggen van de volgende diensten:", "zh-tw": "\u5f9e\u4e0b\u5217\u670d\u52d9\u767b\u51fa\uff1a", "pl": "Wylogowanie z nast\u0119puj\u0105cych serwis\u00f3w:", "et": "V\u00e4lja logimine j\u00e4rgmistest teenustest:", "he": "\u05de\u05ea\u05e0\u05ea\u05e7 \u05de\u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd \u05d4\u05d1\u05d0\u05d9\u05dd:", "pt-br": "Saindo dos seguintes servi\u00e7os:", "zh": "\u4ece\u4e0b\u5217\u670d\u52a1\u4e2d\u9000\u51fa", "ar": "\u062a\u0633\u062c\u064a\u0644 \u062e\u0631\u0648\u062c \u0645\u0646 \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0623\u062f\u0646\u0627\u0647 ", "lv": "Atsl\u0113g\u0161an\u0101s no \u0161iem servisiem:", "id": "Log out dari layanan-layanan berikut:", "sr": "Odjavljujete se iz slede\u0107ih servisa", "cs": "Odhl\u00e1\u0161en\u00ed z n\u00e1sleduj\u00edc\u00edch slu\u017eeb:", "ro": "Deautentificare din urm\u0103toarele servicii:", "ru": "\u0412\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u043b\u0443\u0436\u0431:", "eu": "Honako zerbitzu hauen saioak itxi:", "fi": "Kirjaudutaan ulos seuraavista palveluista:", "af": "Afmelding van die volgende dienste:", "el": "Γίνεται αποσύνδεση από τις ακόλουθες υπηρεσίες:", "zu": "Iyaphuma kumasevisi alandelayo:", "xh": "Iphuma kwezi nkonzo zilandelayo:", "st": "E tswa ditshebeletsong tse latelang:", "ca": "Sortida dels serveis següents:" }, "failedsps": { "sl": "Odjava z ene ali ve\u010d storitev ni uspela. Odjavo dokon\u010dajte tako, da zaprete spletni brskalnik<\/i>.", "da": "Kan ikke logge ud af en eller flere services. For at sikre at alle dine sessioner er lukket skal du lukke din browser<\/i>.", "pt": "N\u00e3o foi poss\u00edvel sair de um ou mais servi\u00e7os. Para garantir que todas as suas sess\u00f5es s\u00e3o fechadas, \u00e9 recomendado fechar o seu browser<\/i>.", "sv": "Kan inte logga ut fr\u00e5n eller flera tj\u00e4nster. F\u00f6r att vara s\u00e4ker p\u00e5 att du fortfarande inte \u00e4r inloggad ska du st\u00e4nga igen alla dina webbl\u00e4sarf\u00f6nster<\/i>.", "no": "Greide ikke \u00e5 logge ut fra en eller flere tjenester. For \u00e5 forsikre deg om at du blir logget ut, oppfordrer vi deg til \u00e5 lukke nettleseren din<\/i>.", "nn": "Greide ikkje \u00e5 logge ut fr\u00e5 ein eller fleire tenester. For \u00e5 sikre deg at du blir logga ut, oppfordrar vi deg til \u00e5 lukke nettlesaren din<\/i>.", "de": "Abmelden von einem oder mehreren Diensten schlug fehl. Um sicherzustellen, dass alle Ihre Sitzungen geschlossen sind, wird Ihnen empfohlen, Ihren Webbrowser zu schlie\u00dfen<\/i>.", "hr": "Odjavljivanje iz jednog ili vi\u0161e servisa nije uspjelo. Da biste bili sigurni da su sve va\u0161e sjednice zavr\u0161ene, preporu\u010damo da zatvorite web preglednik<\/i>.", "fr": "Impossible de se d\u00e9connecter d'un ou plusieurs services. Pour \u00eatre certain de clore vos sessions, il vous est recommand\u00e9 de fermer votre navigateur<\/i>.", "lt": "Nepavyksta atsijungti nuo vienos ar daugiau paslaug\u0173. Siekiant u\u017etikrinti s\u0117kming\u0105 darbo pabaig\u0105, rekomenduojame u\u017edaryti nar\u0161ykl\u0119<\/i>.", "it": "Impossibile disconnettersi da uno o pi\u00f9 servizi. Per assicurarsi di chiudere tutte le sessioni si consiglia di chiudere il browser<\/i>", "es": "No fue posible desconectarse de uno o m\u00e1s servicios. Para garantizar que todas sus sesiones han sido cerradas, se recomienda que cierre su navegador web<\/i>.", "hu": "Legal\u00e1bb egy szolg\u00e1ltat\u00e1sb\u00f3l nem siker\u00fclt kil\u00e9pni. Ahhoz, hogy biztosan lez\u00e1rja a megkezdett munkamenetet, k\u00e9rj\u00fck, z\u00e1rja be b\u00f6ng\u00e9sz\u0151j\u00e9t<\/i>.", "ja": "\u4e00\u3064\u4ee5\u4e0a\u306e\u30b5\u30fc\u30d3\u30b9\u304b\u305f\u30ed\u30b0\u30a2\u30a6\u30c8\u51fa\u6765\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u78ba\u5b9f\u306b\u30bb\u30c3\u30b7\u30e7\u30f3\u3092\u7d42\u4e86\u3055\u305b\u308b\u306b\u306f\u3001WEB\u30d6\u30e9\u30a6\u30b6\u3092\u9589\u3058\u308b<\/i>\u4e8b\u3092\u63a8\u5968\u3057\u307e\u3059\u3002", "nl": "Het was niet mogelijk bij een of meerdere diensten uit te loggen. Om alle sessies te sluiten, raden wij u aan uw webbrowser te af te sluiten<\/i>.", "zh-tw": "\u7121\u6cd5\u6b63\u5e38\u767b\u51fa\uff0c\u70ba\u78ba\u4fdd\u60a8\u7684\u6240\u6709\u9023\u7dda\u7686\u5df2\u95dc\u9589\uff0c\u5efa\u8b70\u60a8\u95dc\u9589\u700f\u89bd\u5668<\/i>\u3002", "et": "\u00dchest v\u00f5i mitmest teenusest v\u00e4lja logimine ei \u00f5nnestunud. Selleks, et olla kindel k\u00f5igi sessioonide l\u00f5petamises soovitame sulgeda k\u00f5ik brauseri aknad<\/i>.", "he": "\u05d0\u05d9 \u05d0\u05e4\u05e9\u05e8 \u05dc\u05d4\u05ea\u05e0\u05ea\u05e7 \u05de\u05d0\u05d7\u05d3 \u05d0\u05d5 \u05d9\u05d5\u05ea\u05e8 \u05de\u05d4\u05e9\u05e8\u05d5\u05ea\u05d9\u05dd. \u05db\u05d3\u05d9 \u05dc\u05d5\u05d5\u05d3\u05d0 \u05e9\u05d4\u05ea\u05e0\u05ea\u05e7\u05ea \u05de\u05d5\u05de\u05dc\u05e5 \u05dc\u05e1\u05d2\u05d5\u05e8 \u05d0\u05ea <\/i>.\u05d4\u05d3\u05e4\u05d3\u05e4\u05df \u05e9\u05dc\u05da", "pt-br": "Incapaz de sair de um ou mais servi\u00e7os. Para garantir que todas as suas sess\u00f5es ser\u00e3o fechadas, incentivamos voc\u00ea a fechar seu navegador<\/i>.", "zh": "\u65e0\u6cd5\u4ece\u4e00\u4e2a\u6216\u8005\u591a\u4e2a\u670d\u52a1\u4e2d\u9000\u51fa\uff0c\u8bf7\u786e\u8ba4\u4f60\u6240\u6709sessions\u5df2\u5173\u95ed\uff0c\u6211\u4eec\u9f13\u52b1\u4f60 \u5173\u95ed\u6d4f\u89c8\u5668<\/i>", "ar": "\u0644\u0645 \u0627\u0633\u062a\u0637\u0639 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062e\u0631\u0648\u062c \u0645\u0646 \u0648\u0627\u062d\u062f\u0629 \u0627\u0648 \u0627\u0643\u062b\u0631 \u0645\u0646 \u0627\u0644\u062e\u062f\u0645\u0627\u062a. \u0644\u0644\u062a\u0623\u0643\u062f \u0645\u0646 \u0627\u0646 \u062c\u0645\u064a\u0639 \u0635\u0641\u062d\u0627\u062a\u0643 \u0642\u062f \u0623\u063a\u0644\u0642\u062a \u0642\u0645 \u0628\u0625\u063a\u0644\u0627\u0642 \u0645\u062a\u0635\u0641\u062d\u0643", "lv": "Nav iesp\u0113jams atsl\u0113gties no viena vai vair\u0101kiem servisiem. Lai aizv\u0113rtu visas sesijas, aizveriet savu interneta p\u0101rl\u016bku<\/i>.", "id": "Tidak dapat log out dari satu atau beberapa layanan. Untuk memastikan semua session anda ditutup, anda disaranakan untuk menutup web browser anda<\/i>.", "sr": "Odjavljivanje iz jednog ili vi\u0161e servisa nije uspelo. Da biste bili sigurni da su sve va\u0161e sesija zavr\u0161ene, preporu\u010dujemo da zatvorite web pretra\u017eiva\u010d<\/i>.", "cs": "Odhl\u00e1\u0161en\u00ed z jedn\u00e9 nebo z v\u00edce slu\u017eeb se nezda\u0159ilo. Aby bylo zaji\u0161t\u011bno, \u017ee v\u0161echny va\u0161e relace budou uzav\u0159eny, doporu\u010dujeme ukon\u010dit v\u00e1\u0161 webov\u00fd prohl\u00ed\u017ee\u010d<\/i>.", "ro": "Nu a fost posibil\u0103 deautentificarea pentru unul sau mai multe servicii. Pentru a fi sigur c\u0103 toate sesiunile sunt \u00eenchise, v\u0103 rug\u0103m s\u0103 \u00eenchide\u021bi browser-ul<\/i>.", "ru": "\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0436\u0431. \u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u0441\u0441\u0438\u0439, \u0437\u0430\u043a\u0440\u043e\u0439\u0442\u0435 \u0432\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440<\/i>. ", "eu": "Ezinezkoa da zerbitzu bat edo batzuen saioak ixtea. Zure saio guztiak itxi direla ziurtatzeko, zure web nabigatzailea ixtea<\/i> gomendatzen da. ", "fi": "Uloskirjautuminen yhdest\u00e4 tai useammasta palvelusta ep\u00e4onnistui. Sulje web-selaimesi<\/i> varmistaaksesi, ett\u00e4 kaikki istuntosi sulkeutuvat.", "af": "Dit was nie moontlik om van een of meer dienste af te meld nie. Om seker te wees dat al jou sessies afgesluit word, is dit beter om jou webblaaier toe te maak<\/i>.", "el": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 \u03b1\u03c0\u03cc \u03bc\u03af\u03b1 \u03ae \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b5\u03c2\u002e \u0393\u03b9\u03b1 \u03c4\u03bf \u03ba\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf \u03cc\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u03c3\u03c5\u03bd\u03b5\u03b4\u03c1\u03b9\u03ce\u03bd \u03c3\u03b1\u03c2 (sessions), \u03c3\u03b1\u03c2 \u03c3\u03c5\u03bd\u03b9\u03c3\u03c4\u03bf\u03cd\u03bc\u03b5 \u03bd\u03b1 \u03ba\u03bb\u03b5\u03af\u03c3\u03b5\u03c4\u03b5<\/i> \u03c4\u03bf \u03c0\u03c1\u03cc\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1 \u03c0\u03bb\u03bf\u03ae\u03b3\u03b7\u03c3\u03b7\u03c2 (web browser).", "xh": "Awukwazi ukuphuma kwinkonzo enye okanye ezingakumbi. Ukuqinisekisa zonke iiseshoni zakho zivaliwe, ukhuthazwa uvale ibhrawuza yewebhu.", "zu": "Ayikwazi ukuphuma kusevisi eyodwa noma ngaphezulu. Ukuze wenze isiqiniseko sokuthi wonke amaseshini akho avaliwe, ukhuthazwa ukuthi uvale isiphequluli sakho sewebhu.", "st": "Ha e kgone ho tswa tshebeletsong e le nngwe kapa ho feta. Ho netefatsa hore diseshene tsohle tsa hao di kwetswe, o kgothaletswa ho kwala sebadi sa webo sa hao.", "ca": "No es pot tancar la sessió d'un o més serveis. Per assegurar-vos que totes les vostres sessions estan tancades, us animem a tancar el vostre navegador web<\/i>." } } simplesamlphp-1.19.1/dictionaries/errors.definition.json0000644000000000000000000001770014042503475022203 0ustar rootroot{ "error_header": { "en": "SimpleSAMLphp error" }, "report_trackid": { "en": "If you report this error, please also report this tracking number which makes it possible to locate your session in the logs available to the system administrator:" }, "debuginfo_header": { "en": "Debug information" }, "debuginfo_text": { "en": "The debug information below may be of interest to the administrator \/ help desk:" }, "report_header": { "en": "Report errors" }, "report_text": { "en": "Optionally enter your email address, for the administrators to be able contact you for further questions about your issue:" }, "report_email": { "en": "E-mail address:" }, "report_explain": { "en": "Explain what you did when this error occurred..." }, "report_submit": { "en": "Send error report" }, "howto_header": { "en": "How to get help" }, "howto_text": { "en": "This error probably is due to some unexpected behaviour or to misconfiguration of SimpleSAMLphp. Contact the administrator of this login service, and send them the error message above." }, "title_CREATEREQUEST": { "en": "Error creating request" }, "descr_CREATEREQUEST": { "en": "An error occurred when trying to create the SAML request." }, "title_DISCOPARAMS": { "en": "Bad request to discovery service" }, "descr_DISCOPARAMS": { "en": "The parameters sent to the discovery service were not according to specifications." }, "title_GENERATEAUTHNRESPONSE": { "en": "Could not create authentication response" }, "descr_GENERATEAUTHNRESPONSE": { "en": "When this identity provider tried to create an authentication response, an error occurred." }, "title_LDAPERROR": { "en": "LDAP Error" }, "descr_LDAPERROR": { "en": "LDAP is the user database, and when you try to login, we need to contact an LDAP database. An error occurred when we tried it this time." }, "title_LOGOUTREQUEST": { "en": "Error processing the Logout Request" }, "descr_LOGOUTREQUEST": { "en": "An error occurred when trying to process the Logout Request." }, "title_METADATA": { "en": "Error loading metadata" }, "descr_METADATA": { "en": "There is some misconfiguration of your SimpleSAMLphp installation. If you are the administrator of this service, you should make sure your metadata configuration is correctly setup." }, "title_NOACCESS": { "en": "No access" }, "descr_NOACCESS": { "en": "This endpoint is not enabled. Check the enable options in your configuration of SimpleSAMLphp." }, "title_NORELAYSTATE": { "en": "No RelayState" }, "descr_NORELAYSTATE": { "en": "The initiator of this request did not provide a RelayState parameter indicating where to go next." }, "title_PROCESSASSERTION": { "en": "Error processing response from Identity Provider" }, "descr_PROCESSASSERTION": { "en": "We did not accept the response sent from the Identity Provider." }, "title_PROCESSAUTHNREQUEST": { "en": "Error processing request from Service Provider" }, "descr_PROCESSAUTHNREQUEST": { "en": "This Identity Provider received an Authentication Request from a Service Provider, but an error occurred when trying to process the request." }, "title_SLOSERVICEPARAMS": { "en": "No SAML message provided" }, "descr_SLOSERVICEPARAMS": { "en": "You accessed the SingleLogoutService interface, but did not provide a SAML LogoutRequest or LogoutResponse. Please note that this endpoint is not intended to be accessed directly." }, "title_ACSPARAMS": { "en": "No SAML response provided" }, "descr_ACSPARAMS": { "en": "You accessed the Assertion Consumer Service interface, but did not provide a SAML Authentication Response. Please note that this endpoint is not intended to be accessed directly." }, "title_SSOPARAMS": { "en": "No SAML request provided" }, "descr_SSOPARAMS": { "en": "You accessed the Single Sign On Service interface, but did not provide a SAML Authentication Request. Please note that this endpoint is not intended to be accessed directly." }, "title_ARSPARAMS": { "en": "No SAML message provided" }, "descr_ARSPARAMS": { "en": "You accessed the Artifact Resolution Service interface, but did not provide a SAML ArtifactResolve message. Please note that this endpoint is not intended to be accessed directly." }, "title_CASERROR": { "en": "CAS Error" }, "descr_CASERROR": { "en": "Error when communicating with the CAS server." }, "title_CONFIG": { "en": "Configuration error" }, "descr_CONFIG": { "en": "SimpleSAMLphp appears to be misconfigured." }, "title_NOTVALIDCERT": { "en": "Invalid certificate" }, "descr_NOTVALIDCERT": { "en": "You did not present a valid certificate." }, "title_NOTSET": { "en": "Password not set" }, "descr_NOTSET": { "en": "The password in the configuration (auth.adminpassword) is not changed from the default value. Please edit the configuration file." }, "errorreport_header": { "en": "Error report sent" }, "errorreport_text": { "en": "The error report has been sent to the administrators." }, "title_LOGOUTINFOLOST": { "en": "Logout information lost" }, "descr_LOGOUTINFOLOST": { "en": "The information about the current logout operation has been lost. You should return to the service you were trying to log out from and try to log out again. This error can be caused by the logout information expiring. The logout information is stored for a limited amout of time - usually a number of hours. This is longer than any normal logout operation should take, so this error may indicate some other error with the configuration. If the problem persists, contact your service provider." }, "title_UNHANDLEDEXCEPTION": { "en": "Unhandled exception" }, "descr_UNHANDLEDEXCEPTION": { "en": "An unhandled exception was thrown." }, "title_NOTFOUND": { "en": "Page not found" }, "descr_NOTFOUND": { "en": "The given page was not found. The URL was: %URL%" }, "title_NOTFOUNDREASON": { "en": "Page not found" }, "descr_NOTFOUNDREASON": { "en": "The given page was not found. The reason was: %REASON% The URL was: %URL%" }, "title_BADREQUEST": { "en": "Bad request received" }, "descr_BADREQUEST": { "en": "There is an error in the request to this page. The reason was: %REASON%" }, "title_WRONGUSERPASS": { "en": "Incorrect username or password" }, "descr_WRONGUSERPASS": { "en": "Either no user with the given username could be found, or the password you gave was wrong. Please check the username and try again." }, "title_RESPONSESTATUSNOSUCCESS": { "en": "Error received from Identity Provider" }, "descr_RESPONSESTATUSNOSUCCESS": { "en": "The Identity Provider responded with an error. (The status code in the SAML Response was not success)" }, "title_NOCERT": { "en": "No certificate" }, "descr_NOCERT": { "en": "Authentication failed: your browser did not send any certificate" }, "title_INVALIDCERT": { "en": "Invalid certificate" }, "descr_INVALIDCERT": { "en": "Authentication failed: the certificate your browser sent is invalid or cannot be read" }, "title_UNKNOWNCERT": { "en": "Unknown certificate" }, "descr_UNKNOWNCERT": { "en": "Authentication failed: the certificate your browser sent is unknown" }, "title_USERABORTED": { "en": "Authentication aborted" }, "descr_USERABORTED": { "en": "The authentication was aborted by the user" }, "title_NOSTATE": { "en": "State information lost" }, "descr_NOSTATE": { "en": "State information lost, and no way to restart the request" }, "title_METADATANOTFOUND": { "en": "Metadata not found" }, "descr_METADATANOTFOUND": { "en": "Unable to locate metadata for %ENTITYID%" }, "title_AUTHSOURCEERROR": { "en": "Authentication source error" }, "descr_AUTHSOURCEERROR": { "en": "Authentication error in source %AUTHSOURCE%. The reason was: %REASON%" }, "title_MEMCACHEDOWN": { "en": "Cannot retrieve session data" }, "descr_MEMCACHEDOWN": { "en": "Your session data cannot be retrieved right now due to technical difficulties. Please try again in a few minutes." } } simplesamlphp-1.19.1/dictionaries/login.translation.json0000644000000000000000000016417114042503475022212 0ustar rootroot{ "error_header": { "no": "Feil", "nn": "Feil", "sv": "Fel", "es": "Error", "fr": "Erreur", "de": "Fehler", "nl": "Fout", "lb": "Fehler", "sl": "Napaka", "da": "Fejl", "hr": "Gre\u0161ka", "hu": "Hiba", "fi": "Virhe", "pt-br": "Erro", "pt": "Erro", "pl": "B\u0142\u0105d", "cs": "Chyba", "eu": "Eman dituzun datuak okerrak dira", "tr": "Hata", "lt": "Klaida", "it": "Errore", "ja": "\u30a8\u30e9\u30fc", "zh-tw": "\u932f\u8aa4", "et": "T\u00f5rge", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430", "zh": "\u9519\u8bef", "ar": "\u062e\u0637\u0627", "id": "Error", "lv": "K\u013c\u016bda", "sr": "Gre\u0161ka", "ro": "Eroare", "af": "Fout", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1", "zu": "Iphutha", "xh": "Impazamo", "st": "Phoso", "ca": "Error" }, "user_pass_header": { "no": "Skriv inn brukernavn og passord", "nn": "Skriv inn brukarnamn og passord", "sv": "Ange ditt anv\u00e4ndarnamn och l\u00f6senord", "es": "Introduzca su nombre de usuario y contrase\u00f1a", "fr": "Entrez votre identifiant et votre mot de passe", "de": "Bitte geben Sie Ihren Nutzernamen und Ihr Passwort ein", "nl": "Geef je gebruikersnaam en wachtwoord", "lb": "Gid w.e.g Aeren Benotzernumm an d Passwuert an", "sl": "Vnesite svoje uporabni\u0161ko ime in geslo", "da": "Indtast brugernavn og kodeord", "hr": "Unesite korisni\u010dku oznaku i zaporku", "hu": "Felhaszn\u00e1l\u00f3n\u00e9v \u00e9s jelsz\u00f3", "fi": "Sy\u00f6t\u00e4 tunnuksesi ja salasanasi", "pt-br": "Digite seu usu\u00e1rio e senha", "pt": "Introduza o seu nome de utilizador e senha", "pl": "Wprowad\u017a nazw\u0119 uzytkownika i has\u0142o", "cs": "Vlo\u017ete sv\u00e9 jm\u00e9no a heslo", "eu": "Sartu erabiltzaile-izena eta pasahitza", "tr": "Kullan\u0131c\u0131 ad\u0131 ve \u015fifrenizi giriniz", "lt": "\u012eveskite savo prisijungimo vard\u0105 ir slapta\u017eod\u012f", "it": "Inserire nome utente e password", "ja": "\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044", "zh-tw": "\u8acb\u8f38\u5165\u60a8\u7684\u5e33\u865f\u53ca\u5bc6\u78bc", "et": "Sisesta oma kasutajatunnus ja parool", "he": "\u05d4\u05db\u05e0\u05e1 \u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9 \u05d5\u05e1\u05d9\u05e1\u05de\u05d4", "ru": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c", "zh": "\u8f93\u5165\u4f60\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801", "ar": "\u0627\u062f\u062e\u0644 \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0648 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "id": "Masukkan username dan password Anda", "lv": "Ievadiet savu lietot\u0101ja v\u0101rdu un paroli", "sr": "Unesite va\u0161e korisni\u010dko ime i lozinku", "ro": "V\u0103 rug\u0103m s\u0103 completa\u021bi numele de utilizator \u0219i parola", "xh": "Nceda ngenisa igama lakho lomsebenzisi kunye negama lokugqithisa", "af": "Voer jou gebruikersnaam en wagwoord in", "el": "\u0395\u03b9\u03c3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ba\u03b1\u03b9 \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", "zu": "Faka igama lakho lomsebenzisi nephasiwedi", "st": "Kenya lebitso la mosebedisi le phasewete", "ca": "Introduïu el vostre nom d’usuari i contrasenya" }, "user_pass_text": { "no": "En tjeneste har bedt om bekreftelse p\u00e5 din identitet. Skriv inn ditt brukernavn og passord for \u00e5 autentisere deg.", "nn": "Ei webteneste har spurt etter autentisering av deg. Skriv inn brukarnamnet ditt og passordet ditt for \u00e5 autentisera deg.", "sv": "En webbtj\u00e4nst har beg\u00e4rt att du ska logga in. Detta betyder att du beh\u00f6ver ange ditt anv\u00e4ndarnamn och ditt l\u00f6senord i formul\u00e4ret nedan.", "es": "Un servicio solicita que se autentique. Por favor, introduzca su nombre de usuario y contrase\u00f1a en el siguiente formulario.", "fr": "Un service a demand\u00e9 \u00e0 ce que vous vous authentifiez. Cela signifie que vous devez entrer votre identifiant et votre mot de passe dans le formulaire ci-dessous.", "de": "Um diesen Dienst zu nutzen, m\u00fcssen Sie sich authentifizieren. Bitte geben sie daher unten Nutzernamen und Passwort ein.", "nl": "Voor deze dienst is authenticatie vereist. Geef je gebruikersnaam en wachtwoord in onderstaand formulier.", "lb": "En Service huet ungefrot aerch ze authentifiz\u00e9iren. Daat heescht daer musst aeren Benotzernumm an d'Passwuert an de Formulairen heidr\u00ebnner angin.", "sl": "Storitev zahteva, da se prijavite. To pomeni, da je potreben vnos uporabni\u0161kega imena in gesla v spodnji polji.", "da": "En web-tjeneste har bedt om at tilkendegive dig. Det betyder, at du skal indtaste dit brugernavn og kodeord herunder.", "hr": "Aplikacija zahtjeva od vas da se autentificirate. Unesite va\u0161u korisni\u010dku oznaku i zaporku u dolje navedena polja.", "hu": "Ez a szolg\u00e1ltat\u00e1s megk\u00f6veteli, hogy azonos\u00edtsa mag\u00e1t. K\u00e9rj\u00fck, adja meg felhaszn\u00e1l\u00f3nev\u00e9t \u00e9s jelszav\u00e1t az al\u00e1bbi \u0171rlapon.", "fi": "Palvelu on pyyt\u00e4nyt kirjautumista. Ole hyv\u00e4 ja sy\u00f6t\u00e4 tunnuksesi ja salasanasi alla olevaan kaavakkeeseen.", "pt-br": "Um servi\u00e7o que voc\u00ea pediu necessita que voc\u00ea se autentique. Digite seu nome de usu\u00e1rio e senha no formul\u00e1rio abaixo.", "pt": "Foi pedida a sua autentica\u00e7\u00e3o por um servi\u00e7o. Por favor, introduza o seu nome de utilizador e senha nos campos seguintes.", "pl": "Serwis za\u017c\u0105da\u0142 autentykacji. Prosz\u0119 w poni\u017cszym formularzu wprowadzi\u0107 nazw\u0119 uzytkownika oraz has\u0142o.", "cs": "Slu\u017eba po\u017eaduje va\u0161i identifikaci. Pros\u00edm vlo\u017ete sv\u00e9 jm\u00e9no a heslo.", "tr": "Bir servis kendinizi yetkilendirmenizi istedi. L\u00fctfen a\u015fa\u011f\u0131daki forma kullan\u0131c\u0131 ad\u0131n\u0131z\u0131 ve \u015fifrenizi giriniz.", "lt": "Paslauga pra\u0161o autentikacijos. \u017demiau \u012fveskite savo prisijungimo vard\u0105 ir slapta\u017eod\u012f.", "it": "Un servizio ha richiesto l'autenticazione. Si prega di inserire le proprie credenziali nella maschera di login sottostante.", "ja": "\u30b5\u30fc\u30d3\u30b9\u306f\u3042\u306a\u305f\u81ea\u8eab\u306e\u8a8d\u8a3c\u3092\u8981\u6c42\u3057\u3066\u3044\u307e\u3059\u3002\u4ee5\u4e0b\u306e\u30d5\u30a9\u30fc\u30e0\u306b\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "zh-tw": "\u6709\u500b\u670d\u52d9\u9700\u60a8\u9032\u884c\u9a57\u8b49\uff0c\u8acb\u65bc\u4e0b\u65b9\u8f38\u5165\u5e33\u865f\u5bc6\u78bc\u3002", "et": "Teenus n\u00f5uab autentimist. Palun sisesta allpool olevasse vormi oma kasutajatunnus ja parool.", "he": "\u05e9\u05d9\u05e8\u05d5\u05ea \u05d1\u05d9\u05e7\u05e9 \u05e9\u05ea\u05d6\u05d3\u05d4\u05d4. \u05d0\u05e0\u05d0 \u05d4\u05db\u05e0\u05e1 \u05d0\u05ea \u05e9\u05dd \u05d4\u05de\u05e9\u05ea\u05de\u05e9 \u05d5\u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05e9\u05dc\u05da \u05d1\u05d8\u05d5\u05e4\u05e1 \u05de\u05ea\u05d7\u05ea.", "ru": "\u0421\u043b\u0443\u0436\u0431\u0430 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c.", "zh": "\u4e00\u4e2a\u670d\u52a1\u9700\u8981\u4f60\u7684\u8ba4\u8bc1\uff0c\u8bf7\u5728\u4e0b\u9762\u8f93\u5165\u4f60\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801", "ar": "\u0637\u0644\u0628\u062a \u0627\u062d\u062f\u064a \u0627\u0644\u062e\u062f\u0645\u0627\u062a \u0627\u0646 \u062a\u0648\u062b\u0642 \u0627\u0646\u0643 \u0627\u0646\u062a. \u0631\u062c\u0627\u0621\u0627\u064b \u0642\u0645 \u0628\u0625\u062f\u0631\u0627\u062c \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0648 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631 \u062e\u0627\u0635\u062a\u0643 \u0628\u0627\u0644\u0627\u0633\u062a\u0645\u0627\u0631\u0629 \u0623\u062f\u0646\u0627\u0647", "id": "Sebuah layanan telah meminta Anda untuk melakukan autentifikasi. Silahkan masukkan username dan password Anda pada form dibawah", "lv": "Serviss pieprasa autentifik\u0101ciju. L\u016bdzu ievadiet savu lietot\u0101ja v\u0101rdu un paroli.", "sr": "Servis zahteva od vas da se autentifikujete. Unesite va\u0161e korisni\u010dko ime i lozinku u dole navedena polja.", "ro": "Un serviciu a solicitat autentificarea dumneavoastr\u0103. V\u0103 rug\u0103m s\u0103 completa\u021bi numele de utilizator \u0219i parola \u00een c\u00e2mpurile de mai jos.", "eu": "Zerbitzu batek kautotu zaitezen eskatzen du. Mesedez, zure erabiltzaile-izena eta pasahitza honako formulario honetan sartu itzazu.", "af": "'n Diens vereis dat jy jouself identifiseer. Voer jou gebruikersnaam en wagwoord in die onderstaande vorm in.", "el": "\u039c\u03b9\u03b1 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03b6\u03b7\u03c4\u03ae\u03c3\u03b5\u03b9 \u03c4\u03b7\u03bd \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03ae \u03c3\u03b1\u03c2. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b5\u03b9\u03c3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ba\u03b1\u03b9 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03ae\u03c2 \u03c3\u03b1\u03c2 \u03c3\u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03c4\u03c9 \u03c6\u03cc\u03c1\u03bc\u03b1.", "zu": "Isevisi icele ukuthi uziqinisekise. Sicela ufake igama lakho lomsebenzisi nephasiwedi ngohlobo olungezansi.", "xh": "Inkonzo icele ukuba uzingqinisise. Nceda ungenise igama lomsebenzisi nephaswedi yakho kwifomu ngezantsi.", "st": "Tshebeletso e kopile hore o inetefatse. Ka kopo kenya lebitso la mosebedisi le phasewete ya hao foromong e ka tlase mona.", "ca": "Un servei us ha demanat autenticar-vos. Introduïu el vostre nom d’usuari i contrasenya en el formulari següent." }, "login_button": { "no": "Logg inn", "nn": "Logg inn", "sv": "Logga in", "es": "Iniciar sesi\u00f3n", "fr": "S'identifier", "de": "Anmelden", "nl": "Inloggen", "lb": "Login", "sl": "Prijava", "da": "Login", "se": "Mana sis", "hr": "Prijavi se", "hu": "Bejelentkez\u00e9s", "fi": "Kirjaudu", "pt-br": "Acessar", "pt": "Entrar", "pl": "Login", "cs": "P\u0159ihl\u00e1sit", "eu": "Saioa hasi", "tr": "Giri\u015f", "lt": "Prisijungti", "it": "Login", "ja": "\u30ed\u30b0\u30a4\u30f3", "zh-tw": "\u767b\u5165", "et": "Logi sisse", "he": "\u05db\u05e0\u05d9\u05e1\u05d4", "ru": "\u0412\u043e\u0439\u0442\u0438", "zh": "\u767b\u5f55", "ar": "\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644", "id": "Login", "lv": "Piesl\u0113gties", "sr": "Prijavi se", "ro": "Autentificare", "xh": "Ngena", "af": "Meld aan", "el": "\u0395\u03af\u03c3\u03bf\u03b4\u03bf\u03c2", "zu": "Ngena", "st": "Ho kena", "ca": "Inicia la sessió" }, "processing": { "es": "Procesando...", "sl": "Procesiranje...", "zh-tw": "\u8655\u7406\u4e2d...", "zu": "Iyacubungula...", "xh": "Iyaprosesa...", "st": "E a sebetsa...", "ca": "Processant.." }, "username": { "no": "Brukernavn", "nn": "Brukarnamn", "sv": "Anv\u00e4ndarnamn", "es": "Nombre de usuario", "fr": "Identifiant", "de": "Nutzername", "nl": "Gebruikersnaam", "lb": "Benotzernumm", "sl": "Uporabni\u0161ko ime", "da": "Brugernavn", "se": "Geavahusnamma", "hr": "Korisni\u010dka oznaka", "hu": "Felhaszn\u00e1l\u00f3n\u00e9v", "fi": "Tunnus", "pt-br": "Usu\u00e1rio", "pt": "Nome de utilizador", "pl": "Nazwa u\u017cytkownika", "cs": "U\u017eivatel", "eu": "Erabiltzaile-izena", "tr": "Kullan\u0131c\u0131 ad\u0131", "lt": "Prisijungimo vardas", "it": "Nome utente", "ja": "\u30e6\u30fc\u30b6\u30fc\u540d", "zh-tw": "\u5e33\u865f", "et": "Kasutajatunnus", "he": "\u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9", "ru": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "zh": "\u7528\u6237\u540d", "ar": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645", "id": "Username", "lv": "Lietot\u0101ja v\u0101rds", "sr": "Korisni\u010dko ime", "ro": "Nume de utilizator", "xh": "Igama lomsebenzisi", "af": "Gebruikersnaam", "el": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03a7\u03c1\u03ae\u03c3\u03c4\u03b7", "zu": "Igama lomsebenzisi", "st": "Lebitso la mosebedisi", "ca": "Nom d'usuari" }, "organization": { "no": "Organisasjon", "nn": "Organisasjon", "sv": "Organisation", "es": "Organizaci\u00f3n", "fr": "Fournisseur", "de": "Organisation", "nl": "Organisatie", "lb": "Organisatioun", "sl": "Organizacija", "da": "Organisationsnavn", "se": "Organisa\u0161uvdna", "hr": "Ustanova", "hu": "Szervezet", "fi": "Organisaatio", "pt-br": "Organiza\u00e7\u00e3o", "pt": "Organiza\u00e7\u00e3o", "pl": "Organizacja", "cs": "Organizace", "eu": "Erakundea", "tr": "Organizasyon", "lt": "Organizacija", "it": "Organizzazione", "ja": "\u7d44\u7e54", "zh-tw": "\u7d44\u7e54", "et": "Organisatsioon", "he": "\u05d0\u05d9\u05e8\u05d2\u05d5\u05df", "ru": "\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f", "zh": "\u7ec4\u7ec7", "ar": "\u0627\u0644\u062c\u0647\u0629 ", "id": "Organisasi", "lv": "Organiz\u0101cija", "sr": "Institucija", "ro": "Institu\u021bie", "xh": "Umbutho", "af": "Organisasie", "el": "\u039f\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03cc\u03c2", "zu": "Inhlangano", "st": "Khampani", "ca": "Organització" }, "password": { "no": "Passord", "nn": "Passord", "sv": "L\u00f6senord", "es": "Contrase\u00f1a", "fr": "Mot de passe", "de": "Passwort", "nl": "Wachtwoord", "lb": "Passwuert", "sl": "Geslo", "da": "Kodeord", "se": "Beassans\u00e1tni", "hr": "Zaporka", "hu": "Jelsz\u00f3", "fi": "Salasana", "pt-br": "Senha", "pt": "Senha", "pl": "Has\u0142o", "cs": "Heslo", "eu": "Pasahitza", "tr": "\u015eifre", "lt": "Slapta\u017eodis", "it": "Password", "ja": "\u30d1\u30b9\u30ef\u30fc\u30c9", "zh-tw": "\u5bc6\u78bc", "et": "Parool", "he": "\u05e1\u05d9\u05e1\u05de\u05d4", "ru": "\u041f\u0430\u0440\u043e\u043b\u044c", "zh": "\u5bc6\u7801", "ar": "\u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "id": "Password", "lv": "Parole", "sr": "Lozinka", "ro": "Parola", "xh": "Igama lokugqithisa", "af": "Wagwoord", "el": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2", "zu": "Iphasiwedi", "st": "Phasewete", "ca": "Contrasenya" }, "help_header": { "no": "Hjelp! Jeg har glemt passordet mitt.", "nn": "Hjelp! Eg har gl\u00f8ymd passordet mitt", "sv": "Hj\u00e4lp! Jag kommer inte ih\u00e5g mitt l\u00f6senord.", "es": "\u00a1Ayuda! Se me ha olvidado la contrase\u00f1a.", "fr": "\u00c0 l'aide! Je ne me souviens plus de mon mot de passe.", "de": "Hilfe, ich habe mein Passwort vergessen.", "nl": "Help! Ik weet mijn wachtwoord niet meer.", "lb": "Hellef! Ech hun m\u00e4in Passwuert vergiess!", "sl": "Na pomo\u010d! Pozabil sem svoje geslo.", "da": "Hj\u00e6lp! Jeg har glemt mit kodeord.", "hr": "Upomo\u0107! Zaboravio\/la sam svoju zaporku.", "hu": "Seg\u00edts\u00e9g! Elfelejtettem a jelszavam.", "fi": "Apua! En muista salasanaani", "pt-br": "Ajude-me! N\u00e3o lembro minha senha.", "pt": "N\u00e3o me lembro da minha senha", "pl": "Pomocy! Nie pami\u0119tam has\u0142a.", "cs": "Chci pomoci. Zapomn\u011bl jsem heslo.", "eu": "Lagundu! Ez dut nire pasahitza gogoratzen.", "tr": "Yard\u0131m! \u015eifremi hat\u0131rlam\u0131yorum.", "lt": "Pagalbos! Nepamenu savo slapta\u017eod\u017eio.", "it": "Aiuto! Non ricordo la mia password.", "ja": "\u305f\u3059\u3051\u3066! \u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u601d\u3044\u51fa\u305b\u307e\u305b\u3093\u3002", "zh-tw": "\u6c42\u6551\uff01\u6211\u5fd8\u8a18\u5bc6\u78bc\u4e86\u3002", "et": "Appi! Ma ei m\u00e4leta parooli.", "he": "\u05d4\u05e6\u05d9\u05dc\u05d5! \u05e9\u05db\u05d7\u05ea\u05d9 \u05d0\u05ea \u05d4\u05e1\u05d9\u05e1\u05de\u05d4.", "ru": "\u041f\u043e\u043c\u043e\u0433\u0438\u0442\u0435! \u042f \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u0441\u0432\u043e\u0439 \u043f\u0430\u0440\u043e\u043b\u044c.", "zh": "\u5e2e\u52a9\uff01\u6211\u5fd8\u8bb0\u6211\u7684\u5bc6\u7801\u4e86\uff01", "ar": "\u0633\u0627\u0639\u062f\u0646\u064a! \u0644\u0627 \u0627\u0630\u0643\u0631 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "id": "Tolong! Saya tidak ingat password saya", "lv": "Pal\u012bdziet! Es neatceros paroli.", "sr": "Upomo\u0107! Zaboravio\/la sam svoju lozinku.", "ro": "Nu mai \u0219tiu parola.", "af": "Hulp! Ek het nie my wagwoord onthou nie.", "el": "\u0392\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1! \u0394\u03b5 \u03b8\u03c5\u03bc\u03ac\u03bc\u03b1\u03b9 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03bc\u03bf\u03c5.", "zu": "Siza! Angiyikhumbuli iphasiwedi yami.", "xh": "Ncedani! Andiyikhumbuli iphaswedi yam.", "st": "Thuso! Ha ke hopole phasewete ya ka.", "ca": "Ajuda! No recordo la meva contrasenya." }, "help_text": { "no": "Synd! - Uten riktig brukernavn og passord kan du ikke autentisere deg. Det kan v\u00e6re noen som kan hjelpe deg. Fors\u00f8k \u00e5 kontakt brukerst\u00f8tte ved din vertsorganisasjon.", "nn": "Synd! - Utan riktig brukarnamn og passord kan du ikkje autentisera deg. Ta kontakt med brukarst\u00f8tte hos din organisasjon.", "sv": "Tyv\u00e4rr kan du inte logga in i tj\u00e4nsten om du inte har ditt anv\u00e4ndarnamn och ditt l\u00f6senord. Ta kontakt med din organisations support eller helpdesk f\u00f6r att f\u00e5 hj\u00e4lp.", "es": "Sin su nombre de usuario y contrase\u00f1a no se puede identificar y acceder al servicio. Quiz\u00e1s haya alguien que pueda ayudarle. \u00a1Contacte con el centro de atenci\u00f3n al usuario de su organizaci\u00f3n!", "fr": "Pas de chance! Sans votre identifiant et votre mot de passe vous ne pouvez pas vous authentifier et acc\u00e9der au service. Il y a peut-\u00eatre quelqu'un pour vous aider. Contactez le help desk de votre universit\u00e9!", "de": "Tut uns leid - Ohne Nutzername und Passwort k\u00f6nnen Sie sich nicht authentifizieren und somit den Dienst nicht nutzen. M\u00f6glicherweise kann ihnen jemand helfen, kontaktieren Sie dazu den Helpdesk ihrer Einrichtung.", "nl": "Zonder je gebruikersnaam en wachtwoord kun je je niet authenticeren en dus niet gebruikmaken van deze dienst.", "lb": "Pesch gehaat! - Ouni aeren Benotzernumm an d'Passwuert k\u00ebnn der aerch net authentifiz\u00e9iren an op den Service zougraiffen.", "sl": "\u017dal se brez uporabni\u0161kega imena in gesla ne morete prijaviti in uporabljati storitev.", "da": "Desv\u00e6rre, uden korrekt brugernavn og kodeord kan du ikke f\u00e5 adgang til tjenesten. M\u00e5ske kan help-desk p\u00e5 din hjemmeinstitution hj\u00e6lpe dig!", "hr": "\u0160teta! - Bez ispravne korisni\u010dke oznake i zaporke ne mo\u017eete pristupiti aplikaciji. Da biste saznali va\u0161u zaporku kontaktirajte administratora elektroni\u010dkog (LDAP) imenika va\u0161e ustanove.", "hu": "Ajaj! - Felhaszn\u00e1l\u00f3i neve \u00e9s jelszava n\u00e9lk\u00fcl nem tudja azonos\u00edtani mag\u00e1t, \u00edgy nem f\u00e9rhet hozz\u00e1 a szolg\u00e1ltat\u00e1shoz. Biztosan van valaki, aki tud \u00f6nnek seg\u00edteni. Vegye fel a kapcsolatot az \u00fcgyf\u00e9lszolg\u00e1lattal!", "fi": "Pahus! - Ilman tunnusta ja salasanaa et voi kirjautua palveluun. Voi olla, ett\u00e4 joku voi auttaa sinua. Ole hyv\u00e4 ja ota yhteytt\u00e4 korkeakoulusi tukeen!", "pt-br": "Muito mal! - Sem o seu nome de usu\u00e1rio e a senha voc\u00ea n\u00e3o pode autenticar-se para acessar o servi\u00e7o. Pode haver algu\u00e9m que possa lhe ajudar. Consulte a central de d\u00favidas!", "pt": "Sem o seu nome de utilizador e senha n\u00e3o se pode autenticar para acesso ao servi\u00e7o. Para obter ajuda, consulte o seu servi\u00e7o de apoio ao utilizador.", "pl": "Niedobrze! - Bez nazwy u\u017cytkownika i\/lub has\u0142a nie mo\u017cesz zosta\u0107 uwierzytelniony dla tego serwisu. Mo\u017ce jest kto\u015b, kto mo\u017ce Ci pom\u00f3c. Skonsultuj si\u0119 z dzia\u0142em pomocy technicznej na Twojej uczelni.", "cs": "Probl\u00e9m! Bez jm\u00e9na a hesla se nem\u016f\u017eete identifikovat. Existuje n\u011bkdo kdo v\u00e1m pom\u016f\u017ee. Konzultujte helpdesk va\u0161\u00ed organizace.", "tr": "\u00c7ok k\u00f6t\u00fc! - Kullan\u0131c\u0131 ad\u0131n\u0131z ve \u015fifreniz olmadan bu servisi kullanamazs\u0131n\u0131z. Size yard\u0131mc\u0131 olabilecek birileri olabilir. Kurulu\u015funuza dan\u0131\u015f\u0131n. ", "lt": "Blogai - be prisijungimo vardo ir slapta\u017eod\u017eio negal\u0117site autentikuotis ir patekti \u012f reikiam\u0105 paslaug\u0105. Galb\u016bt yra kas Jums gal\u0117t\u0173 pad\u0117ti. Susisiekite su savo universiteto vartotoj\u0173 aptarnavimo specialistais.", "it": "Senza il nome utente e la password, non \u00e8 possibile effettuare l'autenticazione al servizio. C'\u00e8 probabilmente qualcuno che pu\u00f2 fornire aiuto. Consultare il proprio help desk.", "ja": "\u304a\u6c17\u306e\u6bd2\u3067\u3059! - \u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u7121\u304f\u3066\u306f\u30b5\u30fc\u30d3\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u70ba\u306b\u3042\u306a\u305f\u81ea\u8eab\u3092\u8a8d\u8a3c\u3059\u308b\u4e8b\u304c\u51fa\u6765\u307e\u305b\u3093\u3002\u3042\u306a\u305f\u306e\u5927\u5b66\u306e\u30d8\u30eb\u30d7\u30c7\u30b9\u30af\u306b\u76f8\u8ac7\u3059\u308b\u3068\u3001\u3042\u306a\u305f\u306e\u52a9\u3051\u306b\u306a\u3063\u3066\u304f\u308c\u308b\u3067\u3057\u3087\u3046\u3002", "zh-tw": "\u6c92\u6709\u60a8\u7684\u5e33\u865f\u5bc6\u78bc\u7684\u8a71\u5c07\u6703\u7121\u6cd5\u5b58\u53d6\u670d\u52d9\u5537\uff01\u8acb\u806f\u7e6b\u60a8\u7684\u7d44\u7e54\u670d\u52d9\u53f0\uff0c\u4e5f\u8a31\u6703\u6709\u4eba\u80fd\u5e6b\u52a9\u4f60\u3002", "et": "Paha lugu! Ilma kasutajatunnust ja parooli teadmata pole v\u00f5imalik seda teenust kasutada. Loodetavasti saab sind keegi aidata. V\u00f5ta \u00fchendust oma \u00fclikooli kasutajatoeteenusega!", "he": "\u05d7\u05d1\u05dc! - \u05d1\u05dc\u05d9 \u05e9\u05dd \u05d4\u05de\u05e9\u05ea\u05de\u05e9 \u05d5\u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05e9\u05dc\u05da \u05d0\u05ea\u05d4 \u05dc\u05d0 \u05d9\u05db\u05d5\u05dc \u05dc\u05d4\u05d6\u05d3\u05d4\u05d5\u05ea \u05d1\u05db\u05d3\u05d9 \u05dc\u05d2\u05e9\u05ea \u05dc\u05e9\u05d9\u05e8\u05d5\u05ea. \u05d9\u05db\u05d5\u05dc \u05dc\u05d4\u05d9\u05d5\u05ea \u05e9\u05d9\u05e9 \u05de\u05d9\u05e9\u05d4\u05d5 \u05e9\u05d9\u05db\u05d5\u05dc \u05dc\u05e2\u05d6\u05d5\u05e8 \u05dc\u05da. \u05e4\u05e0\u05d4 \u05dc\u05ea\u05de\u05d9\u05db\u05d4 \u05d4\u05d8\u05db\u05e0\u05d9\u05ea \u05d1\u05d0\u05d5\u05e0\u05d9\u05d1\u05e8\u05e1\u05d9\u05d8\u05d4 \u05e9\u05dc\u05da!", "ru": "\u041e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0445\u043e! - \u0411\u0435\u0437 \u0432\u0430\u0448\u0438\u0445 \u0438\u043c\u0435\u043d\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044f \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0432\u0430\u0448\u0435 \u043f\u0440\u0430\u0432\u043e \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u043b\u0443\u0436\u0431\u0435. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0435\u0441\u0442\u044c \u043a\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c, \u043a\u0442\u043e \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0430\u043c. \u041f\u0440\u043e\u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c \u0441\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0432 \u0432\u0430\u0448\u0435\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0435!", "zh": "\u592a\u7cdf\u7cd5\u4e86\uff01-\u6ca1\u6709\u4f60\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u4f60\u5c06\u4e0d\u80fd\u8bbf\u95ee\u8be5\u670d\u52a1\uff0c\u4e5f\u8bb8\u6709\u4eba\u80fd\u591f\u5e2e\u52a9\u4f60\uff0c\u8bf7\u54a8\u8be2\u4f60\u6240\u5728\u5927\u5b66\u7684\u670d\u52a1\u53f0", "ar": "\u0644\u0633\u0648\u0621 \u0627\u0644\u062d\u0638 \u0644\u0627 \u064a\u0645\u0643\u0646\u0646\u0627 \u0627\u0644\u062a\u0648\u062b\u0642 \u0645\u0646 \u0647\u0648\u064a\u062a\u0643 \u0628\u062f\u0648\u0646 \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0648 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631 \u0648\u0628\u0627\u0644\u062a\u0627\u0644\u064a \u0644\u0627 \u064a\u0645\u0643\u0646\u0643 \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0627\u0644\u062e\u062f\u0645\u0629. \u0644\u0644\u0645\u0633\u0627\u0639\u062f\u0629 \u0627\u062a\u0635\u0644 \u0628\u0627\u0644\u0645\u0648\u0638\u0641 \u0627\u0644\u0645\u0633\u0624\u0648\u0644 \u0628\u0635\u0641\u062d\u0629 \u0627\u0644\u0645\u0633\u0627\u0639\u062f\u0629 \u0628\u062c\u0627\u0645\u0639\u062a\u0643", "id": "Sayang sekali! - Tanpa username dan password Anda tidak dapat melakukan autentifikasi agar dapat mengakses layanan. Mungkin ada seseorang yang dapat menolong Anda. Hubungi help desk pada universitas Anda.", "lv": "Bez lietot\u0101ja v\u0101rda un paroles J\u016bs nevarat autentific\u0113ties un nevarat izmantot servisu. Iesp\u0113jams, ir k\u0101ds, kas var Jums pal\u012bdz\u0113t. Vaic\u0101jiet savas universit\u0101tes pal\u012bdz\u012bbas dienestam.", "sr": "\u0160teta! - Bez ispravnog korisni\u010dkog imena i lozinke ne mo\u017eete pristupiti servisu. Da biste saznali va\u0161e korisni\u010dko ime i lozinku obratite se va\u0161oj mati\u010dnoj instituciji.", "ro": "Din p\u0103cate f\u0103r\u0103 nume de utilizator \u0219i parol\u0103 nu v\u0103 pute\u021bi autentifica pentru accesul la acest serviciu. Contacta\u021bi echipa de suport tehnic de la universitatea dumneavoastr\u0103.", "eu": "Zeinen txarto! - Zure erabiltziale-izena eta pasahitza gabe ezin zara identifikatu ezta zerbitzuan sartu ere. Agian bada norbait lagun diezazukeena. Jar zaitez harremanetan erakundeko laguntza zentroarekin!", "af": "Jammer! - Sonder jou gebruikersnaam en wagwoord kan jy jouself nie vir toegang tot die diens identifiseer nie. Dalk is daar iemand wat jou kan help. Raadpleeg die hulplyn by jou organisasie!", "el": "\u039b\u03c5\u03c0\u03bf\u03cd\u03bc\u03b1\u03c3\u03c4\u03b5. \u03a7\u03c9\u03c1\u03af\u03c2 \u03c4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ba\u03b1\u03b9 \u03c4\u03bf\u03bd \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c3\u03b1\u03c2, \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c4\u03b1\u03c5\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af\u03c4\u03b5 \u03ce\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03ba\u03c4\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1. \u03a3\u03c5\u03bc\u03b2\u03bf\u03c5\u03bb\u03b5\u03c5\u03c4\u03b5\u03af\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03b1\u03c1\u03c9\u03b3\u03ae\u03c2 \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd \u0028\u0068\u0065\u006c\u0070 \u0064\u0065\u0073\u006b\u0029 \u03c4\u03bf\u03c5 \u03bf\u03c1\u03b3\u03b1\u03bd\u03b9\u03c3\u03bc\u03bf\u03cd \u03c3\u03b1\u03c2.", "xh": "Ngaphandle kwegama lomsebenzisi nephaswedi yakho awukwazi ukuzingqinisisa ukuze ufumane ufikelelo kwinkonzo. Kusenokuba ukho umntu onokukunceda. Qhagamshelana nedesika yoncedo kumbutho wakho!", "zu": "Ngaphandle kwegama lakho lomsebenzisi nephasiwedi awukwazi ukuziqinisekisa ukuze ufinyelele isevisi. Kungase kube khona ozokusiza. Thinta ideski losizo enhlanganweni yakho!", "st": "Ntle le lebitso l ahao la mosebedisi le phasewete o ke ke wa inetefatsa bakeng sa phihlello ho tshebeletso. Ho ka nna ha ba le motho ya ka o thusang. Ikopanye le ba deske ya thuso khampaning ya heno!", "ca": "Sense el vostre nom d'usuari i contrasenya, no podeu autenticar-vos per accedir al servei. Pot ser que algú us pugui ajudar. Poseu-vos en contacte amb el centre d'atenció a l'usuari" }, "error_nopassword": { "no": "Du kontaktet loginsiden, men passordet ble ikke sendt med. Fors\u00f8k igjen.", "nn": "Passordet blei ikkje sendt. Pr\u00f8v p\u00e5 nytt.", "sv": "Du skicka in en inloggningsf\u00f6rfr\u00e5gan men det verkar som om ditt l\u00f6senord inte fanns med i f\u00f6rfr\u00e5gan. F\u00f6rs\u00f6k igen!", "es": "Usted envi\u00f3 algo a la p\u00e1gina de acceso pero, por alguna raz\u00f3n, no se envi\u00f3 la contrase\u00f1a. Int\u00e9ntelo de nuevo, por favor.", "fr": "Vous avez envoy\u00e9 quelque chose sur la page d'identification mais pour une raison inconnue votre mot de passe n'a pas \u00e9t\u00e9 transmis. Veuillez r\u00e9essayer.", "de": "Sie haben etwas an die Anmeldeseite geschickt, aber aus irgendeinem Grund ist das Passwort nicht \u00fcbermittelt worden. Bitte versuchen Sie es erneut.", "nl": "Je hebt wel iets ingetikt, maar blijkbaar is je wachtwoord niet verstuurd. Probeer het opnieuw AUB.", "lb": "Der hud eppes un d'Login Sait gesch\u00e9eckt me aus iergentengem Grond huet d Passwuert gefehlt. Prob\u00e9iert w.e.g nach eng K\u00e9ier.", "sl": "Pri\u0161lo je do napake, poskusite znova.", "da": "Dit kodeord blev ikke sendt - pr\u00f8v igen.", "hr": "Iz nekog razloga autentifikacijskom servisu nije proslije\u0111ena va\u0161a zaporka. Molimo poku\u0161ajte ponovo.", "hu": "Valamilyen okn\u00e1l fogva a jelsz\u00f3 nem olvashat\u00f3. K\u00e9rj\u00fck, pr\u00f3b\u00e1lja \u00fajra!", "fi": "L\u00e4hetit jotain kirjautumissivulle, mutta jostain syyst\u00e4 salasanaa ei l\u00e4hetetty. Ole hyv\u00e4 ja yrit\u00e4 uudestaan.", "pt-br": "Voc\u00ea enviou alguma coisa para a p\u00e1gina de login, mas por alguma raz\u00e3o a senha n\u00e3o foi enviada. Por favor tente novamente.", "pt": "A senha n\u00e3o foi enviada no seu pedido. Por favor tente de novo.", "pl": "Wys\u0142a\u0142e\u015b \"co\u015b\" do strony logowania, ale z jaki\u015b powod\u00f3w has\u0142o nie zosta\u0142o wys\u0142ane. Spr\u00f3buj jeszcze raz.", "cs": "Odeslal jste data do p\u0159ihla\u0161ovac\u00ed stranky, ale z n\u011bjak\u00e9ho d\u016fvodu nebylo odesl\u00e1no heslo. Pros\u00edm zkuste to znovu.", "tr": "Giri\u015f sayfas\u0131na bir\u015feyler g\u00f6nderdiniz, fakat baz\u0131 nedenlerden dolay\u0131 \u015fifreniz g\u00f6nderilemedi. L\u00fctfen tekrar deneyiniz.", "lt": "J\u016bs ka\u017ek\u0105 nusiunt\u0117te \u012f prisijungimo puslap\u012f, ta\u010diau d\u0117l ka\u017ekoki\u0173 prie\u017eas\u010di\u0173 slapta\u017eodis nebuvo nusi\u0173stas. Pra\u0161ome bandyti dar kart\u0105.", "it": "Sono state inviate delle informazioni alla pagina di login, ma per qualche motivo la password risulta mancante. Si prega di riprovare.", "ja": "\u3042\u306a\u305f\u306f\u30ed\u30b0\u30a4\u30f3\u30da\u30fc\u30b8\u3067\u4f55\u304b\u3092\u9001\u4fe1\u3057\u307e\u3057\u305f\u304c\u3001\u4f55\u3089\u304b\u306e\u7406\u7531\u3067\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u9001\u4fe1\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u518d\u5ea6\u8a66\u3057\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002", "zh-tw": "\u60a8\u7684\u78ba\u50b3\u9001\u4e86\u4e00\u4e9b\u8a0a\u606f\u81f3\u767b\u5165\u9801\u9762\uff0c\u4f46\u662f\u5bc6\u78bc\u4f3c\u4e4e\u672a\u88ab\u9001\u51fa\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002", "et": "Sa saatsid midagi sisselogimislehele, kuid miskip\u00e4rast parooli ei saadetud. Palun proovi uuesti.", "he": "\u05e9\u05dc\u05d7\u05ea \u05de\u05e9\u05d4\u05d5 \u05dc\u05d3\u05e3 \u05d4\u05db\u05e0\u05d9\u05e1\u05d4 \u05dc\u05de\u05e2\u05e8\u05db\u05ea, \u05d0\u05d1\u05dc \u05d1\u05d2\u05dc\u05dc \u05e1\u05d9\u05d1\u05d4 \u05db\u05dc \u05e9\u05d4\u05d9\u05d0 \u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05dc\u05d0 \u05e0\u05e9\u05dc\u05d7\u05d4. \u05d1\u05d1\u05e7\u05e9\u05d4 \u05e0\u05e1\u05d4 \u05e9\u05d5\u05d1.", "ru": "\u0412\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u0445\u043e\u0434\u0430, \u043d\u043e \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435 \u043f\u043e\u0441\u043b\u0430\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.", "zh": "\u4f60\u786e\u5b9e\u53d1\u9001\u4e86\u4e00\u4e9b\u4fe1\u606f\u7ed9\u767b\u5f55\u9875\u9762\uff0c\u4f46\u7531\u4e8e\u67d0\u4e9b\u539f\u56e0\uff0c\u4f60\u6ca1\u6709\u53d1\u9001\u5bc6\u7801\uff0c\u8bf7\u518d\u8bd5\u4e00\u6b21", "ar": "\u0644\u0642\u062f \u0642\u0645\u062a \u0628\u0625\u0631\u0633\u0627\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0644\u0635\u0641\u062d\u0629 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0643\u0646 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631 \u063a\u064a\u0631 \u0645\u0631\u0641\u0642\u0629. \u0631\u062c\u0627\u0621\u0627\u064b \u0627\u0639\u062f \u0627\u0644\u0645\u062d\u0627\u0648\u0644\u0629", "id": "Anda mengirimkan sesuatu ke halaman login, tetapi karena suatu alasan tertentu password tidak terkirimkan, Silahkan coba lagi.", "lv": "Kaut k\u0101du iemeslu d\u0113\u013c parole nav nos\u016bt\u012bta. L\u016bdzu m\u0113\u0123iniet v\u0113lreiz.", "sr": "Iz nekog razloga autentifikacionom servisu nije prosle\u0111ena va\u0161a lozinka. Molimo poku\u0161ajte ponovo.", "ro": "A\u021bi trimis informa\u021bii c\u0103tre pagina de autentificare dar din motive necunoscute parola nu a fost trimis\u0103. V\u0103 rug\u0103m s\u0103 \u00eencerca\u021bi din nou.", "eu": "Sarrera orrira zerbait bidali duzu baina, arrazoiren bategatik, pasahitza ez da bidali.Saia zaitez berriro, mesedez.", "af": "Jy het probeer aanmeld maar jou wagwoord is nie verstuur nie, probeer asb. weer.", "el": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b4\u03b5\u03bd \u03b5\u03c3\u03c4\u03ac\u03bb\u03b7. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce, \u03c0\u03c1\u03bf\u03c3\u03c0\u03b1\u03b8\u03ae\u03c3\u03c4\u03b5 \u03be\u03b1\u03bd\u03ac.", "zu": "Uthumele okuthile ekhasini lokungena, kodwa ngasizathu simbe iphasiwedi ayizange ithunyelwe. Sicela uzame futhi.", "xh": "Uthumele into kwikhasi lokungena, kodwa ngesizathu esithile iphaswedi ayithunyelwanga. Nceda uzame kwakhona.", "st": "o Rometse se seng leqepheng la ho kena, empa ka lebaka le sa tsejweng phaewete ha e a romelwa. Ka kopo leka hape.", "ca": "Heu enviat alguna cosa a la pàgina d’inici de sessió, però per alguna raó la contrasenya no s’ha enviat. Torneu-ho a provar." }, "error_wrongpassword": { "no": "Feil brukernavn eller passord.", "nn": "Feil brukarnamn eller passord.", "sv": "Fel anv\u00e4ndarnamn eller l\u00f6senord.", "es": "Nombre de usuario o contrase\u00f1a incorrectos", "fr": "Mauvais identifiant ou mot de passe.", "de": "Falscher Nutzername oder Passwort.", "nl": "Gebruikersnaam of wachtwoord niet bekend.", "lb": "Falschen Benotzernumm oder Passwuert", "sl": "Napa\u010dno uporabni\u0161ko ime ali geslo!", "da": "Forkert brugernavn eller kodeord.", "se": "Boastu geavahusnamma, beassans\u00e1tni dehe organisa\u0161uvdna.", "hr": "Neispravna korisni\u010dka oznaka ili zaporka.", "hu": "Hib\u00e1s felhaszn\u00e1l\u00f3i n\u00e9v vagy jelsz\u00f3!", "fi": "V\u00e4\u00e4r\u00e4 tunnus tai salasana.", "pt-br": "Nome de usu\u00e1rio ou senha incorretos.", "pt": "Nome de utilizador ou senha incorrecta.", "pl": "Nieprawid\u0142owa nazwa u\u017cytkownika lub has\u0142o.", "cs": "Nekorektn\u00ed jmeno nebo heslo.", "eu": "Erabiltzaile-izena edo pasahitza okerra", "tr": "Kullan\u0131c\u0131 ad\u0131 ve\/veya \u015fifre yanl\u0131\u015f.", "lt": "Neteisingas prisijungimo vardas arba slapta\u017eodis.", "it": "Nome utente o password errati.", "ja": "\u30e6\u30fc\u30b6\u30fc\u540d\u304b\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u9593\u9055\u3063\u3066\u3044\u307e\u3059\u3002", "zh-tw": "\u932f\u8aa4\u7684\u5e33\u865f\u6216\u5bc6\u78bc\u3002", "et": "Kasutajatunnus v\u00f5i parool pole \u00f5ige.", "he": "\u05e1\u05d9\u05e1\u05de\u05d4 \u05d0\u05d5 \u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9 \u05dc\u05d0 \u05e0\u05db\u05d5\u05e0\u05d9\u05dd.", "ru": "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c.", "zh": "\u9519\u8bef\u7684\u7528\u6237\u540d\u6216\u8005\u5bc6\u7801", "ar": " \u0627\u0633\u0645 \u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0648 \u0643\u0644\u0645\u0629 \u0633\u0631 \u062e\u0637\u0627", "id": "Username atau password salah", "lv": "Nekorekts lietot\u0101ja v\u0101rds vai parole.", "sr": "Neispravno korisni\u010dko ime ili lozinka.", "ro": "Nume de utilizator incorect sau parola incorect\u0103.", "xh": "Awungenanga ngoba igama olisebenzisayo okanye isigqithisi asifakwanga kakuhle.", "af": "Verkeerde gebruikersnaam of wagwoord.", "el": "\u03a4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ae \u03bf \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03bb\u03ac\u03b8\u03bf\u03c2.", "zu": "Igama lomsebenzisi noma iphasiwedi engalungile.", "st": "Lebitso la mosebedisi kapa phasewete e fosahetse.", "ca": "Nom d'usuari o contrasenya incorrecta." }, "contact_info": { "no": "Kontaktinformasjon:", "nn": "Kontaktinformasjon:", "sv": "Kontaktinformation:", "es": "Informaci\u00f3n de contacto:", "fr": "Coordonn\u00e9es :", "de": "Kontakt", "nl": "Contactinformatie", "sl": "Kontakt", "da": "Kontaktoplysninger", "hr": "Kontakt podaci:", "hu": "El\u00e9r\u00e9si inform\u00e1ci\u00f3k", "fi": "Yhteystiedot", "pt-br": "Informa\u00e7\u00f5es de Contato", "pt": "Contactos:", "pl": "Informacje kontaktowe:", "cs": "Kontaktn\u00ed informace", "eu": "Harremanetarako informazioa:", "tr": "\u0130leti\u015fim bilgileri:", "lt": "Kontaktai:", "it": "Informazioni di contatto:", "ja": "\u9023\u7d61\u5148:", "zh-tw": "\u806f\u7d61\u8cc7\u8a0a\uff1a", "et": "Kontaktinfo:", "he": "\u05e6\u05d5\u05e8 \u05e7\u05e9\u05e8", "ru": "\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f", "zh": "\u8054\u7cfb\u65b9\u5f0f", "ar": "\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0627\u062a\u0635\u0627\u0644", "id": "Informasi Kontak", "lv": "Kontaktinform\u0101cija", "sr": "Kontakt podaci:", "ro": "Informa\u021bii de contact:", "af": "Kontak detail:", "el": "\u03a3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1\u03c2:", "zu": "Ulwazi lokuxhumana:", "xh": "Inkcazelo yoqhagamshelwano:", "st": "Tlhahisoleseding ya boikopanyo:", "ca": "Informació de contacte:" }, "select_home_org": { "no": "Velg vertsorganisasjon", "nn": "Vel vertsorganisasjon", "sv": "V\u00e4lj vilken organisation du kommer ifr\u00e5n", "es": "Seleccione su organizaci\u00f3n de origen", "fr": "Choisissez votre fournisseur.", "de": "W\u00e4hlen sie die Einrichtung, von der Sie ihre Zugangsdaten beziehen", "nl": "Kies je organisatie", "sl": "Izberite va\u0161o doma\u010do organizacijo", "da": "V\u00e6lg din hjemmeinstitution", "hr": "Odaberite va\u0161u mati\u010dnu ustanovu", "hu": "V\u00e1lassza ki az \u00f6n szervezet\u00e9t", "fi": "Valitse kotiorganisaatiosi", "pt-br": "Escolha a sua organiza\u00e7\u00e3o principal", "pt": "Escolha a sua organiza\u00e7\u00e3o de origem", "pl": "Wybierz swoj\u0105 domow\u0105 organizacj\u0119", "cs": "Zvolte svou organizaci", "tr": "Organizasyonunuzu se\u00e7iniz", "lt": "Pasirinkite savo organizacij\u0105", "it": "Selezionare la propria organizzazione", "ja": "\u3042\u306a\u305f\u306e\u7d44\u7e54\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044", "zh-tw": "\u9078\u64c7\u60a8\u7684\u6240\u5c6c\u7d44\u7e54", "et": "Vali oma koduorganisatsioon", "he": "\u05d1\u05d7\u05e8 \u05d0\u05ea \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea \u05e9\u05dc\u05da", "ru": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e", "zh": "\u9009\u62e9\u4f60\u7684\u7ec4\u7ec7", "ar": "\u0627\u062e\u062a\u0627\u0631 \u062c\u0647\u062a\u0643 \u0627\u0644\u0627\u0645", "id": "Pilih Basis Organisasi Anda", "lv": "Izv\u0113lieties organiz\u0101ciju", "sr": "Izaberite va\u0161u mati\u010dnu instituciju", "ro": "Alege\u021bi institu\u021bia de origine", "eu": "Hautatu zure jatorrizko erakundea", "af": "Kies jou tuisorganisasie", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03c6\u03bf\u03c1\u03ad\u03b1", "xh": "Khetha umbutho wakho wekhaya", "zu": "Khetha inhlangano yakho yasekhaya", "st": "Kgetha khampani ya lehae ya hao", "ca": "Trieu la vostra organització principal" }, "change_home_org_title": { "no": "Endre din vertsorganisasjon", "nn": "Endra vertsorganisasjon", "sv": "\u00c4ndra vilken organisation du kommer ifr\u00e5n", "es": "Cambiar la organizaci\u00f3n de origen", "fr": "Changez votre fournisseur", "de": "Eine andere Einrichtung, von der Sie Zugangsdaten erhalten, ausw\u00e4hlen", "nl": "Verander je organisatie", "sl": "Izberite va\u0161o doma\u010do organizacijo.", "da": "Skift hjemmeinstitution", "hr": "Promjenite odabir va\u0161e mati\u010dne ustanove", "hu": "V\u00e1lasszon m\u00e1sik szervezetet", "fi": "Muuta kotiorganisaatiotasi", "pt-br": "Mudar a organiza\u00e7\u00e3o principal", "pt": "Alterar a sua organiza\u00e7\u00e3o de origem", "pl": "Zmie\u0144 swoj\u0105 domow\u0105 organizacj\u0119", "cs": "Zm\u011bnte svou organizaci", "tr": "Organizasyonunuzu de\u011fi\u015ftirin", "lt": "Pakeisti savo organizacij\u0105", "it": "Cambiare la propria organizzazione", "ja": "\u3042\u306a\u305f\u306e\u7d44\u7e54\u3092\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044", "zh-tw": "\u8b8a\u66f4\u60a8\u7684\u6240\u5c6c\u7d44\u7e54", "et": "Muuda oma koduorganisatsiooni", "he": "\u05d4\u05d7\u05dc\u05e3 \u05d0\u05ea \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea \u05e9\u05dc\u05da", "ru": "\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e", "zh": "\u6539\u53d8\u4f60\u7684\u5bb6\u5ead\u7ec4\u7ec7", "ar": "\u063a\u064a\u0631\u0627\u0644\u062c\u0647\u0629 \u0627\u0644\u0627\u0645", "id": "Ubah basis organisasi anda", "lv": "Main\u012bt organiz\u0101ciju", "sr": "Promenite izbor za va\u0161u mati\u010dnu instituciju", "ro": "Modifica\u021bi institu\u021bia de origine", "eu": "Zure jatorrizko erakundea aldatu", "af": "Verander jou tuisorganisasie", "el": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03c6\u03bf\u03c1\u03ad\u03b1", "xh": "Tshintsha umbutho wakho wekhaya", "zu": "Shintsha inhlangano yakho yasekhaya", "st": "Fetola khampani ya lehae ya heno", "ca": "Canvieu la vostra organització principal" }, "change_home_org_text": { "no": "Du har valgt %HOMEORG%<\/b> som din vertsorganisasjon. Dersom dette er feil kan du velge en annen.", "nn": "Du har vald %HOMEORG%<\/b> som din vertsorganisasjon. Dersom dette er feil, kan du velja ein annan organisasjon fr\u00e5 menyen.", "sv": "Du har valt %HOMEORG%<\/b> som organisation du kommer ifr\u00e5n. Om detta \u00e4r fel s\u00e5 kan du v\u00e4lja en annan.", "es": "Ha seleccionado %HOMEORG%<\/b> como organizaci\u00f3n de origen. Si esta informaci\u00f3n es incorrecta, puede seleccionar otra.", "fr": "Vous avez choisi %HOMEORG%<\/b> comme votre fournisseur. Si ce n'est pas correct, vous pouvez le changer.", "de": "Sie haben %HOMEORG%<\/b> als ihre Einrichtung gew\u00e4hlt, k\u00f6nnen diese Auswahl aber noch \u00e4ndern.", "nl": "Je hebt %HOMEORG%<\/b> gekozen als je organisatie. Als dit niet correct is kun je een andere keuze maken.", "sl": "Izbrali ste %HOMEORG%<\/b> kot va\u0161o doma\u010do organizacijo. V primeru da je izbor napa\u010den, izberite drugo.", "da": "Du har valgt %HOMEORG%<\/b> som din hjemmeinstitution. Hvis dette ikke er korrekt, kan du v\u00e6lge en anden.", "hr": "Odabrali ste %HOMEORG%<\/b> kao va\u0161u mati\u010dnu ustanovu. Ako to nije to\u010dno mo\u017eete odabrati drugu ustanovu.", "hu": "A %HOMEORG%<\/b> szervezetet v\u00e1lasztotta ki. Ha a v\u00e1laszt\u00e1s nem volt helyes, k\u00e9rem v\u00e1lasszon m\u00e1sikat.", "fi": "Olet valinnut kotiorganisaatioksesi %HOMEORG%<\/b> . Voit muuttaa asetusta valitsemalla toisen.", "pt-br": "Voc\u00ea escolheu %HOMEORG%<\/b> como sua organiza\u00e7\u00e3o pessoal. Se isto estiver incorreto voc\u00ea pode escolher outra.", "pt": "Escolheu %HOMEORG%<\/b> como a sua organiza\u00e7\u00e3o de origem. Se n\u00e3o estiver correcto, pode escolher outra.", "pl": "Wybra\u0142e\u015b %HOMEORG%<\/b> jako swoj\u0105 domow\u0105 organizacj\u0119. Je\u015bli nieprawid\u0142owa mo\u017cesz wybra\u0107 inn\u0105.", "cs": "M\u00e1te nastavenu %HOMEORG%<\/b> jako domovskou organizaci. Pokud je to \u0161patn\u011b zvolte jinou.", "tr": "%HOMEORG%<\/b>'u organizasyonunuz olarak se\u00e7tiniz. E\u011fer yanl\u0131\u015f ise, ba\u015fka bir tanesini se\u00e7ebilirsiniz.", "lt": "J\u016bs savo nam\u0173 organizacija pasirinkote %HOMEORG%<\/b>. Jei tai yra neteisingas pasirinkimas, galite pasirinkti kit\u0105.", "it": "E' stata selezionata %HOMEORG%<\/b> come propria organizzazione. Se \u00e8 sbagliata, \u00e8 possibile selezionarne un'altra.", "ja": "\u3042\u306a\u305f\u306f %HOMEORG%<\/b> \u3092\u7d44\u7e54\u3068\u3057\u3066\u9078\u629e\u3057\u307e\u3057\u305f\u3002\u3053\u308c\u306b\u554f\u984c\u304c\u3042\u308b\u5834\u5408\u306f\u4ed6\u306e\u3082\u306e\u3092\u9078\u3076\u4e8b\u3082\u53ef\u80fd\u3067\u3059\u3002", "zh-tw": "\u60a8\u5df2\u9078\u64c7 %HOMEORG%<\/b> \u4f5c\u70ba\u6240\u5c6c\u7d44\u7e54\u3002\u5982\u679c\u932f\u8aa4\uff0c\u60a8\u96a8\u6642\u90fd\u53ef\u4ee5\u91cd\u65b0\u9078\u64c7\u5176\u4ed6\u7684\u3002", "et": "Sa valisid oma koduorganisatsiooniks %HOMEORG%<\/b>. Kui see pole \u00f5ige, siis v\u00f5id uuesti valida.", "he": "\u05d1\u05d7\u05e8\u05ea \u05d0\u05ea %HOMEORG%<\/b> \u05db\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d4\u05d1\u05d9\u05ea \u05e9\u05dc\u05da. \u05d0\u05dd \u05d4\u05de\u05d9\u05d3\u05e2 \u05de\u05d5\u05d8\u05e2\u05d4 \u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05d1\u05d7\u05d5\u05e8 \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d0\u05d7\u05e8.", "ru": "\u0412\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 %HOMEORG%<\/b> \u043a\u0430\u043a \u0432\u0430\u0448\u0443 \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e. \u0415\u0441\u043b\u0438 \u0432\u044b \u043e\u0448\u0438\u0431\u043b\u0438\u0441\u044c - \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e.", "zh": "\u4f60\u9009\u62e9\u4e86%HOMEORG%<\/b>\u4f5c\u4e3a\u4f60\u7684\u5bb6\u5ead\u7ec4\u7ec7\u3002\u5982\u679c\u9519\u4e86\u8bf7\u9009\u62e9\u5176\u4ed6\u7684", "ar": "\u0644\u0642\u062f \u0642\u0645\u062a \u0628\u0627\u062e\u062a\u064a\u0627\u0631 %HOMEORG%<\/b> \u0643\u062c\u0647\u062a\u0643 \u0627\u0644\u0627\u0645. \u0627\u0646 \u0643\u0627\u0646 \u0647\u0630\u0627 \u0627\u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u063a\u064a\u0631 \u0635\u062d\u064a\u062d \u064a\u0645\u0643\u0646\u0643 \u062a\u063a\u064a\u064a\u0631\u0647", "id": "Anda telah memilih %HOMEORG%<\/b> sebagai basis organisasi anda. Jika ini salah anda dapat memilih yang lain.", "lv": "J\u016bs izv\u0113l\u0113j\u0101ties %HOMEORG%<\/b>. ja tas nav pareizi, izv\u0113lieties citu.", "sr": "Odabrali ste %HOMEORG%<\/b> kao va\u0161u mati\u010dnu instituciju. Ako to nije ta\u010dno mo\u017eete odabrati drugu instituciju.", "ro": "A\u021bi ales ca institu\u021bie de origine%HOMEORG%<\/b>. Dac\u0103 nu este corect v\u0103 rug\u0103m s\u0103 alege\u021bi alt\u0103 institu\u021bie.", "eu": "%HOMEORG%<\/b> hautatu duzu zure jatorrizko erakunde bezala. Informazio hau okerra bada beste bat hautatu dezakezu.", "af": "Jy het %HOMEORG%<\/b> gekies as jou tuisorganisasie. As dit is verkeerd jy kan 'n ander een te kies.", "el": "\u0395\u03c0\u03b9\u03bb\u03b5\u03b3\u03bc\u03ad\u03bd\u03bf\u03c2 \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c2 \u03c6\u03bf\u03c1\u03ad\u03b1\u03c2: %HOMEORG%<\/b>.", "zu": "Ukhethe okuthi %HOMEORG% njengenhlangano yakho yasekhaya. Uma lokhu kungalungile ungase ukhethe enye.", "xh": "Uye wakhetha u-%HOMEORG% njengombutho wakho wekhaya. Ukuba oku akuchanekanga usenokukhetha omnye.", "st": "O kgethile %HOMEORG% jwalo ka khampani ya lehae ya heno. Haeba sena se fosahetse o ka kgetha e nngwe hape.", "ca": "Heu triat %HOMEORG%<\/b> com la vostra organització principal. Si això no és correcte, podeu triar-ne una altra." }, "change_home_org_button": { "no": "Velg vertsorganisasjon", "nn": "Vel vertsorganisasjon", "sv": "\u00c4ndra organisation", "es": "Seleccione su organizaci\u00f3n de origen", "fr": "Choisissez votre fournisseur.", "de": "Einrichtung ausw\u00e4hlen", "nl": "Kies je organisatie", "sl": "Izberite doma\u010do organizacijo.", "da": "V\u00e6lg hjemmeinstitution", "hr": "Odaberite mati\u010dnu ustanovu", "hu": "V\u00e1lassza ki a szervezet\u00e9t", "fi": "Valitse kotiorganisaatiosi", "pt-br": "Escolher uma organiza\u00e7\u00e3o principal", "pt": "Escolha a sua organiza\u00e7\u00e3o de origem", "pl": "Wybierz domow\u0105 organizacj\u0119", "cs": "Zvolte domovskou organizaci", "tr": "Organizasyon se\u00e7iniz", "lt": "Pasirinkite organizacij\u0105", "it": "Selezionare la propria organizzazione", "ja": "\u7d44\u7e54\u306e\u9078\u629e", "zh-tw": "\u9078\u64c7\u6240\u5c6c\u7d44\u7e54", "et": "Vali koduorganisatsioon", "he": "\u05d4\u05d7\u05dc\u05e3 \u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05d1\u05d9\u05ea", "ru": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e", "zh": "\u9009\u62e9\u4f60\u7684\u5bb6\u5ead\u7ec4\u7ec7", "ar": "\u0627\u062e\u062a\u0627\u0631 \u062c\u0647\u062a\u0643 \u0627\u0644\u0627\u0645", "id": "Pilih basis organisasi", "lv": "Izv\u0113l\u0113ties organiz\u0101ciju", "sr": "Izaberite mati\u010dnu instituciju", "ro": "Alege\u021bi institu\u021bia de origine", "eu": "Jatorrizko erakundea hautatu", "af": "Kies tuisorganisasie", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bf\u03b9\u03ba\u03b5\u03af\u03bf\u03c5 \u03c6\u03bf\u03c1\u03ad\u03b1", "xh": "Khetha umbutho wekhaya", "zu": "Khetha inhlangano yasekhaya", "st": "Kgetha khampani ya lehae", "ca": "Escull la teva organització principal" }, "help_desk_link": { "no": "Hjemmesiden til brukerst\u00f8tte", "nn": "Heimeside for brukarst\u00f8tte", "sv": "Hemsida f\u00f6r helpdesk", "es": "P\u00e1gina del centro de atenci\u00f3n al usuario", "fr": "Page web de l'assistance technique", "de": "Seite des Helpdesk", "nl": "Helpdesk homepage", "sl": "Spletna stran tehni\u010dne podpore uporabnikom.", "da": "Servicedesk", "hr": "Stranice slu\u017ebe za podr\u0161ku korisnicima", "hu": "\u00dcgyf\u00e9lszolg\u00e1lat weboldala", "fi": "Helpdeskin kotisivu", "pt-br": "Central de Ajuda", "pt": "P\u00e1gina do servi\u00e7o de apoio ao utilizador", "pl": "Strona domowa pomocy technicznej (Helpdesk)", "cs": "Help desk", "tr": "Yard\u0131m anasayfas\u0131", "lt": "Naudotoj\u0173 aptarnavimo puslapis", "it": "Homepage del servizio di assistenza", "ja": "\u30d8\u30eb\u30d7\u30c7\u30b9\u30af\u30da\u30fc\u30b8", "zh-tw": "\u670d\u52d9\u53f0\u9996\u9801", "et": "Kasutajatoe koduleht", "he": "\u05ea\u05de\u05d9\u05db\u05d4 \u05d8\u05db\u05e0\u05d9\u05ea", "ru": "\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441\u043b\u0443\u0436\u0431\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438", "zh": "\u670d\u52a1\u53f0\u7684\u4e3b\u9875", "ar": "\u0635\u0641\u062d\u0629 \u0627\u0644\u0645\u0633\u0627\u0639\u062f\u0629", "id": "Homepage Help desk", "lv": "Pal\u012bdz\u012bbas dienesta interneta lapa", "sr": "Stranice slu\u017ebe za podr\u0161ku korisnicima", "ro": "Pagina echipei de suport tehnic", "eu": "Laguntza teknikoaren orria ", "af": "Hulplyn-tuisblad", "el": "\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2 \u03b1\u03c1\u03c9\u03b3\u03ae\u03c2 \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd", "zu": "Ikhasi lasekhaya ledeski losizo", "xh": "Ikhasi lekhaya ledesika yoncedo", "st": "Leqephe la lapeng la ba deske ya thuso", "ca": "Pàgina d'inici del centre d'atenció a l'usuari" }, "help_desk_email": { "no": "Send e-post til brukerst\u00f8tte", "nn": "Send epost til brukarst\u00f8tte", "sv": "Skicka e-post till helpdesk", "es": "Enviar correo electr\u00f3nico al centro de atenci\u00f3n al usuario", "fr": "Assistance technique par courriel", "de": "Email an den Helpdesk senden", "nl": "Stuur een e-mail naar de helpdesk", "sl": "Po\u0161lji sporo\u010dilo tehni\u010dni podpori.", "da": "Send en e-mail til servicedesk", "hr": "Po\u0161aljite e-mail slu\u017ebi za podr\u0161ku korisnicima", "hu": "K\u00fcldj\u00f6n e-mailt az \u00fcgyf\u00e9lszolg\u00e1latnak", "fi": "L\u00e4het\u00e4 s\u00e4hk\u00f6posti helpdeskille.", "pt-br": "Envie um e-mail para a Central de Ajuda.", "pt": "Enviar um e-mail para o servi\u00e7o de apoio ao utilizador", "pl": "wy\u015blij e-mail do helpdesku", "cs": "Email helpdesku zasl\u00e1n.", "tr": "Yard\u0131m'a e-posta g\u00f6nderin", "lt": "Si\u0173sti el. lai\u0161k\u0105 naudotoj\u0173 aptarnavimo specialistams", "it": "Invia una mail al servizio di assistenza", "ja": "\u30d8\u30eb\u30d7\u30c7\u30b9\u30af\u306b\u30e1\u30fc\u30eb\u3059\u308b", "zh-tw": "\u50b3\u9001 e-mail \u5c0b\u6c42\u5354\u52a9", "et": "Saada kasutajatoele e-kiri.", "he": "\u05e9\u05dc\u05d7 \u05d3\u05d5\u05d0\u05dc \u05dc\u05ea\u05d9\u05db\u05d4 \u05d4\u05d8\u05db\u05e0\u05d9\u05ea", "ru": "\u041f\u043e\u0441\u043b\u0430\u0442\u044c email \u0432 \u0441\u043b\u0443\u0436\u0431\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438", "zh": "\u53d1\u9001Email\u7ed9\u670d\u52a1\u53f0", "ar": "\u0627\u0631\u0633\u0644 \u0625\u064a\u0645\u064a\u0644 \u0644\u0635\u0641\u062d\u0629 \u0627\u0644\u0645\u0633\u0627\u0639\u062f\u0629", "id": "Kirim e-mail ke help dek", "lv": "S\u016bt\u012bt e-pastu pal\u012bdz\u012bbas dienestam", "sr": "Po\u0161alji e-mail slu\u017ebi za podr\u0161ku korisnicima", "ro": "Trimite\u021bi un mesaj la echipa de suport tehnic", "eu": "Bidali posta laguntza teknikoari ", "af": "Stuur e-pos aan hulplyn", "el": "\u0391\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u0065\u006d\u0061\u0069\u006c \u03c3\u03c4\u03b7\u03bd \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1 \u03b1\u03c1\u03c9\u03b3\u03ae\u03c2 \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd", "xh": "Thumela i-imeyile kwidesika yoncedo", "zu": "Thumela i-imeyili edeskini losizo", "st": "Romela imeile ho ba deske ya thuso", "ca": "Envia un correu electrònic el centre d'atenció a l'usuari" }, "next": { "no": "Fortsett", "nn": "Neste", "sv": "N\u00e4sta", "es": "Siguiente", "fr": "Suivant", "de": "Weiter", "nl": "Volgende", "sl": "Naprej", "da": "N\u00e6ste", "hr": "Dalje", "hu": "K\u00f6vetkez\u0151", "fi": "Seuraava", "pt-br": "Pr\u00f3ximo", "pt": "Seguinte", "pl": "Nast\u0119pny", "cs": "Dal\u0161\u00ed", "tr": "S\u0131radaki", "lt": "Kitas", "it": "Avanti", "ja": "\u6b21\u3078", "zh-tw": "\u4e0b\u4e00\u6b65", "et": "Edasi", "he": "\u05d4\u05d1\u05d0", "ru": "\u0414\u0430\u043b\u0435\u0435", "zh": "\u4e0b\u4e00\u6b65", "ar": "\u0627\u0644\u062a\u0627\u0644\u064a", "id": "Selanjutnya", "lv": "T\u0101l\u0101k", "sr": "Dalje", "ro": "Urm\u0103torul pas", "eu": "Hurrengoa", "xh": "Olandelayo", "af": "Volgende", "el": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf", "zu": "Okulandelayo", "st": "E latelang", "ca": "Següent" }, "remember_username": { "es": "Recordar mi nombre de usuario", "de": "Nutzername merken", "hu": "Eml\u00e9kezzen a felhaszn\u00e1l\u00f3nevemre", "ru": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043c\u043e\u0451 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f", "zh-tw": "\u8a18\u4f4f\u6211\u7684\u4f7f\u7528\u8005\u540d\u7a31", "nl": "Onthoud gebruikersnaam", "da": "Husk mit brugernavn", "af": "Onthou my gebruikersnaam", "pt-br": "Lembrar meu nome de usu\u00e1rio", "el": "\u039d\u03b1 \u03b8\u03c5\u03bc\u03ac\u03c3\u03b1\u03b9 \u03c4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7", "zu": "Khumbula igama lami lomsebenzisi", "xh": "Khumbula igama lomsebenzisi lam", "st": "Hopola lebitso la ka la mosebedisi", "sl": "Zapomni si moje uporabniško ime", "ca": "Recorda el meu nom d’usuari" }, "remember_me": { "es": "Recordarme", "de": "Angemeldet bleiben", "hu": "Eml\u00e9kezzen r\u00e1m", "ru": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043c\u0435\u043d\u044f", "zh-tw": "\u8a18\u4f4f\u6211", "nl": "Onthoud mij", "da": "Husk mig", "af": "Onthou my", "pt-br": "Lembre-me", "el": "\u039d\u03b1 \u03bc\u03b5 \u03b8\u03c5\u03bc\u03ac\u03c3\u03b1\u03b9", "xh": "Ndikhumbule", "zu": "Ngikhumbule", "sl": "Zapomni si me", "st": "Nkgopole", "ca": "Recorda'm" }, "remember_organization": { "ca": "Recorda la meva organització principal" } } simplesamlphp-1.19.1/dictionaries/admin.translation.json0000644000000000000000000033445214042503475022173 0ustar rootroot{ "cfg_check_header": { "no": "Sjekker konfigurasjonen", "nn": "Konfigurasjonssjekk", "sv": "Konfigurationskontroll", "es": "Comprobar configuraci\u00f3n", "nl": "Configuratie-validatie", "sl": "Preverjanje konfiguracije", "da": "Unders\u00f8gelse af konfiguration", "hr": "Provjera konfiguracije", "hu": "Be\u00e1ll\u00edt\u00e1sok ellen\u0151rz\u00e9se", "pt-br": "Verificar configura\u00e7\u00e3o", "pt": "Verifica\u00e7\u00e3o da configura\u00e7\u00e3o", "pl": "Sprawdzenie konfiguracji", "cs": "Verifikace konfigurace", "eu": "Konfigurazioa egiaztatu", "tr": "Konfig\u00fcrasyon kontrol\u00fc", "de": "Konfigurationscheck", "fr": "V\u00e9rification de la configuration", "it": "Verifica della configurazione", "ja": "\u8a2d\u5b9a\u78ba\u8a8d", "lt": "Konfig\u016bracijos patikrinimas", "zh-tw": "\u8a2d\u5b9a\u6aa2\u67e5", "et": "Seadistuste kontroll", "he": "\u05d1\u05d3\u05d9\u05e7\u05ea \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea", "ru": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438", "zh": "\u914d\u7f6e\u68c0\u67e5", "ar": "\u0645\u0631\u0627\u062c\u0639\u0629 \u0627\u0644\u062a\u0631\u062a\u064a\u0628", "lv": "Konfigur\u0101cijas p\u0101rbaude", "id": "Pemeriksaan konfigurasi", "sr": "Provera pode\u0161avanja", "ro": "Verificarea configura\u021biei", "el": "\u0388\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd", "ca": "Comprovar la configuaraci\u00f3" }, "cfg_check_select_file": { "no": "Velg hvilken konfigurasjonfil som skal sjekkes", "nn": "Vel konfigurasjonsfil som skal sjekkast", "sv": "V\u00e4lj vilken konfigurationfil som ska kontrolleras:", "es": "Seleccione el fichero de configuraci\u00f3n a comprobar:", "nl": "Selecteer een configuratiefile voor validatie:", "sl": "Izberite konfiguracijsko datoteko, ki jo \u017eelite preveriti", "da": "V\u00e6lg den konfiguration som skal unders\u00f8ges", "hr": "Odaberite konfiguracijsku datoteku koju \u017eelite provjeriti:", "hu": "V\u00e1lassza ki az ellen\u0151rizend\u0151 konfigur\u00e1ci\u00f3s \u00e1llom\u00e1nyt", "pt-br": "Selecione o arquivo de configura\u00e7\u00e3o para verificar", "pt": "Escolha o ficheiro de configura\u00e7\u00e3o a verificar:", "pl": "Wybierz plik konfiguracyjny do sprawdzenia:", "cs": "Vyber konfigura\u010dn\u00edho souboru k verifikaci:", "tr": "Kontrol edilecek konfig\u00fcrasyon dosyas\u0131n\u0131 se\u00e7:", "de": "W\u00e4hlen Sie die Konfigurationsdatei, die gecheckt werden soll:", "fr": "S\u00e9lectionnez le fichier de configuration \u00e0 v\u00e9rifier :", "it": "Selezionare il file di configurazione da verificare:", "ja": "\u78ba\u8a8d\u3059\u308b\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e:", "lt": "Tikrinti konfig\u016bracijos fail\u0105:", "zh-tw": "\u9078\u64c7\u8981\u6aa2\u67e5\u7684\u8a2d\u5b9a\u6a94\uff1a", "et": "Vali seadistustefail, mida kontrollida:", "he": "\u05d1\u05d7\u05e8 \u05e7\u05d5\u05d1\u05e5 \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05dc\u05d1\u05d3\u05d9\u05e7\u05d4:", "ru": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:", "zh": "\u9009\u62e9\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u7528\u4e8e\u68c0\u6d4b", "ar": "\u0627\u062e\u062a\u0627\u0631\u0645\u0644\u0641 \u0627\u0644\u062a\u0631\u062a\u064a\u0628 \u0627\u0644\u0630\u064a \u062a\u0631\u063a\u0628 \u0628\u0645\u0631\u0627\u062c\u0639\u062a\u0647", "lv": "Izv\u0113lieties p\u0101rbaud\u0101mos konfigur\u0101cijas failus:", "id": "Pilih file konfigurasi untuk diperiksa", "sr": "Odaberite konfiguracionu fajl koji \u017eelite proveriti:", "ro": "Alege\u021bi fi\u0219ierul de configurare care dori\u021bi s\u0103-l verifica\u021bi:", "eu": "Hautatu ezazu egiaztatu beharreko konfigurazio fitxategia: ", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03b3\u03b9\u03b1 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf: ", "ca": "Seleccioneu el fitxer de configuraci\u00f3 per comprovar:" }, "cfg_check_missing": { "no": "Mangler element i konfigurasjonsfilen", "nn": "Det manglar informasjon i konfigurasjonsfila", "sv": "Alternativ saknas i konfigurationsfilen", "es": "Opciones que faltan en el fichero de configuraci\u00f3n", "nl": "Opties missen in de config file", "sl": "V konfiguracijski datoteki manjkajo nastavitve", "da": "Valg kan ikke behandles - se konfigurationsfil", "hr": "Parametri koji nedostaju u konfiguracijskoj datoteci", "hu": "Hi\u00e1nyz\u00f3 opci\u00f3k a konfigur\u00e1ci\u00f3s \u00e1llom\u00e1nyban", "pt-br": "Op\u00e7\u00f5es faltando no arquivo de configura\u00e7\u00e3o", "pt": "Op\u00e7\u00f5es ausentes do ficheiro de configura\u00e7\u00e3o", "pl": "Brakuj\u0105ce opcje z pliku konfiguracyjnego", "cs": "Chybejici polozky v konfiguracnim souboru", "tr": "Config dosyas\u0131ndaki tercihler eksik", "de": "Optionen, die in der Konfigurationsdatei fehlen", "fr": "Options manquantes dans le fichier de configuration", "it": "Opzioni mancanti dal file di configurazione", "ja": "\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u30aa\u30d7\u30b7\u30e7\u30f3\u304c\u5728\u308a\u307e\u305b\u3093", "lt": "Tr\u016bkstami parametrai konfig\u016braciniame faile", "zh-tw": "\u8a2d\u5b9a\u6a94\u7f3a\u5c11\u9078\u9805", "et": "Seadistustefailist puuduvad seadistused:", "he": "\u05d0\u05e4\u05e9\u05e8\u05d5\u05d9\u05d5\u05ea \u05d7\u05e1\u05e8\u05d5\u05ea \u05de\u05e7\u05d5\u05d1\u05e5 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea", "zh": "\u914d\u7f6e\u6587\u4ef6\u4e2d\u9009\u9879\u7f3a\u5931", "ar": "\u062e\u064a\u0627\u0631\u0627\u062a \u0645\u0641\u0642\u0648\u062f\u0629 \u0645\u0646 \u0645\u0644\u0641 \u0627\u0644\u062a\u0631\u062a\u064a\u0628", "lv": "Konfigur\u0101cijas fail\u0101 tr\u016bkst opciju", "id": "Opsi-opsi uang hilang dari file konfigurasi", "sr": "Paramentri koji nedostaju u konfiguracionom fajlu", "ro": "Op\u021biuni care nu apar \u00een fi\u0219ierul de configurare", "ru": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438", "eu": "Konfigurazio fitxategian falta diren aukerak", "el": "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 \u03c0\u03bf\u03c5 \u03bb\u03b5\u03af\u03c0\u03bf\u03c5\u03bd \u03b1\u03c0\u03cc \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd", "ca": "Falten les opcions del fitxer de configuraci\u00f3" }, "cfg_check_superfluous": { "no": "Overf\u00f8ldig element i konfigurasjonsfilen", "nn": "Overfl\u00f8dig informasjon i konfigurasjonsfila", "sv": "\u00d6verfl\u00f6diga alternativ i konfigurationsfilen", "es": "Opciones sobrantes en el fichero de configuraci\u00f3n", "nl": "Teveel opties in de config file", "sl": "Odve\u010dne nastavitve v konfiguracijski datoteki", "da": "Overfl\u00f8digt valg i konfigurationsfil", "hr": "Suvi\u0161ni parametri u konfiguracijskoj datoteci", "hu": "Felesleges opci\u00f3k a konfigur\u00e1ci\u00f3s \u00e1llom\u00e1nyban", "pt-br": "Op\u00e7\u00f5es sup\u00e9rfluas no arquivo de configura\u00e7\u00e3o", "pt": "Op\u00e7\u00f5es sup\u00e9rfluas do ficheiro de configura\u00e7\u00e3o", "pl": "Zb\u0119dne opcje w pliku konfiguracyjnym", "cs": "Nadbyte\u010dn\u00e9 polo\u017eky v konfigura\u010dn\u00edm souboru", "tr": "Config dosyas\u0131ndaki gereksiz tercihler", "de": "\u00dcberfl\u00fcssige Optionen in der Konfigurationsdatei", "fr": "Options superflues dans le fichier de configuration", "it": "Opzioni superflue nel file di configurazione", "ja": "\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306b\u4e0d\u9069\u5207\u306a\u30aa\u30d7\u30b7\u30e7\u30f3\u304c\u5728\u308a\u307e\u3059", "lt": "Pertekliniai parametrai konfig\u016braciniame faile", "zh-tw": "\u591a\u9918\u8a2d\u5b9a\u5b58\u5728\u65bc\u8a2d\u5b9a\u6a94", "et": "\u00dcleliigne seadistus seadistustefailis", "he": "\u05d0\u05e4\u05e9\u05e8\u05d5\u05d9\u05d5\u05ea \u05de\u05d9\u05d5\u05ea\u05e8\u05d5\u05ea \u05d1\u05e7\u05d5\u05d1\u05e5 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea", "zh": "\u914d\u7f6e\u6587\u4ef6\u4e2d\u62e5\u6709\u8fc7\u591a\u7684\u9009\u9879", "ar": "\u062e\u064a\u0627\u0631\u0627\u062a \u0641\u0627\u0626\u0636\u0629 \u0628\u0645\u0644\u0641 \u0627\u0644\u062a\u0631\u062a\u064a\u0628", "lv": "S\u012bkas (superfluous) opcijas konfigur\u0101cijas fail\u0101", "id": "Pilihan tak beguna di file konfigurasi", "sr": "Suvi\u0161ni parametri u konfiguracionom fajlu", "ro": "Op\u021biuni inutile \u00een fi\u0219ierul de configurare", "ru": "\u0418\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438", "eu": "Konfigurazio fitxategian soberan dauden aukerak", "el": "\u03a0\u03b5\u03c1\u03b9\u03c4\u03c4\u03ad\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd", "ca": "Opcions superflues al fitxer de configuraci\u00f3" }, "cfg_check_noerrors": { "no": "Ingen feil funnet", "nn": "Fann ingen feil", "sv": "Inga fel funna.", "es": "No se han encontrado errores", "nl": "Geen fouten gevonden.", "sl": "Ni napak", "da": "Ingen fejl", "hr": "Nije prona\u0111ena niti jedna gre\u0161ka.", "hu": "Nincs hiba.", "pt-br": "N\u00e3o foram encontrados erros.", "pt": "N\u00e3o foram encontrados erros.", "pl": "Nie znaleziono b\u0142\u0119d\u00f3w.", "cs": "Nenalezeny \u017e\u00e1dn\u00e9 chyby", "eu": "Ez da errorerik aurkitu", "tr": "Hata bulunmad\u0131.", "de": "Keine Fehler gefunden.", "fr": "Aucune erreur.", "it": "Nessun errore trovato.", "ja": "\u30a8\u30e9\u30fc\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002", "lt": "Klaid\u0173 nerasta.", "zh-tw": "\u6c92\u6709\u767c\u73fe\u932f\u8aa4\u3002", "et": "T\u00f5rkeid ei leitud", "he": "\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5 \u05e9\u05d2\u05d9\u05d0\u05d5\u05ea.", "zh": "\u6ca1\u6709\u53d1\u73b0\u9519\u8bef", "ar": "\u0644\u0627 \u062a\u0648\u062c\u062f \u0623\u062e\u0637\u0627\u0621 ", "lv": "K\u013c\u016bdas nav atrastas.", "id": "Tidak ada error yang ditemukan", "sr": "Nije prona\u0111ena nijedna gre\u0161ka.", "ro": "Nu au fost depistate erori.", "ru": "\u041e\u0448\u0438\u0431\u043e\u043a \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e.", "el": "\u0394\u03b5\u03bd \u03b5\u03bd\u03c4\u03bf\u03c0\u03af\u03c3\u03c4\u03b7\u03ba\u03b1\u03bd \u03bb\u03ac\u03b8\u03b7.", "ca": "No s'ha trobat cap error." }, "cfg_check_back": { "no": "G\u00e5 tilbake til fil-listen", "nn": "G\u00e5 tilbake til filoversikten", "sv": "G\u00e5 tillbaka till fillistan", "es": "Volver al listado de archivos", "nl": "Ga terug naar de lijst van files.", "sl": "Vrnite se na seznam datotek", "da": "Tilbage til listen over filer", "hr": "Vrati se natrag na popis datoteka", "hu": "Vissza az f\u00e1jlok list\u00e1j\u00e1hoz", "pt-br": "Voltar a lista de arquivos", "pt": "Voltar \u00e0 lista de ficheiros", "pl": "Powr\u00f3t do listy plik\u00f3w", "cs": "Zp\u00e1tky na seznam soubor\u016f", "eu": "Itzuli fitxategien zerrendara", "tr": "Dosya listesine geri d\u00f6n", "de": "Gehe zur\u00fcck zur Dateiliste", "fr": "Retour \u00e0 la liste des fichiers", "it": "Tornare indietro alla lista dei file", "ja": "\u30d5\u30a1\u30a4\u30eb\u30ea\u30b9\u30c8\u306b\u623b\u308b", "lt": "Gr\u012f\u017eti \u012f fail\u0173 s\u0105ra\u0161\u0105", "zh-tw": "\u56de\u5230\u6a94\u6848\u5217\u8868", "et": "Mine tagasi failide nimekirja", "he": "\u05d7\u05d6\u05d5\u05e8 \u05d0\u05dc \u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05e7\u05d1\u05e6\u05d9\u05dd", "zh": "\u8fd4\u56de\u81f3\u6587\u4ef6\u5217\u8868", "ar": "\u0639\u062f \u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u0644\u0641\u0627\u062a", "lv": "Iet atpaka\u013c uz sarakstu", "id": "Kembali ke daftar file", "sr": "Vrati se natrag na listu fajlova", "ro": "Merge\u021bi \u00eenapoi la lista de fi\u0219iere", "ru": "\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043f\u0438\u0441\u043a\u0443 \u0444\u0430\u0439\u043b\u043e\u0432", "el": "\u0395\u03c0\u03b9\u03c3\u03c4\u03c1\u03bf\u03c6\u03ae \u03c3\u03c4\u03bf\u03bd \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd", "ca": "Torneu a la llista de fitxers" }, "metaover_header": { "no": "Oversikt over metadata", "nn": "Oversikt over metadata", "sv": "Metadata\u00f6versikt", "es": "Ver metadatos", "nl": "Metadata-overzicht", "sl": "Pregled metapodatkov", "da": "Metadataoversigt", "hr": "Pregled metapodataka", "hu": "Metaadat \u00e1ttekint\u00e9s", "pt-br": "Vis\u00e3o geral da metadata", "pt": "Vista geral dos metadados", "pl": "Przegl\u0105d metadanych", "cs": "P\u0159ehled metadat", "tr": "\u00dcstveri (metada) genel g\u00f6r\u00fcn\u00fcm\u00fc", "de": "Metadaten-\u00dcberblick", "fr": "Vue d'ensemble des m\u00e9tadonn\u00e9es", "it": "Visione generale dei metadati", "ja": "\u30e1\u30bf\u30c7\u30fc\u30bf\u306e\u6982\u8981", "lt": "Metaduomen\u0173 per\u017ei\u016bra", "zh-tw": "Metadata \u7e3d\u89bd", "et": "Metaandmete \u00fclevaade", "he": "\u05e1\u05e7\u05d9\u05e8\u05ea \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2", "zh": "\u5143\u4fe1\u606f\u6d4f\u89c8", "ar": "\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629 \u0644\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629\/ \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627", "lv": "Metadatu p\u0101rskats", "id": "Ikhtisar Metadata", "sr": "Pregled metapodataka", "ro": "Prezentare general\u0103 a metadatelor", "ru": "\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445", "eu": "Ikusi metadatuak", "el": "\u0395\u03c0\u03b9\u03c3\u03ba\u03cc\u03c0\u03b7\u03c3\u03b7 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd (metadata)", "ca": "Visi\u00f3 general de les metadades" }, "metaover_intro": { "no": "For \u00e5 se p\u00e5 detaljene i en SAML-entitet, klikk p\u00e5 SAML-entitet overskriften", "nn": "For \u00e5 sj\u00e5 p\u00e5 detaljane for ein SAML entitet, klikk p\u00e5 SAML entitet", "sv": "F\u00f6r att titta p\u00e5 detaljer f\u00f6r en SAML-entitet klicka p\u00e5 rubriken f\u00f6r SAML-entiteten.", "es": "Para ver los detalles de una entidad SAML, haga click en la cabecera de la entidad.", "nl": "Klik op een SAML-entiteit om de details voor die entiteit te bekijken.", "sl": "Za pregled podrobnosti SAML entitete, kliknite na glavo te entitete", "da": "For at se detaljer vedr\u00f8rende SAML-entiteten, klik p\u00e5 entitets-headeren", "hr": "Da biste vidjeli detalje o SAML entitetu, kliknite na njegovo zaglavlje.", "hu": "A SAML entit\u00e1sok r\u00e9szletei\u00e9rt kattintson a SAML entit\u00e1s fejl\u00e9c\u00e9re", "pt-br": "Para ver os detalhes da entidade SAML, clique ", "pt": "Para obter detalhes sobre uma entidade SAML, clique no t\u00edtulo da entidade.", "pl": "Kliknij na nag\u0142\u00f3wek ko\u0144c\u00f3wki aby wy\u015bwietli\u0107 szczeg\u00f3\u0142y SAML.", "cs": "Pro zobrazen\u00ed detailu SAML entity, klikni na hlavi\u010dku entity", "tr": "Bir SAML eleman\u0131 hakk\u0131ndaki detaylar\u0131 g\u00f6rmek i\u00e7in, SAML eleman\u0131 ba\u015fl\u0131\u011f\u0131na t\u0131klay\u0131n.", "de": "Um sich Details f\u00fcr eine SAML-Entit\u00e4t anzusehen, klicken Sie auf die Kopfzeile der SAML-Entit\u00e4t.", "fr": "Pour examiner les d\u00e9tails d'une entit\u00e9 SAML, cliquez sur son en-t\u00eate.", "it": "Per visualizzare i dettagli di una entit\u00e0 SAML, cliccare sull'header SAML dell'entit\u00e0.", "ja": "SAML\u5b9f\u4f53\u306e\u8a73\u7d30\u3092\u78ba\u8a8d\u3059\u308b\u70ba\u306b\u306f\u3001SAML\u5b9f\u4f53\u30d8\u30c3\u30c0\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u4e0b\u3055\u3044\u3002", "lt": "Nor\u0117dami per\u017ei\u016br\u0117ti detalesn\u0119 informacij\u0105 apie SAML, paspauskite ant SAML antra\u0161t\u0117s.", "zh-tw": "\u9ede\u9078 SAML \u7269\u4ef6\u6a19\u984c\uff0c\u53ef\u6aa2\u8996 SAML \u7269\u4ef6\u8a73\u7d30\u8cc7\u8a0a\u3002", "et": "SAML olemi detailide vaatamiseks kl\u00f5psa SAML olemi p\u00e4isel.", "he": "\u05db\u05d3\u05d9 \u05dc\u05d4\u05e1\u05ea\u05db\u05dc \u05e2\u05dc \u05d4\u05e4\u05e8\u05d8\u05d9\u05dd \u05e9\u05dc \u05d9\u05e9\u05d5\u05ea SAML, \u05dc\u05d7\u05e5 \u05e2\u05dc \u05db\u05d5\u05ea\u05e8\u05ea \u05d9\u05e9\u05d5\u05ea \u05d4SAML ", "zh": "\u60f3\u8981\u67e5\u770bSAML\u5b9e\u4f53\u7684\u8be6\u7ec6\u60c5\u51b5\uff0c\u8bf7\u70b9\u51fbSAML\u5b9e\u4f53\u8f7d\u5165\u5668", "ar": "\u0644\u0625\u0644\u063a\u0627\u0621 \u0646\u0638\u0631\u0629 \u0639\u0644\u064a \u062a\u0641\u0627\u0635\u064a\u0644 \u0627\u062d\u062f\u064a \u0648\u062d\u062f\u0627\u062a SAML, \u0627\u0636\u063a\u0637 \u0639\u0644\u064a \u062a\u0631\u0648\u064a\u0633\u0629 \u0627\u0644\u0648\u062d\u062f\u0629 ", "lv": "Lai apl\u016bkotu SAML vienuma deta\u013cas, klik\u0161\u0137iniet uz vienuma galvenes.", "id": "Untuk melihat detail entiti SAML, klik pada bagian header entiti SAML", "sr": "Da biste videli detalje o SAML entitetu, kliknite na njegovo zaglavlje.", "ro": "Pentru a vizualiza detalii privind o entitate SAML, ap\u0103sa\u021bi pe antetul entit\u0103\u021bii SAML.", "ru": "\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 SAML, \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0437\u0430\u043f\u0438\u0441\u0438 SAML.", "eu": "SAML entitate baten xehetasunak ikusteko, klikatu entitatearen goiburua.", "el": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b5\u03af\u03c4\u03b5 \u03c4\u03b9\u03c2 \u03bb\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 \u03b3\u03b9\u03b1 \u03bc\u03b9\u03b1 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1 \u0053\u0041\u004d\u004c, \u03ba\u03ac\u03bd\u03c4\u03b5 \u03ba\u03bb\u03b9\u03ba \u03c3\u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03ba\u03b5\u03c6\u03b1\u03bb\u03af\u03b4\u03b1 \u03c4\u03b7\u03c2 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2.", "ca": "Per veure els detalls d'una entitat SAML, feu clic a la cap\u00e7alera de l'entitat SAML." }, "metaover_errorentry": { "no": "Feil i metadataoppf\u00f8ringen", "nn": "Feil i dette metadatainnslaget", "sv": "Fel i dessa metadat", "es": "Error en los metadatos de la entrada", "de": "Fehler in diesem Metadaten Eintrag", "nl": "Fout in metadata", "sl": "Napaka pri vnosu metapodatkov", "da": "Fejl i denne sektion af metadata", "hr": "Ovaj zapis metapodataka sadr\u017ei gre\u0161ku", "hu": "Hiba ebben a metaadat bejegyz\u00e9sben", "pt-br": "Erro na entrada desta metadata", "pt": "Erro nesta entrada de metadados", "pl": "B\u0142\u0105d w metadanych", "cs": "Chyba v t\u00e9to polo\u017ece metadat", "tr": "\u00dcstveri (metadata) bilgisinde hata var", "fr": "Erreur dans les m\u00e9tadonn\u00e9es de cet \u00e9l\u00e9ment", "it": "Errore in questo elemento dei metadati", "ja": "\u3053\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u30a8\u30f3\u30c8\u30ea\u3067\u306e\u30a8\u30e9\u30fc", "lt": "Klaida \u0161iame metaduomen\u0173 \u012fra\u0161e", "zh-tw": "\u6709\u932f\u8aa4\u5b58\u5728\u9019\u500b Metadata \u689d\u76ee", "et": "T\u00f5rge selles metaandmete kirjes", "he": "\u05e9\u05d2\u05d9\u05d0\u05d4 \u05d1\u05e8\u05e9\u05d5\u05de\u05ea \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05d6\u05d5", "zh": "\u8be5\u5143\u4fe1\u606f\u5b9e\u4f53\u5b58\u5728\u9519\u8bef", "ar": "\u062e\u0637\u0627 \u0628\u0647\u0630\u0627 \u0627\u0644\u0628\u064a\u0627\u0646 \u0627\u0644\u0648\u0635\u0641\u064a\/ \u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627", "lv": "K\u013c\u016bda \u0161aj\u0101 metadatu ierakst\u0101", "id": "Error pada entri metadata ini", "sr": "Ovaj zapis metapodataka sadr\u017ei gre\u0161ku", "ro": "Eroare \u00een aceast\u0103 metadat\u0103", "ru": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0432\u0432\u043e\u0434\u0435 \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445", "eu": "Metadatu sarrera honetan errorea", "el": "\u03a3\u03c6\u03ac\u03bb\u03bc\u03b1 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03b1\u03c7\u03ce\u03c1\u03b7\u03c3\u03b7 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd", "ca": "Error en aquesta entrada de metadades" }, "metaover_required_found": { "no": "Obligatorisk felt", "nn": "N\u00f8dvendige felt", "sv": "N\u00f6dv\u00e4ndiga alternativ", "es": "Campos obligatorios", "de": "Notwendige Felder", "nl": "Verplichte velden", "sl": "Zahtevana polja", "da": "Obligatoriske felter", "hr": "Obavezna polja", "hu": "K\u00f6telez\u0151 mez\u0151k", "pt-br": "Campos requeridos", "pt": "Campos obrigat\u00f3rios", "pl": "Pola wymagane", "cs": "Po\u017eadovan\u00e1 pole", "tr": "Gerekli alanlar", "fr": "Champs requis", "it": "Campi richiesti", "ja": "\u5fc5\u9808\u9805\u76ee", "lt": "Privalomi laukai", "zh-tw": "\u5fc5\u8981\u6b04\u4f4d", "et": "Kohustuslikud v\u00e4ljad", "he": "\u05e9\u05d3\u05d5\u05ea \u05e0\u05d3\u05e8\u05e9\u05d9\u05dd", "zh": "\u5fc5\u9700\u7684\u533a\u57df", "ar": "\u062d\u0642\u0644 \u0625\u062c\u0628\u0627\u0631\u064a", "lv": "Oblig\u0101tie lauki", "id": "Field-field yang wajib diisi", "sr": "Obavezna polja", "ro": "C\u00e2mpuri obligatorii", "ru": "\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f", "eu": "Derrigorrezko eremuak", "el": "\u03a5\u03c0\u03bf\u03c7\u03c1\u03b5\u03c9\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1", "ca": "Camps obligatoris" }, "metaover_required_not_found": { "no": "F\u00f8lgende obligatoriske felter ble ikke funnet", "nn": "Fann ikkje f\u00f8lgjande n\u00f8dvendige felt", "sv": "F\u00f6ljande n\u00f6dv\u00e4ndiga alternativ hittades inte", "es": "Los siguientes datos obligatorios no se han encontrado", "de": "Die folgenden notwendigen Felder wurden nicht gefunden", "nl": "De volgende verplichte velden konden niet worden gevonden", "sl": "Naslednjih zahtevanih polj ni bilo mogo\u010de najti", "da": "F\u00f8lgende obligatoriske felter kunne ikke findes ", "hr": "Nisu prona\u0111ena sljede\u0107a obavezna polja", "hu": "A k\u00f6vetkez\u0151 k\u00f6telez\u0151 mez\u0151k hi\u00e1nyoznak", "pt-br": "Os seguintes campos requeridos n\u00e3o foram encontrados", "pt": "Os seguintes campos obrigat\u00f3rios n\u00e3o foram encontrados", "pl": "Nastepuj\u0105ce wymagane pola nie zosta\u0142y znalezione", "cs": "N\u00e1sleduj\u00edc\u00ed po\u017eadovan\u00e1 pole nenalezena", "tr": "\u015eu gerekli alanlar bulunamad\u0131", "fr": "Les champs suivants n'existent pas et sont requis", "it": "I seguenti campi, richiesti, non sono stati trovati", "ja": "\u4ee5\u4e0b\u306e\u5fc5\u9808\u9805\u76ee\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f", "lt": "\u0160ie privalomi laukai nerasti", "zh-tw": "\u4e0b\u5217\u8cc7\u6599\u627e\u4e0d\u5230\u5fc5\u8981\u6b04\u4f4d", "et": "J\u00e4rgmisi kohuslikke v\u00e4lju ei leitud", "he": "\u05d4\u05e9\u05d3\u05d5\u05ea \u05d4\u05d3\u05e8\u05d5\u05e9\u05d9\u05dd \u05d4\u05d1\u05d0\u05d9\u05dd \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5", "zh": "\u4e0b\u5217\u5fc5\u9700\u7684\u533a\u57df\u6ca1\u6709\u627e\u5230", "ar": "\u0627\u0644\u062d\u0642\u0648\u0644 \u0627\u0644\u0625\u062c\u0628\u0627\u0631\u064a\u0629 \u0623\u062f\u0646\u0627\u0647 \u0645\u0641\u0642\u0648\u062f\u0629", "lv": "Nav atrasti oblig\u0101tie lauki", "id": "Field-field yang diperlukan wajib disisi berikut ini tidak ditemukan", "sr": "Nisu prona\u0111ena slede\u0107a opciona polja", "ro": "Urm\u0103toarele c\u00e2mpuri obligatorii nu au fost g\u0103site", "ru": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b", "eu": "Derrigorrezko datu hauek ez dira aurkitu", "el": "\u03a4\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03c4\u03c9 \u03c5\u03c0\u03bf\u03c7\u03c1\u03b5\u03c9\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1 \u03b4\u03b5 \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd", "ca": "No s'han trobat els seg\u00fcents camps obligatoris" }, "metaover_optional_found": { "no": "Valgbart felt", "nn": "Valfrie felt", "sv": "Frivilliga alternativ", "es": "Datos opcionales", "de": "Optionale Felder", "nl": "Optionele velden", "sl": "Neobvezna polja", "da": "Valgfrie felter", "hr": "Opcionalna polja", "hu": "Opcion\u00e1lis mez\u0151", "pt-br": "Campos opcionais", "pt": "Campos opcionais", "pl": "Pola opcjonalne", "cs": "Voliteln\u00e1 pole", "tr": "\u0130ste\u011fe ba\u011fl\u0131 alanlar", "fr": "Champs optionnels", "it": "Campi opzionali", "ja": "\u4efb\u610f\u9805\u76ee", "lt": "Neprivalomi laukai", "zh-tw": "\u9078\u64c7\u6027\u6b04\u4f4d", "et": "Lisav\u00e4ljad", "he": "\u05e9\u05d3\u05d5\u05ea \u05e8\u05e9\u05d5\u05ea", "zh": "\u9009\u9879\u533a\u57df", "ar": "\u062d\u0642\u0644 \u0627\u062e\u062a\u064a\u0627\u0631\u064a", "lv": "Neoblig\u0101tie lauki", "id": "Field-field opsional", "sr": "Opciona polja", "ro": "C\u00e2mpuri op\u021bionale", "ru": "\u041d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f", "eu": "Hautazko datuak", "el": "\u03a0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1", "ca": "Camps opcionals" }, "metaover_optional_not_found": { "no": "F\u00f8lgende valgbare felt ble ikke funnet", "nn": "Fann ikkje f\u00f8lgjande valfrie felt", "sv": "F\u00f6ljande frivilliga alternativ hittades inte", "es": "Los siguientes datos opcionales no se han encontrado", "de": "Die folgenden optionalen Felder wurden nicht gefunden", "nl": "De volgende optionele velden konden niet worden gevonden", "sl": "Naslednjih neobveznih polj ni bilo mogo\u010de najti", "da": "F\u00f8lgende valgfrie felter kunne ikke findes", "hr": "Nisu prona\u0111ena sljede\u0107a opcionalna polja", "hu": "A k\u00f6vetkez\u0151 opcion\u00e1lis mez\u0151k nem tal\u00e1lhat\u00f3k", "pt-br": "Os seguintes campos opcionais n\u00e3o foram encontrados", "pt": "Os seguintes campos opcionais n\u00e3o foram encontrados", "pl": "Nastepuj\u0105ce pola opcjonalne nie zosta\u0142y znalezione", "cs": "Nasleduj\u00edc\u00ed voliteln\u00e1 pole nenalezena", "tr": "\u015eu iste\u011fe ba\u011fl\u0131 alanlar bulunamad\u0131", "fr": "Les champs optionnels suivants n'ont pas \u00e9t\u00e9 trouv\u00e9s", "it": "I seguenti campi, opzionali, non sono stati trovati", "ja": "\u4ee5\u4e0b\u306e\u4efb\u610f\u9805\u76ee\u306f\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f", "lt": "\u0160ie neprivalomi laukai nerasti", "zh-tw": "\u4e0b\u5217\u8cc7\u6599\u627e\u4e0d\u5230\u9078\u64c7\u6027\u6b04\u4f4d", "et": "J\u00e4rgmisi lisav\u00e4lju ei leitud", "he": "\u05e9\u05d3\u05d5\u05ea \u05d4\u05e8\u05e9\u05d5\u05ea \u05d4\u05d1\u05d0\u05d9\u05dd \u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5", "zh": "\u4e0b\u5217\u5fc5\u9700\u7684\u9009\u9879\u533a\u57df\u6ca1\u6709\u627e\u5230", "ar": "\u0627\u0644\u062d\u0642\u0648\u0644 \u0627\u0644\u0627\u062e\u062a\u064a\u0627\u0631\u064a\u0629 \u0623\u062f\u0646\u0627\u0647 \u0645\u0641\u0642\u0648\u062f\u0629", "lv": "Nav atrasti neoblig\u0101tie lauki", "id": "Field-field opsional berikut tidak dapat ditemukan", "sr": "Nisu prona\u0111ena slede\u0107a opciona polja", "ro": "Urm\u0103toarele c\u00e2mpuri op\u021bionale nu au fost g\u0103site", "ru": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b", "eu": "Hautazko datu hauek ez dira aurkitu", "el": "\u03a4\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03c4\u03c9 \u03c0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03ac \u03c0\u03b5\u03b4\u03af\u03b1 \u03b4\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd", "ca": "No s'han trobat els seg\u00fcents camps opcionals" }, "metaover_unknown_found": { "no": "F\u00f8lgende felt ble ikke gjenkjent", "nn": "Gjenkjenner ikkje f\u00f8lgjande felt", "sv": "F\u00f6ljande alternativ k\u00e4ndes inte igen", "es": "No se han reconocido los siguientes datos", "de": "Die folgenden Felder wurden nicht erkannt", "nl": "De volgende velden zijn niet bekend", "sl": "Nepoznana polja", "da": "F\u00f8lgende felter kunne ikke tolkes", "hr": "Sljede\u0107a polja nisu prepoznata", "hu": "A k\u00f6vetkez\u0151 mez\u0151k nem \u00e9rtelmezhet\u0151k", "pt-br": "Os seguintes campos n\u00e3o foram reconhecidos", "pt": "Os seguintes campos n\u00e3o foram reconhecidos", "pl": "Nastepuj\u0105ce pola nie zosta\u0142y rozpoznane", "cs": "N\u00e1sleduj\u00edc\u00ed pole nebyla rozpozn\u00e1na", "tr": "\u015eu alanlar tan\u0131nmad\u0131", "fr": "Les champs suivants n'ont pas \u00e9t\u00e9 reconnus", "it": "I seguenti campi non sono stati riconosciuti", "ja": "\u4ee5\u4e0b\u306e\u9805\u76ee\u306f\u8a8d\u8b58\u3055\u308c\u307e\u305b\u3093\u3067\u3057\u305f", "lt": "\u0160ie laukai neatpa\u017einti", "zh-tw": "\u4e0b\u5217\u6b04\u4f4d\u7121\u6cd5\u8b58\u5225", "et": "J\u00e4rgmistest v\u00e4ljadest ei saadud aru", "he": "\u05d4\u05e9\u05d3\u05d5\u05ea \u05d4\u05d1\u05d0\u05d9\u05dd \u05dc\u05d0 \u05d6\u05d5\u05d4\u05d5", "zh": "\u4e0b\u5217\u533a\u57df\u65e0\u6cd5\u8bc6\u522b", "ar": "\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u062a\u0639\u0631\u0641 \u0639\u0644\u064a \u0627\u0644\u0642\u0644 \u0623\u062f\u0646\u0627\u0647 ", "lv": "Nav atpaz\u012bti \u0161\u0101di ievadlauki", "id": "Field-field berikut ini tidak dapat dikenali", "sr": "Slede\u0107a polja nisu prepoznata", "ro": "Urm\u0103toarele c\u00e2mpuri nu au fost recunoscute", "ru": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u044b", "eu": "Datu hauek ez dira antzeman", "el": "\u03a4\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03c4\u03c9 \u03c0\u03b5\u03b4\u03af\u03b1 \u03b4\u03b5\u03bd \u03b1\u03bd\u03b1\u03b3\u03bd\u03c9\u03c1\u03af\u03c3\u03c4\u03b7\u03ba\u03b1\u03bd", "ca": "No s'han reconegut els seg\u00fcents camps" }, "metadata_metadata": { "no": "Metadata", "nn": "Metadata", "sv": "Metadata", "es": "Metadatos", "nl": "Metadata", "sl": "Metapodatki", "da": "Metadata", "hr": "Metapodaci", "hu": "Metaadatok", "pt-br": "Metadata", "pt": "Metadados", "pl": "Metadane", "cs": "Metadata", "tr": "\u00dcstveri (metadata)", "de": "Metadaten", "fr": "M\u00e9tadonn\u00e9es", "it": "Metadati", "ja": "\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "Metaduomenys", "zh-tw": "Metadata", "et": "Metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2", "zh": "\u5143\u4fe1\u606f", "ar": "\u0628\u064a\u0627\u0646\u0627\u062a \u0648\u0635\u0641\u064a\u0629\/ \u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627", "lv": "Metadati", "id": "Metadata", "sr": "Metapodaci", "ro": "Metadate", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435", "eu": "Metadatuak", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1", "ca": "Metadades" }, "metadata_xmlformat": { "no": "I SAML 2.0 Metadata XML Format:", "nn": "P\u00e5 SAML 2.0 metadata XML-format", "sv": "I SAML 2.0 Metadata XML-format:", "es": "En formato xml de metadatos SAML 2.0:", "nl": "In SAML 2.0 Metadata XML formaat:", "sl": "V SAML 2.0 Metapodatkovni XML format:", "da": "I SAML 2.0 metadata xml-format:", "hr": "Metapodaci u SAML 2.0 XML formatu:", "hu": "SAML 2.0 XML form\u00e1tumban:", "pt-br": "Em formato SAML 2.0 Metadata XML", "pt": "Metadados no formato XML SAML 2.0", "pl": "W formacie SAML 2.0 Metadata XML", "cs": "Ve SAML 2.0 metadata xml form\u00e1tu:", "tr": "XML format\u0131nda SAML 2.0 SP \u00dcstverisi (Metadata)", "de": "Im SAML 2.0 Metadaten-XML Format:", "fr": "Au format XML de m\u00e9tadonn\u00e9es SAML 2.0", "it": "Metadati SAML 2.0 in formato XML:", "ja": "SAML 2.0 \u7528\u306e\u30e1\u30bf\u30c7\u30fc\u30bfXML\u30d5\u30a9\u30fc\u30de\u30c3\u30c8:", "lt": "SAML 2.0 Metaduomenys XML formatu:", "zh-tw": "\u5728 SAML 2.0 Metadata XML \u683c\u5f0f\uff1a", "et": "SAML 2.0 metaandmete XML-vormingus:", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e2\u05d1\u05d5\u05e8 SAML 2.0 \u05d1\u05ea\u05d1\u05e0\u05d9\u05ea XML:", "zh": "\u5728SAML 2.0 XML \u5143\u4fe1\u606f\u683c\u5f0f\u4e2d\uff1a", "ar": "\u0628\u064a\u0627\u0646\u0627\u062a SAML 2.0 \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0628\u0635\u064a\u063a\u0629 XML", "lv": "SAML 2.0 metadatos XML form\u0101t\u0101:", "id": "Dalam format XML Metadata SAML 2.0", "sr": "Metapodaci u SAML 2.0 XML formatu:", "ro": "\u00cen format metadate XML SAML 2.0:", "ru": "xml \u0444\u043e\u0440\u043c\u0430\u0442 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 SAML 2.0:", "eu": "SAML 2.0 metadatuetako xml formatuan:", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03c3\u03b5 \u03bc\u03bf\u03c1\u03c6\u03ae xml SAML 2.0:", "ca": "En format XML de metadades SAML 2.0:" }, "debug_sending_message_text_link": { "no": "Du er i ferd med \u00e5 sende en melding. Trykk p\u00e5 send melding knappen for \u00e5 fortsette.", "nn": "Du er i ferd med \u00e5 senda ei melding. Trykk p\u00e5 send-peikaren for \u00e5 g\u00e5 vidare", "sv": "Du \u00e4r p\u00e5 v\u00e4g att skicka ett meddelande. Klicka p\u00e5 skickal\u00e4nken f\u00f6r att forts\u00e4tta.", "es": "Se va a proceder a enviar un mensaje. Pulse el enlace \"Enviar mensaje\" para continuar.", "nl": "U gaat een bericht versturen. Klik op de Verstuur bericht link om door te gaan.", "sl": "Sporo\u010dilo boste poslali s klikom na gumb za po\u0161iljanje.", "da": "Du er ved at sende en besked. Tryk p\u00e5 'send' for forts\u00e6tte", "hr": "Kliknite na poveznicu \"Po\u0161alji poruku\" da biste poslali poruku.", "hu": "\u00dczenetet k\u00fcldhet. Kattintson az \u00dczenet k\u00fcld\u00e9se linkre a folytat\u00e1shoz.", "pt-br": "Voc\u00ea est\u00e1 prestes a enviar uma mensagem. Clique no link enviar a mensagem para continuar.", "pt": "Est\u00e1 prestes a enviar uma mensagem. Carregue na liga\u00e7\u00e3o para continuar.", "cs": "M\u016f\u017eete poslat zpr\u00e1vu. Klikn\u011bte na odkaz pro pokra\u010dov\u00e1n\u00ed.", "eu": "Mezu bat bidaltzeari ekingo zaio. Saka ezazu \"Mezua bidali\" lotura jarraitzeko.", "tr": "Mesaj g\u00f6ndermek \u00fczeresiniz. Devam etmek i\u00e7in mesaj g\u00f6nder linkine t\u0131klay\u0131n.", "de": "Sie sind dabei eine Nachricht zu senden. Klicken Sie auf den Nachricht senden Link um fortzufahren.", "fr": "Vous allez envoyer un message. Cliquez sur le lien d'envoi pour continuer.", "it": "Si sta per inviare un messaggio. Premere il pulsante di invio per continuare.", "ja": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002\u7d9a\u3051\u308b\u306b\u306f\u30e1\u30c3\u30bb\u30fc\u30b8\u9001\u4fe1\u30ea\u30f3\u30af\u3092\u62bc\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "lt": "J\u016bs\u0173 prane\u0161imas siun\u010diamas. Nor\u0117dami t\u0119sti, paspauskite prane\u0161imo patvirtinimo nuorod\u0105.", "zh-tw": "\u60a8\u6b63\u5728\u50b3\u9001\u4e00\u5247\u8a0a\u606f\uff0c\u8acb\u9ede\u9078\u50b3\u9001\u8a0a\u606f\u9023\u7d50\u4f86\u7e7c\u7e8c\u3002", "et": "Oled teadet saatmas. J\u00e4tkamiseks vajuta teateviidet.", "he": "\u05d0\u05ea\u05d4 \u05e2\u05d5\u05de\u05d3 \u05dc\u05e9\u05dc\u05d5\u05d7 \u05d4\u05d5\u05d3\u05e2\u05d4. \u05dc\u05d7\u05e5 \u05e2\u05dc \u05db\u05e4\u05ea\u05d5\u05e8 \u05d4\u05e9\u05dc\u05d9\u05d7\u05d4 \u05db\u05d3\u05d9 \u05dc\u05d4\u05de\u05e9\u05d9\u05da.", "zh": "\u4f60\u51c6\u5907\u53d1\u9001\u4e00\u4e2a\u6d88\u606f\uff0c\u8bf7\u70b9\u51fb\u63d0\u4ea4\u94fe\u63a5\u4ee5\u7ee7\u7eed", "ar": "\u0627\u0646\u062a \u0639\u0644\u064a \u0648\u0634\u0643 \u0625\u0631\u0633\u0627\u0644 \u0631\u0633\u0627\u0644\u0629. \u0627\u0636\u063a\u0637 \u0639\u0644\u064a \u0627\u0644\u0631\u0627\u0628\u0637 \u0644\u0644\u0645\u0648\u0627\u0635\u0644\u0629", "lv": "J\u016bs gatavojaties s\u016bt\u012bt zi\u0146u. Spiediet saiti S\u016bt\u012bt zi\u0146u.", "id": "Anda baru saja akan mengirim sebuah pesan. Tekan link submit pesan untuk melanjutkan.", "sr": "Kliknite na link \"Po\u0161alji poruku\" da biste poslali poruku.", "ro": "Mesajul este preg\u0103tit pentru a fi trimis. Ap\u0103sa\u021bi link-ul de trimitere pentru a continua.", "ru": "\u0412\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0435\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0441\u0441\u044b\u043b\u043a\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f.", "el": "\u03a0\u03c1\u03cc\u03ba\u03b5\u03b9\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 \u03ad\u03bd\u03b1 \u03bc\u03ae\u03bd\u03c5\u03bc\u03b1. \u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u00ab\u03a5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03bf\u03c2\u00bb \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03b5\u03c4\u03b5.", "ca": "Esteu a punt d'enviar un missatge. Premeu l'enlla\u00e7 d'enviar el missatge per continuar." }, "debug_sending_message_send": { "no": "Send melding", "nn": "Send melding", "sv": "Skicka meddelande", "es": "Enviar mensaje", "nl": "Verstuur bericht", "sl": "Po\u0161lji sporo\u010dilo", "da": "Send besked", "hr": "Po\u0161alji poruku", "hu": "\u00dczenet k\u00fcld\u00e9se", "pt-br": "Enviar mensagem", "pt": "Enviar mensagem", "pl": "Wy\u015blij wiadomo\u015b\u0107", "cs": "Poslat zpr\u00e1vu", "eu": "Mezua bidali", "tr": "Mesaj g\u00f6nder", "de": "Nachricht senden", "fr": "Envoi du message", "it": "Invio messaggio", "ja": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1", "lt": "Patvirtinti prane\u0161im\u0105", "zh-tw": "\u50b3\u9001\u8a0a\u606f", "et": "Saada teade", "he": "\u05e9\u05dc\u05d7 \u05d4\u05d5\u05d3\u05e2\u05d4", "zh": "\u63d0\u4ea4\u4fe1\u606f", "ar": "\u0633\u0644\u0645 \u0627\u0644\u0631\u0633\u0627\u0644\u0629", "lv": "S\u016bt\u012bt zi\u0146u", "id": "Submit pesan", "sr": "Po\u0161alji poruku", "ro": "Trimite mesajul", "ru": "\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435", "el": "\u03a5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03bf\u03c2", "ca": "Enviar missatge" }, "debug_sending_message_msg_title": { "no": "Melding", "nn": "Melding", "sv": "Meddelande", "es": "Mensaje", "nl": "Bericht", "sl": "Sporo\u010dilo", "da": "Besked", "hr": "Poruka", "hu": "\u00dczenet", "pt-br": "Mensagem", "pt": "Mensagem", "pl": "Wiadomo\u015b\u0107", "cs": "Zpr\u00e1va", "tr": "Mesaj", "de": "Nachricht", "fr": "Message", "it": "Messaggio", "ja": "\u30e1\u30c3\u30bb\u30fc\u30b8", "lt": "Prane\u0161imas", "zh-tw": "\u8a0a\u606f", "et": "Teade", "he": "\u05d4\u05d5\u05d3\u05e2\u05d4", "zh": "\u4fe1\u606f", "ar": "\u0631\u0633\u0627\u0644\u0629", "lv": "Zi\u0146a", "id": "Pesan", "sr": "Poruka", "ro": "Mesaj", "ru": "\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435", "eu": "Mezua", "el": "\u039c\u03ae\u03bd\u03c5\u03bc\u03b1", "ca": "Missatge" }, "debug_sending_message_msg_text": { "no": "Siden du er i debug modus kan du se innholdet i meldingene du sender.", "nn": "Sidan du er inne i feils\u00f8kingsmodus, ser du innhaldet av meldinga du sender: ", "sv": "Med avseende p\u00e5 att du \u00e4r i debugl\u00e4ge kommer du att se inneh\u00e5llet i meddelandet som du skickar:", "es": "Si est\u00e1 en modo de depuraci\u00f3n, ver\u00e1 el contenido del mensaje que va a enviar:", "nl": "Omdat u in debug mode bent, kunt u de inhoud van het bericht dat u verstuurt inzien", "sl": "Ste v debug na\u010dinu, lahko si ogledate vsebino sporo\u010dila, ki ga po\u0161iljate", "da": "Fordi du er i debug-mode kan du se indholdet af de beskeder du sender:", "hr": "Obzirom da ste u modu za otkrivanje gre\u0161aka, imate mogu\u0107nost vidjeti sadr\u017eaj poruke koju \u0161aljete:", "hu": "Mivel hibakeres\u0151 m\u00f3dban van, l\u00e1thatja az elk\u00fcldend\u0151 \u00fczenet tartalm\u00e1t", "pt-br": "Como voc\u00ea est\u00e1 no modo de debug, voc\u00ea pode ver o conte\u00fado da mensagem que voc\u00ea est\u00e1 enviando:", "pt": "Estando em modo debug, pode consultar o conte\u00fado da mensagem que est\u00e1 a enviar:", "cs": "Pokud jste v debug m\u00f3du, m\u016f\u017eete videt obsah zpr\u00e1vy, kterou pos\u00edl\u00e1te:", "tr": "\"Debug\" modda oldu\u011funuz i\u00e7in, g\u00f6nderdi\u011finiz mesaj\u0131n i\u00e7eri\u011fini g\u00f6receksiniz.", "de": "Da Sie sich im Debug-Modus befinden, sehen Sie den Inhalt der Nachricht, die Sie senden:", "fr": "Le mode de d\u00e9bogage est activ\u00e9, le contenu du message envoy\u00e9 est affich\u00e9 :", "it": "Poich\u00e8 ci si trova in modalit\u00e0 di debug, si pu\u00f2 vedere il contenuto del messaggio che si sta per inviare:", "ja": "\u304a\u6c17\u3065\u304d\u306e\u69d8\u306b\u3042\u306a\u305f\u306f\u30c7\u30d0\u30c3\u30b0\u30e2\u30fc\u30c9\u306b\u3044\u307e\u3059\u3002\u3042\u306a\u305f\u306f\u9001\u4fe1\u3059\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u5185\u5bb9\u3092\u898b\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002", "lt": "\u012ejungtas detalus nar\u0161ymas, tod\u0117l matote siun\u010diamos \u017einut\u0117s turin\u012f:", "zh-tw": "\u7576\u60a8\u5728\u9664\u932f\u6a21\u5f0f\u6642\uff0c\u60a8\u5c07\u53ef\u4ee5\u770b\u5230\u60a8\u6240\u50b3\u9001\u7684\u8a0a\u606f\u5167\u5bb9\uff1a", "et": "Kuna oled silumisre\u017eiimis, siis on sul v\u00f5imalik n\u00e4ha saadetava teate sisu:", "he": "\u05db\u05d9\u05d5\u05d5\u05df \u05e9\u05d0\u05ea\u05d4 \u05d1\u05de\u05e6\u05d1 \u05de\u05d1\u05d3\u05d9\u05e7\u05ea \u05d1\u05d0\u05d2\u05d9\u05dd, \u05d0\u05ea\u05d4 \u05e8\u05d5\u05d0\u05d4 \u05d0\u05ea \u05ea\u05d5\u05db\u05df \u05d4\u05d4\u05d5\u05d3\u05e2\u05d4 \u05e9\u05d0\u05ea\u05d4 \u05e9\u05d5\u05dc\u05d7:", "zh": "\u5f53\u4f60\u5904\u5728\u8c03\u8bd5\u6a21\u5f0f\u4e2d\u65f6\uff0c\u4f60\u5c06\u770b\u5230\u4f60\u6b63\u5728\u53d1\u9001\u7684\u6d88\u606f\u7684\u5185\u5bb9", "ar": "\u064a\u0645\u0643\u0646\u0643 \u0631\u0624\u064a\u0629 \u0645\u062d\u062a\u0648\u064a \u0627\u0644\u0631\u0633\u0627\u0644\u0629 \u0637\u0627\u0644\u0645\u0627 \u0643\u0646\u062a \u0641\u064a \u062d\u0627\u0644\u0629 \u062a\u0635\u062d\u064a\u062d", "lv": "T\u0101 k\u0101 \u0161is ir atk\u013c\u016bdo\u0161anas re\u017e\u012bms, J\u016bs varat redz\u0113t s\u016bt\u0101m\u0101s zi\u0146as saturu:", "id": "Karena anda berada pada mode debug, anda dapat melihat isi pesan yang anda kirim:", "sr": "Obzirom da ste u debug modu, imate mogu\u0107nost videti sadr\u017eaj poruke koju \u0161aljete:", "ro": "\u00centruc\u00e2t sunte\u021bi \u00een modul depanare, ve\u021bi vedea con\u021binutul mesajului care va fi trimis:", "ru": "\u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0435\u0441\u044c \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.", "eu": "Arazketa moduan egonez gero, bidaltzera zoazen mezuaren edukia ikusiko duzu: ", "el": "\u0395\u03c0\u03b5\u03b9\u03b4\u03ae \u03b5\u03af\u03c3\u03c4\u03b5 \u03c3\u03b5 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03b5\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03bf\u03cd \u03c3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd (debug), \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b5\u03af\u03c4\u03b5 \u03c4\u03bf \u03c0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf \u03c4\u03bf\u03c5 \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c0\u03bf\u03c5 \u03c3\u03c4\u03ad\u03bb\u03bd\u03b5\u03c4\u03b5:", "ca": "Mentre esteu en mode de depuraci\u00f3, podreu veure el contingut del missatge que envieu:" }, "metaover_group_metadata.saml20-sp-remote": { "no": "SAML 2.0 Tjenesteleverand\u00f8r (ekstern)", "nn": "SAML 2.0 Service Provider (Remote)", "sv": "SAML 2.0 Service Provider (Fj\u00e4rr)", "es": "Proveedor de Servicio SAML 2.0 (remoto)", "nl": "SAML 2.0 Service Provider (Remote)", "sl": "SAML 2.0 SP (Oddaljeni)", "da": "SAML 2.0 tjenesteudbyder (remote)", "hr": "SAML 2.0 davatelj usluge (udaljeni)", "hu": "SAML 2.0 alkalmaz\u00e1sszolg\u00e1ltat\u00f3 (t\u00e1voli)", "pt-br": "SAML 2.0 Service Provider (Remoto)", "pt": "Fornecedor de servi\u00e7o (SP) SAML 2.0 (Remoto)", "pl": "SAML 2.0 Dostawca Serwisu (Zdalny)", "cs": "SAML 2.O Service Provider (Remote - vzd\u00e1len\u00fd)", "tr": "SAML 2.0 Servis Sa\u011flay\u0131c\u0131 (Uzak sistemde sunulan)", "de": "SAML 2.0 Service Provider (entfernt)", "fr": "Fournisseur de service SAML 2.0 distant", "it": "SAML 2.0 Service Provider (Remoto)", "ja": "SAML 2.0\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0(\u30ea\u30e2\u30fc\u30c8)", "lt": "SAML 2.0 Paslaugos teik\u0117jas (nutol\u0119s)", "zh-tw": "SAML 2.0 \u670d\u52d9\u63d0\u4f9b\u8005 (\u9060\u7aef)", "et": "SAML 2.0 teenusepakkuja (kaug)", "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05e8\u05d5\u05d7\u05e7 \u05de\u05e1\u05d5\u05d2 SAML 2.0", "zh": "SAML 2.0 \u670d\u52a1\u63d0\u4f9b\u8005 (\u8fdc\u7a0b)", "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 SAML 2.0 \u0627\u0644\u0628\u0639\u064a\u062f", "lv": "SAML 2.0 servisa pieg\u0101d\u0101t\u0101js (att\u0101lin\u0101ts)", "id": "Service Provider SAML 2.0 (Remote)", "sr": "SAML 2.0 Davalac Servisa (udaljeni)", "ro": "Furnizor de servicii SAML 2.0 (distant)", "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 SAML 2.0 (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "SAML 2.0 Zerbitzu hornitzailea (Urrunekoa)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd SAML 2.0 (\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis SAML 2.0 (remot)" }, "metaover_group_metadata.saml20-idp-hosted": { "no": "SAML 2.0 Identitetsleverand\u00f8r (ekstern)", "nn": "SAML 2.0 Identity Provider (Hosted)", "sv": "SAML 2.0 Identity Provider (V\u00e4rd)", "es": "Proveedor de Identidad SAML 2.0 (local)", "nl": "SAML 2.0 Identity Provider (Hosted)", "sl": "SAML 2.0 IdP (Lokalni)", "da": "SAML 2.0 identitetsudbyder (hosted)", "hr": "SAML 2.0 autentifikacijski servis (lokalni)", "hu": "SAML 2.0 szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (helyi)", "pt-br": "SAML 2.0 Identity Provider (Local)", "pt": "Fornecedor de identidade (IdP) SAML 2.0 (Local)", "pl": "SAML 2.0 Dostawca To\u017csamo\u015bci (Lokalny)", "cs": "SAML 2.0 Identity Provider (Hosted - lok\u00e1ln\u00ed)", "tr": "SAML 2.0 Kimlik Sa\u011flay\u0131c\u0131 (Bu sistemde sunulan)", "de": "SAML 2.0 Identity Provider (gehosted)", "fr": "Fournisseur d'identit\u00e9 SAML 2.0 local", "it": "SAML 2.o Identity Provider (Hosted)", "ja": "SAML 2.0\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0(\u30db\u30b9\u30c8)", "lt": "SAML 2.0 Tapatybi\u0173 teik\u0117jas (vietinis)", "zh-tw": "SAML 2.0 \u9a57\u8b49\u63d0\u4f9b\u8005 (\u672c\u5730)", "et": "SAML 2.0 identiteedipakkuja (hostitud)", "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9 \u05de\u05e1\u05d5\u05d2 SAML 2.0", "zh": "SAML 2.0 \u8eab\u4efd\u63d0\u4f9b\u8005\uff08\u672c\u5730\uff09", "ar": "\u0645\u0642\u062f\u0645 \u0647\u0648\u064a\u0629 SAML 2.0 \u0627\u0644\u0645\u0633\u062a\u0636\u0627\u0641", "lv": "SAML 2.0 identit\u0101tes pieg\u0101d\u0101t\u0101js (host\u0113ts)", "id": "Identity Provider SAML 2.0 (Hosted)", "sr": "SAML 2.0 Davalac Identiteta (lokalni)", "ro": "Furnizor de identitate SAML 2.0 (g\u0103zduit)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 SAML 2.0 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "SAML 2.0 Identitate hornitzailea (Anfitrioia)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 SAML 2.0 (\u03a6\u03b9\u03bb\u03bf\u03be\u03b5\u03bd\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2)", "ca": "Proveïdor d'identitat SAML 2.0 (allotjat)" }, "metaover_group_metadata.saml20-idp-remote": { "no": "SAML 2.0 Identitetsleverand\u00f8r (ekstern)", "nn": "SAML 2.0 Identity Provider (Remote)", "sv": "SAML 2.0 Identity Provider (Fj\u00e4rr)", "es": "Proveedor de Identidad SAML 2.0 (remoto)", "nl": "SAML 2.0 Identity Provider (Remote)", "sl": "SAML 2.0 IdP (Oddaljeni)", "da": "SAML 2.0 identitetsudbyder (remote)", "hr": "SAML 2.0 autentifikacijski servis (udaljeni)", "hu": "SAML 2.0 szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (t\u00e1voli)", "pt-br": "SAML 2.0 Identity Provider (Remoto)", "pt": "Fornecedor de identidade (IdP) SAML 2.0 (Remoto)", "pl": "SAML 2.0 Dostawca To\u017csamo\u015bci (Zdalny)", "cs": "SAML 2.0 Identity Provider (Remote - vzd\u00e1len\u00fd)", "tr": "SAML 2.0 Kimlik Sa\u011flay\u0131c\u0131 (Uzak sistemde sunulan)", "de": "SAML 2.0 Identity Provider (entfernt)", "fr": "Fournisseur d'identit\u00e9 SAML 2.0 distant", "it": "SAML 2.0 Identity Provider (Remoto)", "ja": "SAML 2.0\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0(\u30ea\u30e2\u30fc\u30c8)", "lt": "SAML 2.0 Tapatybi\u0173 teik\u0117jas (nutol\u0119s)", "zh-tw": "SAML 2.0 \u9a57\u8b49\u63d0\u4f9b\u8005 (\u9060\u7aef)", "et": "SAML 2.0 identiteedipakkuja (hostitud)", "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05de\u05e8\u05d5\u05d7\u05e7 \u05de\u05e1\u05d5\u05d2 SAML 2.0", "zh": "SAML 2.0 \u8eab\u4efd\u63d0\u4f9b\u8005\uff08\u8fdc\u7a0b\uff09", "ar": "\u0645\u0642\u062f\u0645 \u0647\u0648\u064a\u0629 SAML 2.0 \u0627\u0644\u0628\u0639\u064a\u062f", "lv": "SAML 2.0 identit\u0101tes pieg\u0101d\u0101t\u0101js (att\u0101lin\u0101ts)", "id": "Identity Provider SAML 2.0 (Remote)", "sr": "SAML 2.0 Davalac Identiteta (udaljeni)", "ro": "Furnizor de identitate SAML 2.0 (distant)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 SAML 2.0 (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "SAML 2.0 Identitate hornitzailea (Urrunekoa)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 SAML 2.0 (\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03bf\u03c2)", "ca": "Proveïdor d'identitat SAML 2.0 (remot)" }, "metaover_group_metadata.shib13-sp-hosted": { "no": "Shib 1.3 Tjenesteleverand\u00f8r (intern)", "nn": "Shib 1.3 Service Provider (Hosted)", "sv": "Shib 1.3 Service Provider (V\u00e4rd)", "es": "Proveedor de Servicio Shib 1.3 (local)", "nl": "Shib 1.3 Service Provider (Hosted)", "sl": "Shib 1.3 SP (Lokalni)", "da": "Shibboleth 1.3 tjenesteudbyder (hosted)", "hr": "Shib 1.3 davatelj usluge (lokalni)", "hu": "Shib 1.3 alkalmaz\u00e1sszolg\u00e1lat\u00f3 (helyi)", "pt-br": "Shib 1.3 Service Provider (Local)", "pt": "Fornecedor de servi\u00e7o (SP) Shib 1.3 (Local)", "pl": "Shib 1.3 Dostawca Serwisu (Lokalny)", "cs": "Shib 1.3 Service Provider (Hosted - lok\u00e1ln\u00ed)", "tr": "Shib 1.3 Servis Sa\u011flay\u0131c\u0131 (Bu sistemde sunulan)", "de": "Shib 1.3 Service Provider (gehosted)", "fr": "Fournisseur de service Shib 1.3 local", "it": "Shib 1.3 Service Provider (Hosted)", "ja": "Shib 1.3\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0(\u30db\u30b9\u30c8)", "lt": "Shib 1.3 Paslaugos teik\u0117jas (vietinis)", "zh-tw": "Shib 1.3 \u670d\u52d9\u63d0\u4f9b\u8005 (\u672c\u5730)", "et": "Shib 1.3 teenusepakkuja (hostitud)", "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 \u670d\u52a1\u63d0\u4f9b\u8005\uff08\u672c\u5730\uff09", "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 Shib 1.3 \u0627\u0644\u0645\u0633\u062a\u0636\u0627\u0641", "lv": "Shib 1.3 servisa pieg\u0101d\u0101t\u0101js (host\u0113ts)", "id": "Service Provider Shib 1.3 (Hosted)", "sr": "Shib 1.3 Davalac Servisa (lokalni)", "ro": "Furnizor de servicii Shib 1.3 (g\u0103zduit)", "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 Shib 1.3 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "Shib 1.3 Zerbitzu hornitzailea (Anfitrioia)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd Shib 1.3 (\u03a6\u03b9\u03bb\u03bf\u03be\u03b5\u03bd\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis Shib 1.3 (allotjat)" }, "metaover_group_metadata.shib13-sp-remote": { "no": "Shib 1.3 Tjenesteleverand\u00f8r (ekstern)", "nn": "Shib 1.3 Service Provider (Remote)", "sv": "Shib 1.3 Service Provider (Fj\u00e4rr)", "es": "Proveedor de Servicio Shib 1.3 (remoto)", "nl": "Shib 1.3 Service Provider (Remote)", "sl": "Shib 1.3 SP (Oddaljeni)", "da": "Shibboleth 1.3 tjenesteudbyder (remote)", "hr": "Shib 1.3 davatelj usluge (udaljeni)", "hu": "Shib 1.3 alkalmaz\u00e1sszolg\u00e1ltat\u00f3 (t\u00e1voli)", "pt-br": "Shib 1.3 Service Provider (Remoto)", "pt": "Fornecedor de servi\u00e7o (SP) SAML 2.0 (Remoto)", "pl": "Shib 1.3 Dostawca Serwisu (Zdalny)", "cs": "Shib 1.3 Service Provider (Remote - vzd\u00e1len\u00fd)", "tr": "Shib 1.3 Servis Sa\u011flay\u0131c\u0131 (Uzak sistemde sunulan)", "de": "Shib 1.3 Service Provider (entfernt)", "fr": "Fournisseur de service Shib 1.3 distant", "it": "Shib 1.3 Service Provider (Remoto)", "ja": "Shib 1.3\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0(\u30ea\u30e2\u30fc\u30c8)", "lt": "Shib 1.3 Paslaugos teik\u0117jas (nutol\u0119s)", "zh-tw": "Shib 1.3 \u670d\u52d9\u63d0\u4f9b\u8005 (\u9060\u7aef)", "et": "Shib 1.3 teenusepakkuja (kaug)", "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05e8\u05d5\u05d7\u05e7 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 \u670d\u52a1\u63d0\u4f9b\u8005\uff08\u8fdc\u7a0b\uff09", "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 Shib 1.3 \u0627\u0644\u0628\u0639\u064a\u062f", "lv": "Shib 1.3 servisa pieg\u0101d\u0101t\u0101js (att\u0101lin\u0101ts)", "id": "Service Provider Shib 1.3 (Remote)", "sr": "Shib 1.3 Davalac Servisa (udaljeni)", "ro": "Furnizor de servicii Shib 1.3 (distant)", "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 Shib 1.3 (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "Shib 1.3 Zerbitzu hornitzailea (Urrunekoa)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd Shib 1.3 (\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis Shib 1.3 (remot)" }, "metaover_group_metadata.shib13-idp-hosted": { "no": "Shib 1.3 Identitetsleverand\u00f8r (ekstern)", "nn": "Shib 1.3 Identity Provider (Hosted)", "sv": "Shib 1.3 Identity Provider (V\u00e4rd)", "es": "Proveedor de Identidad Shib 1.3 (local)", "nl": "Shib 1.3 Identity Provider (Hosted)", "sl": "Shib 1.3 SP (Lokalni)", "da": "Shibboleth 1.3 identitetsudbyder (hosted)", "hr": "Shib 1.3 autentifikacijski servis (lokalni)", "hu": "Shib 1.3 szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (helyi)", "pt-br": "Shib 1.3 Identity Provider (Local)", "pt": "Fornecedor de identidade (IdP) Shib 1.3 (Local)", "pl": "Shib 1.3 Dostawca To\u017csamo\u015bci (Lokalny)", "cs": "Shib 1.3 Identity Provider (Hosted - lok\u00e1ln\u00ed)", "tr": "Shib 1.3 Kimlik Sa\u011flay\u0131c\u0131 (Bu sistemde sunulan)", "de": "Shib 1.3 Identity Provider (gehosted)", "fr": "Fournisseur d'identit\u00e9 Shib 1.3 local", "it": "Shib 1.3 Identity Provider (Hosted)", "ja": "Shib 1.3\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0(\u30db\u30b9\u30c8)", "lt": "Shib 1.3 Tapatybi\u0173 teik\u0117jas (vietinis)", "zh-tw": "Shib 1.3 \u9a57\u8b49\u63d0\u4f9b\u8005 (\u672c\u5730)", "et": "Shib 1.3 identiteedipakkuja (hostitud)", "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 \u8ba4\u8bc1\u63d0\u4f9b\u8005\uff08\u672c\u5730\uff09", "ar": "\u0645\u0642\u062f\u0645 \u0647\u0648\u064a\u0629 Shib 1.3 \u0627\u0644\u0645\u0633\u062a\u0636\u0627\u0641", "lv": "Shib 1.3 identit\u0101tes pieg\u0101d\u0101t\u0101js (host\u0113ts)", "id": "Identity Provider Shib 1.3 (Hosted)", "sr": "Shib 1.3 Davalac Identiteta(lokalni)", "ro": "Furnizor de identitate Shib 1.3 (g\u0103zduit)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Shib 1.3 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "Shib 1.3 Identitate hornitzailea (Anfitrioia)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 Shib 1.3 (\u03a6\u03b9\u03bb\u03bf\u03be\u03b5\u03bd\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2)", "ca": "Proveïdor d'identitat Shib 1.3 (allotjat)" }, "metaover_group_metadata.shib13-idp-remote": { "no": "Shib 1.3 Identitetsleverand\u00f8r (ekstern) ", "nn": "Shib 1.3 Identity Provider (Remote)", "sv": "Shib 1.3 Identity Provider (Fj\u00e4rr)", "es": "Proveedor de Identidad Shib 1.3 (remoto)", "nl": "Shib 1.3 Identity Provider (Remote)", "sl": "Shib 1.3 SP (Oddaljeni)", "da": "Shibboleth 1.3 identitetsudbyder (remote)", "hr": "Shib 1.3 autentifikacijski servis (udaljeni)", "hu": "Shib 1.3 szem\u00e9lyazonoss\u00e1g-szolg\u00e1ltat\u00f3 (t\u00e1voli)", "pt-br": "Shib 1.3 Identity Provider (Remoto)", "pt": "Fornecedor de identidade (IdP) Shib 1.3 (Remoto)", "pl": "Shib 1.3 Dostawca To\u017csamo\u015bci (Zdalny)", "cs": "Shib 1.3 Identity Provider (Remote - vzd\u00e1len\u00fd)", "tr": "Shib 1.3 Kimlik Sa\u011flay\u0131c\u0131 (Uzak sistemde sunulan)", "de": "Shib 1.3 Identity Provider (entfernt)", "fr": "Fournisseur d'identit\u00e9 Shib 1.3 distant", "it": "Shib 1.3 Identity Provider (Remoto)", "ja": "Shib 1.3\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30d7\u30ed\u30d0\u30a4\u30c0(\u30ea\u30e2\u30fc\u30c8)", "lt": "Shib 1.3 Tapatybi\u0173 teik\u0117jas (nutol\u0119s)", "zh-tw": "Shib 1.3 \u9a57\u8b49\u63d0\u4f9b\u8005 (\u9060\u7aef)", "et": "Shib 1.3 identiteedipakkuja (kaug)", "he": "\u05e1\u05e4\u05e7 \u05d6\u05d4\u05d5\u05ea \u05de\u05e8\u05d5\u05d7\u05e7 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 \u8ba4\u8bc1\u63d0\u4f9b\u8005\uff08\u8fdc\u7a0b\uff09", "ar": "\u0645\u0642\u062f\u0645 \u0647\u0648\u064a\u0629 Shib 1.3 \u0627\u0644\u0628\u0639\u064a\u062f", "lv": "Shib 1.3 identit\u0101tes pieg\u0101d\u0101t\u0101js (att\u0101lin\u0101ts)", "id": "Identity Provider Shib 1.3 (Remote)", "sr": "Shib 1.3 Davalac Identiteta (udaljeni)", "ro": "Furnizor de identitate Shib 1.3 (distant)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Shib 1.3 (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "Shib 1.3 Identitate hornitzailea (Urrunekoa)", "ca": "Proveïdor d'identitat Shib 1.3 (remot)" }, "metaconv_title": { "no": "Metadata parser", "nn": "Parser for metadata", "sv": "Metadataanalyserare", "es": "Analizar metadatos", "nl": "Metadata parser", "sl": "Metapodatkovna sintakti\u010dna analiza (parser)", "da": "Metadata parser", "hr": "Analizator metapodataka", "hu": "Metaadat \u00e9rtelmez\u0151", "pt-br": "Parser Metadata", "pt": "Conversor de Metadados", "pl": "Parser metadanych", "cs": "Metadata parser", "tr": "\u00dcstveri (metadata) \u00e7\u00f6z\u00fcmleyici", "de": "Metadaten-Parser", "fr": "Analyseur de m\u00e9tadonn\u00e9es", "it": "Parser dei metadati", "ja": "\u30e1\u30bf\u30c7\u30fc\u30bf\u30d1\u30fc\u30b5", "lt": "Metaduomen\u0173 analizatorius", "zh-tw": "Metadata \u89e3\u6790", "et": "Metaandmete parsija", "he": "\u05de\u05e0\u05ea\u05d7 \u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2", "zh": "\u5143\u4fe1\u606f\u5206\u6790\u5668", "ar": "\u0645\u062d\u0644\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629\/\u0627\u0644\u0645\u064a\u062a\u0627\u062f\u0627\u062a\u0627", "lv": "Metadatu pars\u0113t\u0101js", "id": "Parser metadata", "sr": "Metadata analizator", "ro": "Analizor de metadate", "ru": "\u0421\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445", "eu": "Metadatuak aztertu", "el": "\u0391\u03bd\u03b1\u03bb\u03c5\u03c4\u03ae\u03c2 (parser) \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd", "ca": "Analitzador de metadades" }, "metaconv_selectfile": { "zh-tw": "\u6216\u9078\u64c7\u4e00\u500b\u6a94\u6848\uff1a", "el": "\u03ae \u03b5\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf", "ca": "o seleccioneu un fitxer:" }, "metaconv_xmlmetadata": { "no": "XML metadata", "nn": "XML metadata", "sv": "XML-metadata", "es": "Metadatos XML", "nl": "XML metadata", "sl": "XML metapodatki", "da": "XML metadata", "hr": "Metapodaci u XML formatu", "hu": "XML metaadat", "pt-br": "Metadata XML", "pt": "Metadados em XML", "pl": "XML Metadane", "cs": "XML Metadata", "tr": "XML \u00fcstverisi (metadata)", "de": "XML-Metadaten", "fr": "M\u00e9tadonn\u00e9es XML", "it": "Metadati XML", "ja": "XML\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "XML metaduomenys", "zh-tw": "XML Metadata", "et": "XML-metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05d1\u05ea\u05d1\u05e0\u05d9\u05ea XML", "zh": "XML\u5143\u4fe1\u606f", "ar": "\u0628\u064a\u0627\u0646\u0627\u062a \u0648\u0635\u0641\u064a\u0629 \u0628\u0635\u064a\u063a\u0629 XML", "lv": "XML metadati", "id": "metadata XML", "sr": "Metapodaci u XML formatu", "ro": "Metadate XML", "ru": "XML \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435", "eu": "XML metadatuak", "el": "\u0391\u03bd\u03b1\u03bb\u03c5\u03c4\u03ae\u03c2 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd XML", "ca": "Metadades XML" }, "metaconv_parse": { "no": "Pars", "nn": "Parser", "sv": "Analysera", "es": "Analizar", "nl": "Parse", "sl": "Sintakti\u010dna analiza (parse)", "da": "Parse", "hr": "Analiziraj", "hu": "\u00c9rtelmez", "pt-br": "Parse", "pt": "Converter", "pl": "Przetw\u00f3rz", "cs": "Anal\u00fdza", "tr": "\u00c7\u00f6z\u00fcmle", "de": "Parse", "fr": "Analyser", "it": "Analisi", "ja": "\u30d1\u30fc\u30b9", "lt": "Nagrin\u0117ti", "zh-tw": "\u89e3\u6790", "et": "Parsi", "he": "\u05e0\u05ea\u05d7", "zh": "\u5206\u6790\u5668", "ar": "\u062d\u0644\u0644", "lv": "Pars\u0113t", "id": "Parse", "sr": "Analiziraj", "ro": "Analizeaz\u0103", "ru": "\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437", "eu": "Aztertu", "el": "\u0391\u03bd\u03ac\u03bb\u03c5\u03c3\u03b7", "ca": "Analitzar" }, "metaconv_converted": { "no": "Konvertert metadata", "nn": "Konverterte metadata", "sv": "Omformat metadata", "es": "Metadatos convertidos", "nl": "Geconverteerde metadata", "sl": "Pretvorjeni metapodatki", "da": "Konverteret metadata", "hr": "Pretvoreni metapodaci", "hu": "Konvert\u00e1lt metaadatok", "pt-br": "Metadata convetida", "pt": "Resultado da convers\u00e3o de Metadados", "pl": "Skonwertowane metadane", "cs": "Konvertovan\u00e1 metadata", "tr": "D\u00f6n\u00fc\u015ft\u00fcr\u00fclm\u00fc\u015f \u00fcstveri (metadata)", "de": "Konvertierte Metadaten", "fr": "M\u00e9tadonn\u00e9es converties", "it": "Metadati convertiti", "ja": "\u5909\u63db\u3055\u308c\u305f\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "Sukonvertuoti metaduomenys", "zh-tw": "\u5df2\u8f49\u63db\u4e4b Metadata", "et": "Teisendatud metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05de\u05d5\u05de\u05e8", "zh": "\u8f6c\u6362\u8fc7\u7684\u5143\u4fe1\u606f", "ar": "\u0628\u064a\u0627\u0646\u0627\u062a \u0648\u0635\u0641\u064a\u0629 \u0645\u062d\u0648\u0644\u0629", "lv": "Konvert\u0113tie metadati", "id": "Metadata yang telah dikonvesi", "sr": "Konvertovani metapodaci", "ro": "Metadate convertite", "ru": "\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435", "eu": "Bihurtutako metadatuak", "el": "\u039c\u03b5\u03c4\u03b1\u03c4\u03c1\u03b1\u03c0\u03ad\u03bd\u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1", "ca": "Metadades convertides" }, "metadata_saml20-sp": { "no": "SAML 2.0 SP metadata", "nn": "SAML 2.0 SP Metadata", "sv": "SAML 2.0 SP Metadata", "es": "Metadatos SP SAML 2.0", "nl": "SAML 2.0 SP Metadata", "sl": "SAML 2.0 SP Metapodatki", "da": "SAML 2.0 tjenesteudbyders metadata", "hr": "SAML 2.0 metapodaci o davatelju usluge", "hu": "SAML 2.0 SP Metaadatok", "pt-br": "SAML 2.0 SP Metadata", "pt": "Metadados SAML 2.0 SP", "pl": "SAML 2.0 SP - Metadane", "cs": "SAML 2.0 SP Metadata", "tr": "SAML 2.0 SP \u00dcstveri (Metadata)", "de": "SAML 2.0 SP Metadaten", "fr": "M\u00e9tadonn\u00e9es de SP SAML 2.0", "it": "Metadati SAML 2.0 SP", "ja": "SAML 2.0 SP\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "SAML 2.0 SP Metaduomenys", "zh-tw": "SAML 2.0 SP Metadata", "et": "SAML 2.0 SP metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05e9 \u05de\u05e1\u05d5\u05d2 SAML 2.0 ", "zh": "SAML 2.0 SP \u5143\u4fe1\u606f", "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644 SAML 2.0 SP", "lv": "SAML 2.0 SP metadati", "id": "Metadata SAML 2.0 SP", "sr": "SAML 2.0 SP metapodaci", "ro": "Metadate furnizor de servicii (SP) SAML 2.0", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 SAML 2.0 SP", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd SAML 2.0", "ca": "Metadades SAML 2.0 SP" }, "metadata_saml20-idp": { "no": "SAML 2.0 IdP metadata", "nn": "SAML 2.0 IdP Metadata", "sv": "SAML 2.0 IdP Metadata", "es": "Metadatos IdP SAML 2.0", "nl": "SAML 2.0 IdP Metadata", "sl": "SAML 2.0 IdP Metapodatki", "da": "SAML 2.0 identitetsudbyders metadata", "hr": "SAML 2.0 metapodaci o autentifikacijskom servisu", "hu": "SAML 2.0 IdP Metaadatok", "pt-br": "SAML 2.0 IdP Metadata", "pt": "Metadados SAML 2.0 IdP", "pl": "SAML 2.0 IdP - Metadane", "cs": "SAML 2.0 IdP Metadata", "tr": "SAML 2.0 IdP \u00dcstveri (Metadata)", "de": "SAML 2.0 IdP Metadaten", "fr": "M\u00e9tadonn\u00e9es d'IdP SAML 2.0", "it": "Metadati SAML 2.0 IdP", "ja": "SAML 2.0 IdP\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "SAML 2.0 IdP Metaduomenys", "zh-tw": "SAML 2.0 IdP Metadata", "et": "SAML 2.0 IdP metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05d6 \u05de\u05e1\u05d5\u05d2 SAML 2.0 ", "zh": "SAML 2.0 IdP \u5143\u4fe1\u606f", "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644 SAML 2.0 IdP", "lv": "SAML 2.0 IdP metadati", "id": "Metadata SAML 2.0 IdP", "sr": "SAML 2.0 IdP metapodaci", "ro": "Metadate furnizor de identitate (IdP) SAML 2.0", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 SAML 2.0 IdP", "eu": "SAML 2.0 IdP Metadatuak ", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 SAML 2.0", "ca": "Metadades SAML 2.0 IdP" }, "metadata_shib13-sp": { "no": "Shib 1.3 SP metadata", "nn": "Shib 1.3 SP Metadata", "sv": "Shib 1.3 SP Metadata", "es": "Metadatos SP Shib 1.3", "nl": "Shib 1.3 SP Metadata", "sl": "Shib 1.3 SP Metapodatki", "da": "Shibboleth 1.3 tjenesteudbyders metadata", "hr": "Shib 1.3 metapodaci o davatelju usluge", "hu": "Shib 1.3 SP Metaadatok", "pt-br": "Shib 1.3 SP Metadata", "pt": "Metadados Shib 1.3 SP", "pl": "Shib 1.3 SP - Metadane", "cs": "Shib 1.3 SP Metadata", "tr": "Shib 1.3 SP \u00dcstveri (Metadata)", "de": "Shib 1.3 SP Metadaten", "fr": "M\u00e9tadonn\u00e9es de SP Shib 1.3", "it": "Metadati Shib 1.3 SP", "ja": "Shib 1.3 SP\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "Shib 1.3 SP Metaduomenys", "zh-tw": "Shib 1.3 SP Metadata", "et": "Shib 1.3 SP metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05e9 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 SP \u5143\u4fe1\u606f", "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644Shib 1.3 SP", "lv": "Shib 1.3 SP metadati", "id": "Metadata Shib 1.3 SP", "sr": "Shib 1.3 SP metapodaci", "ro": "Metadate furnizor de servicii (SP) Shib 1.3", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 Shib 1.3 SP", "eu": "Shib 1.3 SP Metadatuak ", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd Shib 1.3", "ca": "Metadades Shib 1.3 SP" }, "metadata_shib13-idp": { "no": "Shib 1.3 IdP metadata", "nn": "Shib 1.3 IdP Metadata", "sv": "Shib 1.3 IdP Metadata", "es": "Metadatos IdP Shib 1.3", "nl": "Shib 1.3 IdP Metadata", "sl": "Shib 1.3 IdP Metapodatki", "da": "Shibboleth 1.3 identitetsudbyders metadata", "hr": "Shib 1.3 metapodaci o autentifikacijskom servisu", "hu": "Shib 1.3 IdP Metaadatok", "pt-br": "Shib 1.3 IdP Metadata", "pt": "Metadados Shib 1.3 IdP", "pl": "Shib 1.3 IdP - Metadane", "cs": "Shib 1.3 IdP Metadata", "tr": "Shib 1.3 IdP \u00dcstveri (Metadata)", "de": "Shib 1.3 IdP Metadaten", "fr": "M\u00e9tadonn\u00e9es d'IdP Shib 1.3", "it": "Metadati Shib 1.3 IdP", "ja": "Shib 1.3 IdP\u30e1\u30bf\u30c7\u30fc\u30bf", "lt": "Shib 1.3 IdP Metaduomenys", "zh-tw": "Shib 1.3 IdP Metadata", "et": "Shib 1.3 IdP metaandmed", "he": "\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9\u05dc \u05e1\u05d6 \u05de\u05e1\u05d5\u05d2 Shib 1.3", "zh": "Shib 1.3 IdP \u5143\u4fe1\u606f", "ar": "\u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0644Shib 1.3 IdP", "lv": "Shib 1.3 IdP metadati", "id": "Metadata Shib 1.3 IdP", "sr": "Shib 1.3 IdP metapodaci", "ro": "Metadate furnizor de identitate (IdP) Shib 1.3", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 Shib 1.3 IdP", "eu": "Shib 1.3 IdP Metadatuak ", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 Shib 1.3", "ca": "Metadades Shib 1.3 IdP" }, "metadata_intro": { "no": "Her er metadata som SimpleSAMLphp har generert for deg. Du m\u00e5 utveksle metadata med de partene du stoler p\u00e5 for \u00e5 sette opp en f\u00f8derasjon.", "nn": "Her er metadata generert av SimpleSAMLphp for deg. Du kan senda dette metadata-dokumentet til dine partnarar, slik at de kan setja opp ein tillitsf\u00f8derasjon.", "sv": "SimpleSAMLphp har har genererat f\u00f6ljande metadata. F\u00f6r att s\u00e4tta upp en betrodd federation kan du skicka metadata till de parter du har f\u00f6rtroende f\u00f6r.", "es": "Aqu\u00ed est\u00e1n los metadatos que SimpleSAMLphp ha generado. Puede enviar este documento de metadatos a sus socios de confianza para configurar una federaci\u00f3n.", "nl": "Dit is de metadata die automatisch is gegenereerd door SimpleSAMLphp. U kunt deze metadata uitwisselen met uw federatiepartners.", "sl": "Tu so metapodatki, ki jih je generiral SimpleSAMLphp. Dokument lahko po\u0161ljete zaupanja vrednim partnerjem, s katerimi boste ustvarili federacijo.", "da": "Her er det metadata, som SimpleSAMLphp har genereret. Du kan sende det til dem du stoler i forbindelse med oprettelsen af en f\u00f8deration.", "hr": "Ovo su metapodaci koje je SimpleSAMLphp izgenerirao za vas. Te metapodatke mo\u017eete poslati davateljima usluga ili elektroni\u010dkih identiteta u koje imate povjerenja i s kojima \u017eelite uspostaviti federaciju.", "hu": "Ezeket a metaadatokat a SimpleSAMLphp gener\u00e1lta. Ezt a dokumentumot k\u00fcldheti el f\u00f6der\u00e1ci\u00f3s partnerei sz\u00e1m\u00e1ra.", "pt-br": "Aqui est\u00e1 a metadata que o SimpleSAMLphp gerou para voc\u00ea. Voc\u00ea pode enviar este documento metadata para parceiros confi\u00e1veis para a configura\u00e7\u00e3o de uma federa\u00e7\u00e3o confi\u00e1vel.", "pt": "De seguida pode encontrar os metadados gerados pelo SimpleSAMLphp. Pode enviar este documento de metadados aos seus parceiros para configurar uma federa\u00e7\u00e3o.", "pl": "Tutaj sa metadane, kt\u00f3re SimpleSAMLphp wygenerowa\u0142 dla Ciebie. Mo\u017cesz je wys\u0142a\u0107 zaufanym partnerom w celu stworzenia zaufanej federacji.", "cs": "Zde jsou metadata, kter\u00e1 pro v\u00e1s SimpleSAMLphp generuje. M\u016f\u017eete zaslat tento dokument sv\u00fdm d\u016fv\u011bryhodn\u00fdm partner\u016fm a zalo\u017eit tak federaci.", "tr": "SimpleSAMLphp'nin sizin i\u00e7in \u00fcretti\u011fi \u00fcstveri (metada). Bu \u00fcstveri dok\u00fcman\u0131n\u0131 g\u00fcvenilir bir federasyon kurmak i\u00e7in g\u00fcvenilir payda\u015flara g\u00f6nderebilirsiniz.", "de": "Hier finden Sie die Metadaten, die SimpleSAMLphp f\u00fcr Sie erzeugt hat. Sie k\u00f6nnen dieses Metadaten-Dokument zu Partnern schicken, denen Sie vertrauen, um eine vertrauensbasierte F\u00f6deration aufzusetzen.", "fr": "Voici les m\u00e9tadonn\u00e9es g\u00e9n\u00e9r\u00e9es par SimpleSAMLphp. Vous pouvez les envoyer \u00e0 vos partenaires de confiances pour construire une f\u00e9d\u00e9ration d'identit\u00e9.", "it": "Questi sono i metadati che SimpleSAMLphp ha generato e che possono essere inviati ai partner fidati per creare una federazione tra siti.", "ja": "\u3053\u3053\u306f SimpleSAMLphp \u304c\u751f\u6210\u3057\u305f\u30e1\u30bf\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u3059\u3002\u3042\u306a\u305f\u306f\u4fe1\u983c\u3059\u308b\u30d1\u30fc\u30c8\u30ca\u30fc\u306b\u3053\u306e\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u9001\u4fe1\u3057\u4fe1\u983c\u3055\u308c\u305f\u9023\u643a\u3092\u69cb\u7bc9\u51fa\u6765\u307e\u3059\u3002", "lt": "Metaduomenys, kuriuos Jums sugeneravo SimpleSAMLphp. Norint \u012fsteigti patikim\u0105 federacij\u0105, galite patikimiems partneriams i\u0161si\u0173sti \u0161iuos metaduomenis.", "zh-tw": "\u9019\u662f SimpleSAMLphp \u7522\u751f\u7d66\u60a8\u7684 Metadata\uff0c\u60a8\u53ef\u4ee5\u50b3\u9001\u6b64 Metadata \u6587\u4ef6\u7d66\u60a8\u4fe1\u4efb\u7684\u5408\u4f5c\u5925\u4f34\u4f86\u5efa\u7acb\u4fe1\u4efb\u806f\u76df\u3002", "et": "Need on SimpleSAMLphp poolt sulle genereeritud metaandmed. V\u00f5id saata need metaandmed usaldatavatele partneritele usaldatava f\u00f6deratsiooni loomiseks.", "he": "\u05d4\u05e0\u05d4 \u05d4\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05e9 SimpleSAMLphp \u05d9\u05d9\u05e6\u05e8 \u05e2\u05d1\u05d5\u05e8\u05da. \u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05e9\u05dc\u05d5\u05d7 \u05d0\u05ea \u05de\u05e1\u05de\u05da \u05d4\u05de\u05d8\u05d0-\u05de\u05d9\u05d3\u05e2 \u05dc\u05e9\u05d5\u05ea\u05e4\u05d9\u05dd \u05de\u05d4\u05d9\u05de\u05e0\u05d9\u05dd \u05db\u05d3\u05d9 \u05dc\u05d9\u05e6\u05d5\u05e8 \u05d0\u05d9\u05d7\u05d5\u05d3 \u05de\u05d0\u05d5\u05d1\u05d8\u05d7. ", "zh": "\u8fd9\u91cc\u662fSimpleSAMLphp\u4e3a\u4f60\u751f\u6210\u7684\u5143\u4fe1\u606f\uff0c\u4f60\u5e94\u8be5\u53d1\u9001\u8fd9\u4e2a\u5143\u4fe1\u606f\u6587\u6863\u7ed9\u4f60\u7684\u4fe1\u4efb\u7684\u5408\u4f5c\u4f19\u4f34\u4ee5\u5efa\u7acb\u4fe1\u4efb\u7684\u8054\u76df", "ar": "\u0647\u0630\u0647 \u0647\u064a \u0628\u064a\u0627\u0646\u0627\u062a\u0643 \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0627\u0644\u0645\u062c\u0647\u0632\u0629 \u0628\u0648\u0627\u0633\u0637\u0629 SAMLphp. \u0644\u0644\u062a\u062c\u0647\u064a\u0632 \u0644\u0641\u062f\u0631\u0627\u0644\u064a\u0629 \u0645\u0648\u062b\u0648\u0642 \u0628\u0647\u0627 \u0642\u0645 \u0628\u0625\u0631\u0633\u0627\u0644 \u0647\u0630\u0647 \u0627\u0644\u0648\u062b\u064a\u0642\u0629 \u0644\u0634\u0631\u0643\u0627\u0621 \u0645\u0648\u062b\u0648\u0642 \u0628\u0647\u0645", "lv": "\u0160eit ir SimpleSAMLphp \u0123ener\u0113tie metadati. J\u016bs varat tos s\u016bt\u012bt partneriem, lai izveidotu uzticamu feder\u0101ciju.", "id": "Berikut ini adalah SimpleSAMLphp metadata yang telah digenerate untuk Anda. Anda dapat mengirim dokumen metadata ini kepada rekan yang dipercayai untuk mensetup federasi terpercaya.", "sr": "Ovo su metapodaci koje je SimpleSAMLphp izgenerisao za vas. Te metapodatke mo\u017eete poslati davaocima servisa ili davaocima identiteta u koje imate poverenja i sa kojima \u017eelite uspostaviti federaciju.", "ro": "Acestea sunt metadate generate de SimpleSAMLphp. Metadatele pot fi trimise c\u0103tre parteneri de \u00eencredere pentru a configura o federa\u021bie de \u00eencredere.", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0432\u0430\u0441 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SimpleSAMLphp. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c \u043f\u0430\u0440\u0442\u043d\u0435\u0440\u0430\u043c \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0435\u0434\u0435\u0440\u0430\u0446\u0438\u0438.", "eu": "Hona hemen SimpleSAMLphp-ak zuretzat sortu dituen metadatuak. Metadatuen dokumentu hau konfidantzazko zure kideei bidal diezaiekezu federazio bat konfiguratzeko.", "el": "\u0391\u03c5\u03c4\u03ac \u03b5\u03af\u03bd\u03b1\u03b9 \u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03c0\u03bf\u03c5 \u03ad\u03c7\u03bf\u03c5\u03bd \u03c0\u03b1\u03c1\u03b1\u03c7\u03b8\u03b5\u03af \u03b1\u03c0\u03cc \u03c4\u03bf \u0053\u0069\u006d\u0070\u006c\u0065\u0053\u0041\u004d\u004c\u0070\u0068\u0070 \u03b3\u03b9\u03b1 \u03b5\u03c3\u03ac\u03c2. \u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c4\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 \u03c3\u03b5 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2 \u03c0\u03bf\u03c5 \u03b5\u03bc\u03c0\u03b9\u03c3\u03c4\u03b5\u03cd\u03b5\u03c3\u03c4\u03b5 \u03c0\u03c1\u03bf\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03bf\u03bc\u03bf\u03c3\u03c0\u03bf\u03bd\u03b4\u03af\u03b1.", "ca": "Aqu\u00ed hi ha les metadades que SimpleSAMLphp ha generat per a vost\u00e8. Podeu enviar aquest document de metadades a clients/proveïdors de confian\u00e7a per configurar una federaci\u00f3 de confian\u00e7a." }, "metadata_xmlurl": { "no": "Du kan n\u00e5 metadata i XML-format p\u00e5 en dedikert URL<\/a>:", "nn": "Du kan f\u00e5 metadata i XML p\u00e5 ein URL<\/a>:", "sv": "Du kan h\u00e4mta metadata i XML-format p\u00e5 dedicerad URL<\/a>:", "es": "Puede obtener una URL con los metadatos xml<\/a>:", "nl": "U kunt deze directe URL gebruiken<\/a> om de metadata XML op te vragen:", "sl": "XML metapodatki se nahajajo na tem naslovu<\/a>:", "da": "Du kan f\u00e5 metadata-xml her<\/a>:", "hr": "Metapodaci su dostupni na ovoj adresi<\/a>:", "hu": "A k\u00f6vetkez\u0151 c\u00edmr\u0151l t\u00f6ltheti le a metaadatokat<\/a>:", "pt-br": "Voc\u00ea pode obter as metadatas xml em uma URL dedicada<\/a>:", "pt": "Pode obter os metadados em XML num URL dedicado<\/a>:", "pl": "Mo\u017cesz pobra\u0107 metadane w formacie xml<\/a>:", "cs": "Z\u00edskejte metadata v XML form\u00e1tu na dedikovan\u00e9 adrese<\/a>", "tr": "\u00dcstveri xml'ini bu ba\u011flant\u0131dan alabilirsiniz<\/a>:", "de": "Sie k\u00f6nnen das Metadaten-XML auf dieser URL erhalten:<\/a>:", "fr": "Vous pouvez obtenir ces m\u00e9tadonn\u00e9es XML depuis une URL d\u00e9di\u00e9e<\/a>:", "it": "Si possono ottenere i metadati in XML dall'URL dedicata<\/a>:", "ja": "\u3053\u306eURL\u3067\u30e1\u30bf\u30c7\u30fc\u30bf\u306eXML\u3092\u53d6\u5f97\u3067\u304d\u307e\u3059<\/a>:", "lt": "J\u016bs galite gauti metaduomenis XML formatu<\/a>:", "zh-tw": "\u60a8\u53ef\u4ee5\u5728 \u76f4\u63a5\u53d6\u5f97 Metadata XML \u683c\u5f0f\u6a94<\/a>", "et": "Metaandmete XML-i on v\u00f5imalik saada spetsiaalselt aadressilt<\/a>:", "he": "\u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05e7\u05d1\u05dc \u05d0\u05ea \u05d4\u05de\u05d8\u05d0 \u05de\u05d9\u05d3\u05e2 \u05d1\u05db\u05ea\u05d5\u05d1\u05ea \u05e0\u05e4\u05e8\u05d3\u05ea<\/a>:", "zh": "\u4f60\u53ef\u4ee5\u5728 \u83b7\u53d6\u5143\u4fe1\u606fXML<\/a>", "ar": "\u064a\u0645\u0643\u0646\u0643 \u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u064a \u0628\u064a\u0627\u0646\u0627\u062a\u0643 \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0628\u0645\u0644\u0641 xml \u0628 URL \u0645\u062a\u062e\u0635\u0635 \u0628\u0625\u062f\u062e\u0627\u0644", "lv": "J\u016bs varat sa\u0146emt metadatu xml \u0161aj\u0101 URL<\/a>:", "id": "Anda dapat mendapatkan xml metadata pada URL tersendiri<\/a>:", "sr": "Metapodaci su dostupni na ovoj adresi<\/a>:", "ro": "Pute\u021bi accesa metadatele xml de la un URL dedicat<\/a>:", "ru": "\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c xml \u0444\u0430\u0439\u043b \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 URL<\/a>:", "eu": "xml metadatuekin URL bat<\/a> eskura dezakezu:", "el": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03bb\u03ae\u03c8\u03b7\u03c2<\/a> \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd:", "ca": "Podeu obtenir una URL amb les metadades en XML <\/a>:" }, "metadata_simplesamlformat": { "no": "I SimpleSAMLphp format - bruk denne dersom du benytter SimpleSAMLphp i den andre enden:", "nn": "P\u00e5 flat fil for SimpleSAMLphp. Bruk denne dersom du bruker SimpleSAMLphp p\u00e5 andre sida:", "sv": "I filformatet f\u00f6r simpleSAML, anv\u00e4nd detta detta format om SimpleSAMLphp anv\u00e4nds i mottagende sida:", "es": "En un fichero de formato SimpleSAMLphp - utilice esta opci\u00f3n si est\u00e1 usando una entidad SimpleSAMLphp en el otro extremo:", "nl": "In SimpleSAMLphp flat file formaat - gebruik dit wanneer uw federatiepartner ook SimpleSAMLphp gebruikt", "sl": "V SimpleSAMLphp \"flat file\" formatu - ta format uporabite, \u010de uporabljate SimpleSAMLphp entiteto na drugi strani:", "da": "I SimpleSAMLphp flat-file format - brug dette hvis du ogs\u00e5 bruger SimpleSAMLphp i den anden ende;", "hr": "U SimpleSAMLphp formatu - koristite ovu opciju ako se na drugoj strani tako\u0111er nalazi SimpleSAMLphp entitet:", "hu": "SimpleSAMLphp f\u00e1jl form\u00e1tumban - akkor haszn\u00e1lhat\u00f3, ha a m\u00e1sik oldalon SimpleSAMLphp van:", "pt-br": "Em formato de arquivo plano SimpleSAMLphp - use isso se voc\u00ea estiver usando uma entidade SimpleSAMLphp do outro lado:", "pt": "Metadados no formato ficheiro de configura\u00e7\u00e3o do SimpleSAMLphp. Use esta alternativa se usar uma entidade SimpleSAMLphp no outro extremo:", "cs": "Ve SimpleSAMLphp souborov\u00e9m form\u00e1tu (flat-file) - pou\u017eijte je, pokud pot\u0159ebujete pou\u017e\u00edvat SimpleSAMLphp na druh\u00e9 stran\u011b:", "tr": "E\u011fer di\u011fer tarafta bir SimpleSAMLphp eleman\u0131n\u0131 kullan\u0131yorsan\u0131z, d\u00fcz SimpleSAMLphp dosya bi\u00e7iminde bunu kullan\u0131n:", "de": "Im SimpleSAMLphp flat-file Format - verwenden Sie das, falls auf der Gegenseite eine SimpleSAMLphp-Entit\u00e4t zum Einsatz kommt:", "fr": "Au format \u00e0 plat SimpleSAMLphp - \u00e0 utiliser si vous avez une installation SimpleSAMLphp sur la partie adverse :", "it": "In formato flat per SimpleSAMLphp - da utilizzare se dall'altra parte c'\u00e8 un'entit\u00e0 che utilizza SimpleSAMLphp", "ja": "SimpleSAMLphp \u306e\u30d5\u30a1\u30a4\u30eb\u30d5\u30a9\u30fc\u30de\u30c3\u30c8 - \u7247\u5074\u3067\u3082 SimpleSAMLphp\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u306b\u3053\u308c\u3092\u4f7f\u7528\u3057\u307e\u3059:", "lt": "SimpleSAMLphp paprasto failo formatas - naudokite j\u012f, jei naudojate SimpleSAMLphp kitoje esyb\u0117je:", "zh-tw": "\u5982\u679c\u60a8\u9700\u8981\u65bc\u5176\u4ed6\u7ad9\u53f0\u4f7f\u7528 SimpleSAMLphp - \u8acb\u53c3\u95b1 SimpleSAMLphp \u5e73\u9762\u6587\u4ef6\u683c\u5f0f\uff1a", "et": "SimpleSAMLphp formaadis: kasuta seda siis, kui ka teine pool kasutab SimpleSAMLphp-d:", "he": "\u05d1\u05ea\u05d1\u05e0\u05d9\u05ea \u05e7\u05d5\u05d1\u05e5 SimpleSAMLphp \u05e9\u05d8\u05d5\u05d7 - \u05dc\u05de\u05e7\u05e8\u05d9\u05dd \u05d1\u05d4\u05dd \u05d0\u05ea\u05d4 \u05de\u05e9\u05ea\u05de\u05e9 \u05d1\u05d9\u05e9\u05d5\u05ea SimpleSAMLphp \u05d1\u05e6\u05d3 \u05d4\u05e9\u05e0\u05d9: ", "zh": "\u5982\u679c\u4f60\u60f3\u5728\u5176\u4ed6\u7f51\u7ad9\u4f7f\u7528\u7684SimpleSAMLphp\uff0c\u90a3\u4e48\u4f60\u5e94\u8be5\u4f7f\u7528SimpleSAMLphp\u6241\u5e73\u7684\u6587\u4ef6\u683c\u5f0f", "ar": "\u0628\u0635\u064a\u063a\u0629 SimpleSAMLphp- \u0627\u0633\u062a\u062e\u062f\u0645 \u0647\u0630\u0647 \u0627\u0644\u0635\u064a\u063a\u0629 \u0627\u0646 \u0643\u0646\u062a \u062a\u0633\u062a\u062e\u062f\u0645 \u0648\u062d\u062f\u0629 SimpleSAMLphp \u0628\u0627\u0644\u0627\u062a\u062c\u0627\u0647 \u0627\u0644\u0627\u062e\u0631 \u0627\u064a\u0636\u0627\u064b", "lv": "SimpleSAMLphp parasta faila form\u0101t\u0101 - lietojiet \u0161o, ja izmantojat SimpleSAMLphp ent\u012btiju otr\u0101 gal\u0101:", "id": "Dalam format file biasa SimpleSAMLphp - gunakan ini jika Anda menggunakan entiti SimpleSAMLphp pada sisi lain:", "sr": "U SimpleSAMLphp formatu - koristite ovu opciju ako se na drugoj strani tako\u0111e nalazi SimpleSAMLphp entitet:", "ro": "\u00cen format fi\u0219ier simplu SimpleSAMLphp - utiliza\u021bi aceast\u0103 variant\u0103 dac\u0103 \u00een cap\u0103tul cel\u0103lalt folosi\u021bi o entitate SimpleSAMLphp:", "ru": "\u0424\u043e\u0440\u043c\u0430\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e SimpleSAMLphp \u0444\u0430\u0439\u043b\u0430", "eu": "SimpleSAMLphp formatuko fitxategi batean - beste muturrean SimpleSAMLphp entitate bat erabiltzen ariz gero, erabil ezazu aukera hau:", "el": "\u03a3\u03b5 \u03bc\u03bf\u03c1\u03c6\u03ae \u03b1\u03c0\u03bb\u03bf\u03cd \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 SimpleSAMLphp - \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 \u03c4\u03b1 \u03bc\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7 \u03bc\u03bf\u03c1\u03c6\u03ae \u03b1\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1 \u0053\u0069\u006d\u0070\u006c\u0065\u0053\u0041\u004d\u004c\u0070\u0068\u0070 \u03c3\u03c4\u03b7\u03bd \u03ac\u03bb\u03bb\u03b7 \u03c0\u03bb\u03b5\u03c5\u03c1\u03ac:", "ca": "En un fitxer de format SimpleSAMLphp: utilitzeu aquesta opci\u00f3 si utilitzeu una entitat SimpleSAMLphp en l'altre extrem:" }, "debug_sending_message_title": { "no": "Sender melding", "nn": "Sender melding", "sv": "Skickar meddelande", "es": "Enviando mensaje", "nl": "Bericht", "sl": "Po\u0161iljanje sporo\u010dila", "da": "Sender besked", "hr": "\u0160aljem poruku", "hu": "\u00dczenet k\u00fcld\u00e9se", "pt-br": "Enviando a mensagem", "pt": "A enviar a mensagem", "pl": "Wysy\u0142anie wiadomo\u015bci", "cs": "Pos\u00edl\u00e1m zpr\u00e1vu", "eu": "Mezua bidaltzen", "tr": "Mesaj g\u00f6nderiliyor", "de": "Sende Nachricht", "fr": "Envoi du message", "it": "Invio del messaggio", "ja": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\u4e2d", "lt": "Siun\u010diamas prane\u0161imas", "zh-tw": "\u8a0a\u606f\u50b3\u9001\u4e2d", "et": "Teate saatmine", "he": "\u05e9\u05d5\u05dc\u05d7 \u05d4\u05d5\u05d3\u05e2\u05d4", "zh": "\u6b63\u5728\u53d1\u9001\u6d88\u606f", "ar": "\u0627\u0631\u0633\u0644 \u0631\u0633\u0627\u0644\u0629", "lv": "Zi\u0146as s\u016bt\u012b\u0161ana", "id": "Mengirimpan pesan", "sr": "\u0160aljem poruku", "ro": "Se trimite mesajul", "ru": "\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f", "el": "\u0391\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5", "ca": "S'est\u00e0 enviant el missatge" }, "debug_sending_message_text_button": { "no": "Du er i ferd med \u00e5 sende en melding. Trykk knappen \u00abSend melding\u00bb for \u00e5 fortsette.", "nn": "Du er i ferd med \u00e5 senda ei melding. Trykk p\u00e5 send-knappen for \u00e5 g\u00e5 vidare", "sv": "Du \u00e4r p\u00e5 v\u00e4g att skicka ett meddelande. Klicka p\u00e5 skickaknappen f\u00f6r att forts\u00e4tta.", "es": "Se va a proceder a enviar un mensaje. Pulse el bot\u00f3n \"Enviar mensaje\" para continuar.", "nl": "U gaat een bericht versturen. Klik op de Verstuur bericht knop om door te gaan.", "sl": "Sporo\u010dilo boste poslali s klikom na gumb za po\u0161iljanje.", "da": "Tryk p\u00e5 'send' for at forts\u00e6tte med at sende beskeden", "hr": "Kliknite na gumb \"Po\u0161alji poruku\" da biste poslali poruku.", "hu": "\u00dczenetet k\u00fcldhet. Kattintson az \u00dczenet k\u00fcld\u00e9se gombra a folytat\u00e1shoz.", "pt-br": "Voc\u00ea est\u00e1 prestes a enviar uma mensagem. Aperte o bot\u00e3o enviar mensagem para continuar.", "pt": "Est\u00e1 prestes a enviar uma mensagem. Carregue no bot\u00e3o para continuar.", "cs": "M\u016f\u017eete poslat zpr\u00e1vu. Po\u017eijte tla\u010d\u00edtko k pokra\u010dov\u00e1n\u00ed.", "eu": "Mezu bat bidaltzeari ekingo zaio. Saka ezazu \"Mezua bidali\" botoia jarraitzeko.", "tr": "Mesaj g\u00f6ndermek \u00fczeresiniz. Devam etmek i\u00e7in mesaj g\u00f6nder butonuna t\u0131klay\u0131n.", "de": "Sie sind dabei eine Nachricht zu senden. Klicken Sie auf den Nachricht senden Knopf um fortzufahren.", "fr": "Vous allez envoyer un message. Cliquez sur le bouton d'envoi pour continuer.", "it": "Si sta per inviare un messaggio. Premere il pulsante di invio per continuare.", "ja": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1\u3057\u307e\u3059\u3002\u7d9a\u3051\u308b\u306b\u306f\u30e1\u30c3\u30bb\u30fc\u30b8\u9001\u4fe1\u30dc\u30bf\u30f3\u3092\u62bc\u3057\u3066\u304f\u3060\u3055\u3044\u3002", "lt": "J\u016bs\u0173 prane\u0161imas siun\u010diamas. Nor\u0117dami t\u0119sti, paspauskite prane\u0161imo patvirtinimo mygtuk\u0105.", "zh-tw": "\u60a8\u6b63\u5728\u50b3\u9001\u4e00\u5247\u8a0a\u606f\uff0c\u8acb\u9ede\u9078\u50b3\u9001\u8a0a\u606f\u6309\u9215\u4f86\u7e7c\u7e8c\u3002", "et": "Oled teadet saatmas. J\u00e4tkamiseks vajuta teatesaatmisnuppu.", "he": "\u05d0\u05ea\u05d4 \u05e2\u05d5\u05de\u05d3 \u05dc\u05e9\u05dc\u05d5\u05d7 \u05d4\u05d5\u05d3\u05e2\u05d4. \u05dc\u05d7\u05e5 \u05e2\u05dc \u05db\u05e4\u05ea\u05d5\u05e8 \u05d4\u05e9\u05dc\u05d9\u05d7\u05d4 \u05db\u05d3\u05d9 \u05dc\u05d4\u05de\u05e9\u05d9\u05da.", "zh": "\u4f60\u51c6\u5907\u53d1\u9001\u4e00\u4e2a\u6d88\u606f\uff0c\u8bf7\u70b9\u51fb\u63d0\u4ea4\u6309\u94ae\u4ee5\u7ee7\u7eed", "ar": "\u0627\u0646\u062a \u0639\u0644\u064a \u0648\u0634\u0643 \u0625\u0631\u0633\u0627\u0644 \u0631\u0633\u0627\u0644\u0629. \u0627\u0636\u063a\u0637 \u0639\u0644\u064a \u0627\u0644\u0632\u0631 \u0644\u0644\u0645\u0648\u0627\u0635\u0644\u0629", "lv": "J\u016bs gatavojaties s\u016bt\u012bt zi\u0146u. Spiediet pogu S\u016bt\u012bt zi\u0146u.", "id": "Anda baru saja akan mengirim sebuah pesan. Tekan tombol submit pesan untuk melanjutkan.", "sr": "Kliknite na dugme \"Po\u0161alji poruku\" da biste poslali poruku.", "ro": "Mesajul este preg\u0103tit pentru a fi trimis. Ap\u0103sa\u021bi butonul de trimitere pentru a continua.", "ru": "\u0412\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0435\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f.", "el": "\u03a0\u03c1\u03cc\u03ba\u03b5\u03b9\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 \u03ad\u03bd\u03b1 \u03bc\u03ae\u03bd\u03c5\u03bc\u03b1. \u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u00ab\u03a5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03bf\u03c2\u00bb \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03b5\u03c4\u03b5.", "ca": "Esteu a punt d'enviar un missatge. Premeu el bot\u00f3 d'enviar el missatge per continuar." }, "debug_disable_debug_mode": { "no": "Do kan skru av debug modus i den globale SimpleSAMLphp konfigurasjonsfila config\/config.php<\/tt>.", "nn": "Du kan skru av feils\u00f8kingsmodus i den globale konfigurasjonsfila for SimpleSAMLphp config\/config.php<\/tt>.", "sv": "Du kan st\u00e4nga av debugl\u00e4get i SimpleSAMLphps globala konfigurationsfil config\/config.php<\/tt>.", "es": "Puede desactivar el modo de depuraci\u00f3n en el fichero de configuraci\u00f3n global de SimpleSAMLphp config\/config.php<\/tt>.", "nl": "U kunt debug mode uitschakelen in de globale SimpleSAMLphp configuratie file config\/config.php<\/tt>.", "sl": "Debug na\u010din lahko izklopite v globalni SimpleSAMLphp konfiguracijski datoteki config\/config.php<\/tt>.", "da": "Du kan sl\u00e5 debug-mode fra i den globale SimpleSAMLphp-konfigurationsfil config\/config.php<\/tt>", "hr": "Mod za otkrivanje gre\u0161aka mo\u017eete isklju\u010diti u glavnoj SimpleSAMLphp konfiguracijskoj datoteci config\/config.php<\/tt>. ", "hu": "A SimpleSAMLphp config\/config.php<\/tt> f\u00e1jlj\u00e1ban kikapcsolhatja a hibakeres\u0151 m\u00f3dot.", "pt-br": "Voc\u00ea pode desligar o modo de debug no arquivo de configura\u00e7\u00e3o global do SimpleSAMLphp config\/config.php<\/tt>.", "pt": "Pode desligar o modo debug no ficheiro global de configura\u00e7\u00e3o config\/config.php<\/tt> do SimpleSAMLphp.", "pl": "Mo\u017cesz wy\u0142aczy\u0107 globalnie tryb debugowania w pliku config\/config.php<\/tt>.", "cs": "M\u016f\u017eete vypnout debug m\u00f3d v globaln\u00ed konfiguraci SimpleSAMLphp config\/config.php<\/tt>.", "tr": "\"Debug\" modunu global SimpleSAMLphp konfig\u00fcrasyon dosyas\u0131nda config\/config.php<\/tt> kapatabilirsiniz.", "de": "Sie k\u00f6nnen den Debug-Modus in der globalen SimpleSAMLphp Konfigurationsdatei config\/config.php<\/tt> ausschalten.", "fr": "Vous pouvez d\u00e9sactivez le mode d\u00e9bogage dans le fichier de configuration globale de SimpleSAMLphp (config\/config.php<\/tt>).", "it": "E' possibile disabilitare la modalit\u00e0 di debug nel file di configurazione globale di SimpleSAMLphp, config\/config.php<\/tt>.", "ja": "\u3042\u306a\u305f\u306fSimpleSAMLphp\u306e\u30b0\u30ed\u30fc\u30d0\u30eb\u8a2d\u5b9aconfig\/config.php<\/tt>\u3067\u30c7\u30d0\u30c3\u30af\u30e2\u30fc\u30c9\u3092\u30aa\u30d5\u306b\u51fa\u6765\u307e\u3059\u3002", "lt": "J\u016bs galite i\u0161jungti detal\u0173j\u012f nar\u0161ym\u0105 globaliame SimpleSAMLphp konfig\u016braciniame faile config\/config.php<\/tt>.", "zh-tw": "\u60a8\u53ef\u4ee5 SimpleSAMLphp \u7684\u5168\u57df\u8a2d\u5b9a\u6a94 config\/config.php<\/tt> \u88e1\u95dc\u9589\u9664\u932f\u6a21\u5f0f\u3002", "et": "Silumisre\u017eiimi on v\u00f5imalik v\u00e4lja l\u00fclitada SimpleSAMLphp seadistustefailist config\/config.php<\/tt>.", "he": "\u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05db\u05d1\u05d5\u05ea \u05d0\u05ea \u05de\u05e6\u05d1 \u05d1\u05d3\u05d9\u05e7\u05ea \u05d4\u05d1\u05d0\u05d2\u05d9\u05dd \u05d1\u05e7\u05d5\u05d1\u05e5 \u05d1\u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05d4\u05d2\u05dc\u05d5\u05d1\u05dc\u05d9 \u05e9\u05dc SimpleSAMLphp config\/config.php<\/tt>.", "zh": "\u4f60\u53ef\u4ee5\u5173\u95ed\u8c03\u8bd5\u6a21\u5f0f\uff0c\u5728SimpleSAMLphp\u5168\u5c40\u914d\u7f6e\u6587\u4ef6config\/config.php<\/tt>\u4e2d", "ar": "\u064a\u0645\u0643\u0646\u0643 \u0625\u063a\u0644\u0627\u0642 \u062d\u0627\u0644\u0629 \u0627\u0644\u062a\u0635\u062d\u064a\u062d \u0628\u0645\u0644\u0641 \u062a\u0631\u062a\u064a\u0628 SimpleSAMLphpconfig\/config.php<\/tt>", "lv": "J\u016bs varat izsl\u0113gt atk\u013c\u016bdo\u0161anas re\u017e\u012bmu glob\u0101laj\u0101 SimpleSAMLphp konfigur\u0101cijas fail\u0101 config\/config.php<\/tt>.", "id": "Anda dapat menonaktifkan mode debuh pada file konfigurasi global simpleSAMLhphp config\/config.php<\/tt>.", "sr": "Debug mod mo\u017eete isklju\u010diti u glavnom SimpleSAMLphp konfiguracionom fajlu config\/config.php<\/tt>. ", "ro": "Se poate opri modul de depanare \u00een fi\u0219ierul de configurare SimpleSAMLphp config\/config.php<\/tt>.", "ru": "\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 global SimpleSAMLphp -config\/config.php<\/tt>. ", "eu": "Arazketa modua desaktibatu daiteke SimpleSAMLphp config\/config.php<\/tt> konfigurazio orokorreko fitxategian.", "el": "\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b1\u03c0\u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03b7 \u03bb\u03b5\u03b9\u03c4\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b5\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03bf\u03cd \u03c3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd (debug) \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c4\u03bf\u03c5 SimpleSAMLphp config\/config.php<\/tt>.", "ca": "Podeu desactivar el mode de depuraci\u00f3 al fitxer de configuraci\u00f3 global de SimpleSAMLphp config\/config.php<\/tt>." }, "metaover_group_metadata.saml20-sp-hosted": { "no": "SAML 2.0 tjenesteleverand\u00f8r (intern)", "nn": "SAML 2.0 Service Provider (Hosted)", "sv": "SAML 2.0 Service Provider (V\u00e4rd)", "es": "Proveedor de Servicio SAML 2.0 (local)", "nl": "SAML 2.0 Service Provider (Hosted)", "sl": "SAML 2.0 SP (Lokalni)", "da": "SAML 2.0 tjenesteudbyder (hosted)", "hr": "SAML 2.0 davatelj usluge (lokalni)", "hu": "SAML 2.0 alkalmaz\u00e1sszolg\u00e1ltat\u00f3 (helyi)", "pt-br": "SAML 2.0 Service Provider (Local)", "pt": "Fornecedor de servi\u00e7o (SP) SAML 2.0 (Local)", "pl": "SAML 2.0 Dostawca Serwisu (Lokalny)", "cs": "SAML 2.0 Service Provider (Hosted - lok\u00e1ln\u00ed)", "tr": "SAML 2.0 Servis Sa\u011flay\u0131c\u0131 (Bu sistemde sunulan)", "de": "SAML 2.0 Service Provider (gehosted)", "fr": "Fournisseur de service SAML 2.0 local", "it": "SAML 2.0 Service Provider (Hosted)", "ja": "SAML 2.0\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0(\u30db\u30b9\u30c8)", "lt": "SAML 2.0 Paslaugos teik\u0117jas (vietinis)", "zh-tw": "SAML 2.0 \u670d\u52d9\u63d0\u4f9b\u8005 (\u672c\u5730)", "et": "SAML 2.0 teenusepakkuja (hostitud)", "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea \u05de\u05e7\u05d5\u05de\u05d9 \u05de\u05e1\u05d5\u05d2 SAML 2.0", "zh": "SAML 2.0 \u670d\u52a1\u63d0\u4f9b\u8005\uff08\u672c\u5730\uff09", "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0629 SAML 2.0 (\u0627\u0644\u0645\u0633\u062a\u0636\u0627\u0641)", "lv": "SAML 2.0 servisa pieg\u0101d\u0101t\u0101js (host\u0113ts)", "id": "Service Provider SAML 2.0 (Hosted)", "sr": "SAML 2.0 Davalac Servisa (lokalni)", "ro": "Furnizor de servicii SAML 2.0 (g\u0103zduit)", "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 SAML 2.0 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "eu": "SAML 2.0 Zerbitzu hornitzailea (Anfitrioia)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd SAML 2.0 (\u03a6\u03b9\u03bb\u03bf\u03be\u03b5\u03bd\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis SAML 2.0 (allotjat)" }, "cfg_check_notices": { "no": "Notiser", "nn": "Legg merke til", "sv": "Meddelanden", "es": "Avisos", "nl": "Opmerkingen", "sl": "Obvestila", "da": "Beskeder", "hr": "Napomene", "hu": "Megjegyz\u00e9sek", "pt-br": "Avisos", "pt": "Observa\u00e7\u00f5es", "pl": "Uwagi", "cs": "Poznamky", "tr": "Notlar", "de": "Anmerkungen", "fr": "A noter", "it": "Notifiche", "ja": "\u304a\u77e5\u3089\u305b", "lt": "Prane\u0161imai", "zh-tw": "\u5099\u8a3b", "et": "M\u00e4rkused", "he": "\u05d4\u05d5\u05d3\u05e2\u05d5\u05ea", "ru": "\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f", "zh": "\u901a\u544a", "ar": "\u0645\u0644\u062d\u0648\u0638\u0627\u062a", "lv": "Br\u012bdin\u0101jumi", "id": "Pemberitahuan", "sr": "Napomene", "ro": "Note\/Observa\u021bii", "eu": "Oharrak", "el": "\u0395\u03b9\u03b4\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03b9\u03c2", "ca": "Avisos" }, "metadata_cert": { "nl": "Certificaten", "sl": "Digitalna potrdila", "sv": "Certifikat", "he": "\u05ea\u05e2\u05d5\u05d3\u05d5\u05ea", "et": "Sertifikaadid", "de": "Zertifikate", "zh": "\u8bc1\u4e66", "da": "Certifikater", "lt": "Sertifikatai", "hu": "Tan\u00fas\u00edtv\u00e1nyok.", "ar": "\u0627\u0644\u0634\u0647\u0627\u062f\u0627\u062a", "hr": "Certifikati", "lv": "Sertifik\u0101ti", "id": "Sertifikat", "sr": "Sertifikati", "nn": "Sertifikat", "fr": "Certificats", "cs": "Certifik\u00e1ty", "it": "Certificati", "es": "Certificados", "ro": "Certificate", "ru": "\u0421\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b", "no": "Sertifikater", "eu": "Ziurtagiriak", "zh-tw": "\u6191\u8b49", "el": "\u03a0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03ac", "ca": "Certificats" }, "metadata_cert_intro": { "nl": "Download de X509-certificaten in PEM-formaat.", "sl": "Prenesi X509 digitalno potrdilo v PEM datoteki.", "sv": "H\u00e4mta X509-certifikaten som PEM-kodade filer.", "he": "\u05d4\u05d5\u05e8\u05d3 \u05d0\u05ea \u05ea\u05e2\u05d5\u05d3\u05d5\u05ea X509 \u05db\u05e7\u05d1\u05e6\u05d9 PEM-\u05de\u05e7\u05d5\u05d3\u05d3.", "et": "Lae alla X509 sertifikaadid PEM kodeeringus failidena.", "de": "Die X509-Zertifikate als PEM-kodierte Dateien herunterladen.", "zh": "\u4e0b\u8f7dX509\u8bc1\u4e66\u4f5c\u4e3aPEM\u7f16\u7801\u7684\u6587\u4ef6", "da": "Download X509 certifikaterne som PEM-indkodet filer.", "lt": "Parsisi\u0173sti X509 sertifikatus kaip PEM koduot\u0117s failus.", "hu": "PEM form\u00e1tum\u00fa X509 tan\u00fas\u00edtv\u00e1ny let\u00f6lt\u00e9se.", "ar": "\u062d\u0645\u0644 \u0634\u0647\u0627\u062f\u0627\u062a X509 \u0643\u0645\u0644\u0641\u0627\u062a \u0628\u062a\u0631\u0645\u064a\u0632 PEM", "hr": "Preuzmite X509 certifikate u PEM formatu.", "lv": "Lejupiel\u0101d\u0113t X509 sertifik\u0101tus k\u0101 PEM-kod\u0113tus failus.", "id": "Download sertifikat X509 sebagai file dikodekan-PEM.", "sr": "Preuzmite X509 sertifikate u PEM formatu.", "nn": "Last ned X509-sertifikat som PEM-koda filer", "fr": "T\u00e9l\u00e9charger les certificats X509 en tant que fichiers encod\u00e9s PEM.", "cs": "St\u00e1hn\u011bte certifik\u00e1t X509 jako PEM-encoded soubor", "it": "Scarica i certificati X509 come file PEM-encoded", "es": "Descargar los certificados X509 en formato PEM.", "ro": "Desc\u0103rca\u021bi certificatele X509 ca fi\u0219iere PEM.", "ru": "\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b X509 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 PEM \u0444\u0430\u0439\u043b\u043e\u0432.", "no": "Last ned X509-sertifikatene som PEM-filer.", "eu": "X509 ziurtagiriak PEM formatuan deskargatu.", "zh-tw": "\u4e0b\u8f09 PEM \u683c\u5f0f\u4e4b X.509 \u6191\u8b49\u6a94\u6848", "el": "\u039b\u03ae\u03c8\u03b7 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03b9\u03b7\u03c4\u03b9\u03ba\u03ce\u03bd X.509 \u03c3\u03b5 \u03ba\u03c9\u03b4\u03b9\u03ba\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 PEM.", "ca": "Baixeu els certificats X509 en format PEM." }, "metaover_group_metadata.adfs-sp-remote": { "es": "Proveedor de Servicio ADFS (remoto)", "ru": "\u0421\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 ADFS (\u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "zh-tw": "ADFS \u670d\u52d9\u63d0\u4f9b\u8005 (\u9060\u7aef)", "nl": "ADFS Service Provider (Remote)", "da": "ADFS tjenesteudbyder (remote)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd ADFS (\u0391\u03c0\u03bf\u03bc\u03b1\u03ba\u03c1\u03c5\u03c3\u03bc\u03ad\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis ADFS (remot)" }, "metaover_group_metadata.adfs-idp-hosted": { "es": "Proveedor de Identidad ADFS (local)", "ru": "\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 ADFS (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435)", "zh-tw": "ADFS \u9a57\u8b49\u63d0\u4f9b\u8005 (\u672c\u5730)", "nl": "ADFS Identity Provider (Hosted)", "da": "ADFS identitetsudbyder (hosted)", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 ADFS (\u03a6\u03b9\u03bb\u03bf\u03be\u03b5\u03bd\u03bf\u03cd\u03bc\u03b5\u03bd\u03bf\u03c2)", "ca": "Proveïdor de serveis ADFS (allotjat)" }, "metadata_adfs-sp": { "es": "Metadatos SP ADFS", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 ADFS", "zh-tw": "ADFS \u670d\u52d9\u63d0\u4f9b\u8005 Metadata", "nl": "ADFS SP Metadata", "da": "ADFS tjenesteudbyder metadata", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a5\u03c0\u03b7\u03c1\u03b5\u03c3\u03b9\u03ce\u03bd ADFS", "ca": "Metadades ADFS SP" }, "metadata_adfs-idp": { "es": "Metadatos IdP ADFS", "ru": "\u041c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 ADFS", "zh-tw": "ADFS \u9a57\u8b49\u63d0\u4f9b\u8005 Metadata", "nl": "ADFS IdP Metadata", "da": "ADFS identitetsudbyder metadata", "el": "\u039c\u03b5\u03c4\u03b1\u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03b1 \u03a0\u03b1\u03c1\u03cc\u03c7\u03bf\u03c5 \u03a4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 ADFS", "ca": "Metadades ADFS IdP" } } simplesamlphp-1.19.1/dictionaries/general.translation.json0000644000000000000000000001567014042503475022516 0ustar rootroot{ "yes": { "no": "Ja", "nn": "Ja", "sv": "Ja", "es": "S\u00ed", "fr": "Oui", "de": "Ja", "nl": "Ja", "lb": "Jo", "sl": "Da", "da": "Ja", "hr": "Da", "hu": "Igen", "fi": "Kyll\u00e4", "pt-br": "Sim", "pt": "Sim", "pl": "Tak", "cs": "Ano", "tr": "Evet", "it": "S\u00ec", "lt": "Taip", "ja": "\u306f\u3044", "zh-tw": "\u662f", "et": "Jah", "he": "\u05db\u05df", "ru": "\u0434\u0430", "zh": "\u662f", "ar": "\u0646\u0639\u0645 \u0641\u0639\u0644\u0627", "lv": "J\u0101", "id": "Iya nih", "sr": "Da", "ro": "Da", "eu": "Bai", "af": "Ja", "el": "\u039d\u03b1\u03af", "zu": "Yebo", "xh": "Ewe", "st": "E", "ca": "Sí" }, "no": { "no": "Nei", "nn": "Nei", "sv": "Nej", "es": "No", "fr": "Non", "de": "Nein", "nl": "Nee", "lb": "Nee", "sl": "Ne", "da": "Nej", "hr": "Ne", "hu": "Nem", "fi": "ei", "pt-br": "N\u00e3o", "pt": "N\u00e3o", "pl": "Nie", "cs": "Ne", "tr": "Hay\u0131r", "it": "No", "lt": "Ne", "ja": "\u3044\u3044\u3048", "zh-tw": "\u5426", "et": "Ei", "he": "\u05dc\u05d0", "ru": "\u041d\u0435\u0442", "zh": "\u6ca1\u6709", "ar": "\u0644\u0627", "lv": "N\u0113", "id": "Tidak", "sr": "Ne", "ro": "Nu", "eu": "Ez", "af": "Nee", "el": "\u038c\u03c7\u03b9", "xh": "Hayi", "zu": "Cha", "st": "Tjhe", "ca": "No" }, "remember": { "no": "Godta ogs\u00e5 for fremtiden", "nn": "Godta ogs\u00e5 for framtida", "sv": "Spara samtycke", "es": "Recordar", "fr": "Se souvenir du consentement", "de": "Zustimmung merken", "nl": "Bewaar toestemming", "lb": "Zoust\u00ebmmung verhalen", "sl": "Zapomni si privolitev.", "da": "Husk samtykke", "hr": "Zapamti moj odabir", "hu": "Eml\u00e9kezzen a hozz\u00e1j\u00e1rul\u00e1sra", "fi": "Muista", "pt-br": "Lembrar Consentimento", "pt": "Lembrar a minha escolha", "pl": "Pami\u0119taj moj\u0105 zgod\u0119", "cs": "Zapamatuj", "tr": "Hat\u0131rla", "it": "Ricordare", "lt": "\u012esiminti", "ja": "\u8a18\u61b6\u3059\u308b", "zh-tw": "\u8a18\u4f4f", "et": "J\u00e4ta meelde", "he": "\u05d6\u05db\u05d5\u05e8", "ru": "\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c", "zh": "\u8bb0\u4f4f", "ar": "\u062a\u0630\u0643\u0631\u0623\u0644\u063a\u062a \u0630\u0643\u0631", "lv": "Atcer\u0113ties", "id": "Ingat", "sr": "Zapamti moj izbor", "ro": "\u021aine minte", "eu": "Onespena gogoratu", "af": "Onthou", "el": "\u039d\u03b1 \u03b8\u03c5\u03bc\u03ac\u03c3\u03b1\u03b9 \u03c4\u03b7\u03bd \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03bc\u03bf\u03c5", "zu": "Khumbula", "xh": "Khumbula", "st": "Hopola", "ca": "Recorda" }, "yes_continue": { "no": "Ja, fortsett", "nn": "Ja, fortsett", "sv": "Ja", "es": "S\u00ed, continuar", "fr": "Oui", "de": "Ja, ich stimme zu", "nl": "Ja, ik ga akkoord", "lb": "Jo", "sl": "Da, nadaljuj", "da": "Ja, jeg accepterer", "hr": "Da, nastavi", "hu": "Igen, elfogadom", "fi": "Kyll\u00e4", "pt-br": "Sim, Aceito", "pt": "Sim, Aceito", "pl": "Tak, akceptuj\u0119", "cs": "Ano, akceptuji", "tr": "Evet, devam et", "it": "S\u00ec, continuare", "lt": "Taip, t\u0119sti", "ja": "\u306f\u3044\u3001\u7d9a\u3051\u307e\u3059", "zh-tw": "\u662f\uff0c\u7e7c\u7e8c", "et": "Jah, j\u00e4tka", "he": "\u05db\u05df, \u05d4\u05de\u05e9\u05da", "ru": "\u0414\u0430, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c", "zh": "\u662f\u7684\uff0c\u7ee7\u7eed", "ar": "\u0646\u0639\u0645\u060c \u0648\u0627\u0635\u0644", "lv": "J\u0101, turpin\u0101t", "id": "Yam lanjutkan", "sr": "Da, nastavi", "ro": "Da, continu\u0103", "eu": "Bai, jarraitu", "af": "Ja, voortgaan", "el": "\u0391\u03c0\u03bf\u03b4\u03bf\u03c7\u03ae", "xh": "Ewe, qhubeka", "zu": "Yebo, qhubeka", "st": "E, tswela pele", "ca": "Sí, continua" }, "no_cancel": { "no": "Nei, avbryt", "nn": "Nei, avbryt", "sv": "Nej", "es": "No, cancelar", "fr": "Non", "de": "Nein, ich stimme nicht zu", "nl": "Nee, ik weiger", "lb": "Nee", "sl": "Ne, prekli\u010di", "da": "Nej, jeg accepterer ikke", "hr": "Ne, odustani", "hu": "Nem, nem fogadom el", "fi": "ei", "pt-br": "N\u00e3o, n\u00e3o aceito", "pt": "N\u00e3o aceito", "pl": "Nie, nie akceptuj\u0119", "cs": "Ne, neakceptuji", "tr": "Hay\u0131r, iptal et", "it": "No, cancellare", "lt": "Ne, nutraukti", "ja": "\u3044\u3044\u3048\u3001\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059", "zh-tw": "\u5426\uff0c\u53d6\u6d88", "et": "Ei, loobu", "he": "\u05dc\u05d0, \u05d1\u05d8\u05dc", "ru": "\u041d\u0435\u0442, \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c", "zh": "\u4e0d\uff0c\u53d6\u6d88", "ar": "\u0644\u0627\u060c \u0627\u0644\u063a", "lv": "N\u0113, atcelt", "id": "Tidak, batalkan", "sr": "Ne, odustani", "ro": "Nu, renun\u021b", "eu": "Ez, utzi", "af": "Nee, kanselleer", "el": "\u0391\u03c0\u03cc\u03c1\u03c1\u03b9\u03c8\u03b7", "xh": "Hayi, rhoxisa", "zu": "Cha, khansela", "st": "Tjhe, hlakola", "ca": "No, cancel·la" }, "service_provider": { "no": "Tjenesteleverand\u00f8r", "nn": "Tenesteleverand\u00f8r", "sv": "Tj\u00e4nsteleverant\u00f6r", "es": "Proveedor de servicio", "fr": "Fournisseur de service", "de": "Service-Provider", "nl": "Service Provider", "lb": "Service Provider", "sl": "Ponudnik storitev", "da": "Tjenesteudbyder", "hr": "Davatelj usluge", "hu": "Alkalmaz\u00e1sszolg\u00e1ltat\u00f3", "fi": "Palveluntarjoaja", "pt-br": "Provedor de Servi\u00e7os", "pt": "Fornecedor de Servi\u00e7o (SP)", "pl": "Dostawca serwisu", "cs": "Poskytovatel slu\u017eby", "tr": "Servis Sa\u011flay\u0131c\u0131", "it": "Fornitore di servizi", "lt": "Paslaugos teik\u0117jas", "ja": "\u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0", "zh-tw": "\u670d\u52d9\u63d0\u4f9b\u8005", "et": "Teenusepakkuja", "he": "\u05e1\u05e4\u05e7 \u05e9\u05d9\u05e8\u05d5\u05ea", "ru": "\u041f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u0443\u0441\u043b\u0443\u0433", "zh": "\u670d\u52a1\u63d0\u4f9b\u8005", "ar": "\u0645\u0642\u062f\u0645 \u062e\u062f\u0645\u0627\u062a", "lv": "Servisa pieg\u0101d\u0101t\u0101js", "id": "Service Provider", "sr": "Davalac Servisa", "ro": "Furnizor de servicii", "eu": "Zerbitzu hornitzailea", "af": "Diens Verskaffer", "el": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2 \u03c5\u03c0\u03b7\u03c1\u03b5\u03c3\u03af\u03b1\u03c2", "xh": "Umboneleli Wenkonzo", "zu": "Umhlinzeki Wesevisi", "st": "Mofani wa Tshebeletso", "ca": "Proveïdor de servei" } } simplesamlphp-1.19.1/dictionaries/login.definition.json0000644000000000000000000000364114042503475021776 0ustar rootroot{ "error_header": { "en": "Error" }, "user_pass_header": { "en": "Enter your username and password" }, "user_pass_text": { "en": "A service has requested you to authenticate yourself. Please enter your username and password in the form below." }, "login_button": { "en": "Login" }, "processing": { "en": "Processing..." }, "username": { "en": "Username" }, "organization": { "en": "Organization" }, "password": { "en": "Password" }, "help_header": { "en": "Help! I don't remember my password." }, "help_text": { "en": "Without your username and password you cannot authenticate yourself for access to the service. There may be someone that can help you. Consult the help desk at your organization!" }, "error_nopassword": { "en": "You sent something to the login page, but for some reason the password was not sent. Try again please." }, "error_wrongpassword": { "en": "Incorrect username or password." }, "select_home_org": { "en": "Choose your home organization" }, "next": { "en": "Next" }, "change_home_org_title": { "en": "Change your home organization" }, "change_home_org_text": { "en": "You have chosen %HOMEORG%<\/b> as your home organization. If this is wrong you may choose another one." }, "change_home_org_button": { "en": "Choose home organization" }, "help_desk_link": { "en": "Help desk homepage" }, "help_desk_email": { "en": "Send e-mail to help desk" }, "contact_info": { "en": "Contact information:" }, "remember_username": { "en": "Remember my username" }, "remember_me": { "en": "Remember me" }, "remember_organization": { "en": "Remember my organization" } } simplesamlphp-1.19.1/COPYING0000644000000000000000000000170314042503475014217 0ustar rootrootCopyright 2007-2021 UNINETT AS, https://www.uninett.no SimpleSAMLphp is licensed under the CC-GNU LGPL version 2.1. http://creativecommons.org/licenses/LGPL/2.1/ Note that some of the embedded libraries may be using other licenses. For example xmlseclibs uses BSD license. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA simplesamlphp-1.19.1/config/0000755000000000000000000000000014042503574014430 5ustar rootrootsimplesamlphp-1.19.1/config/config.php0000644000000000000000000012361614042503574016417 0ustar rootroot 'simplesaml/', /* * The 'application' configuration array groups a set configuration options * relative to an application protected by SimpleSAMLphp. */ //'application' => [ /* * The 'baseURL' configuration option allows you to specify a protocol, * host and optionally a port that serves as the canonical base for all * your application's URLs. This is useful when the environment * observed in the server differs from the one observed by end users, * for example, when using a load balancer to offload TLS. * * Note that this configuration option does not allow setting a path as * part of the URL. If your setup involves URL rewriting or any other * tricks that would result in SimpleSAMLphp observing a URL for your * application's scripts different than the canonical one, you will * need to compute the right URLs yourself and pass them dynamically * to SimpleSAMLphp's API. */ //'baseURL' => 'https://example.com', //], /* * The following settings are *filesystem paths* which define where * SimpleSAMLphp can find or write the following things: * - 'certdir': The base directory for certificate and key material. * - 'loggingdir': Where to write logs. * - 'datadir': Storage of general data. * - 'tempdir': Saving temporary files. SimpleSAMLphp will attempt to create * this directory if it doesn't exist. * When specified as a relative path, this is relative to the SimpleSAMLphp * root directory. */ 'certdir' => 'cert/', 'loggingdir' => 'log/', 'datadir' => 'data/', 'tempdir' => '/tmp/simplesaml', /* * Some information about the technical persons running this installation. * The email address will be used as the recipient address for error reports, and * also as the technical contact in generated metadata. */ 'technicalcontact_name' => 'Administrator', 'technicalcontact_email' => 'na@example.org', /* * (Optional) The method by which email is delivered. Defaults to mail which utilizes the * PHP mail() function. * * Valid options are: mail, sendmail and smtp. */ //'mail.transport.method' => 'smtp', /* * Set the transport options for the transport method specified. The valid settings are relative to the * selected transport method. */ // // smtp mail transport options // 'mail.transport.options' => [ // 'host' => 'mail.example.org', // required // 'port' => 25, // optional // 'username' => 'user@example.org', // optional: if set, enables smtp authentication // 'password' => 'password', // optional: if set, enables smtp authentication // 'security' => 'tls', // optional: defaults to no smtp security // ], // // sendmail mail transport options // 'mail.transport.options' => [ // 'path' => '/usr/sbin/sendmail' // optional: defaults to php.ini path // ], /* * The envelope from address for outgoing emails. * This should be in a domain that has your application's IP addresses in its SPF record * to prevent it from being rejected by mail filters. */ //'sendmail_from' => 'no-reply@example.org', /* * The timezone of the server. This option should be set to the timezone you want * SimpleSAMLphp to report the time in. The default is to guess the timezone based * on your system timezone. * * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php */ 'timezone' => null, /********************************** | SECURITY CONFIGURATION OPTIONS | **********************************/ /* * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash * of a value. It must be changed from its default value to a secret value. The value of * 'secretsalt' can be any valid string of any length. * * A possible way to generate a random salt is by running the following command from a unix shell: * LC_CTYPE=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo */ 'secretsalt' => 'defaultsecretsalt', /* * This password must be kept secret, and modified from the default value 123. * This password will give access to the installation page of SimpleSAMLphp with * metadata listing and diagnostics pages. * You can also put a hash here; run "bin/pwgen.php" to generate one. */ 'auth.adminpassword' => '123', /* * Set this options to true if you want to require administrator password to access the web interface * or the metadata pages, respectively. */ 'admin.protectindexpage' => false, 'admin.protectmetadata' => false, /* * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when * visiting the configuration tab in the web interface. */ 'admin.checkforupdates' => true, /* * Array of domains that are allowed when generating links or redirects * to URLs. SimpleSAMLphp will use this option to determine whether to * to consider a given URL valid or not, but you should always validate * URLs obtained from the input on your own (i.e. ReturnTo or RelayState * parameters obtained from the $_REQUEST array). * * SimpleSAMLphp will automatically add your own domain (either by checking * it dynamically, or by using the domain defined in the 'baseurlpath' * directive, the latter having precedence) to the list of trusted domains, * in case this option is NOT set to NULL. In that case, you are explicitly * telling SimpleSAMLphp to verify URLs. * * Set to an empty array to disallow ALL redirects or links pointing to * an external URL other than your own domain. This is the default behaviour. * * Set to NULL to disable checking of URLs. DO NOT DO THIS UNLESS YOU KNOW * WHAT YOU ARE DOING! * * Example: * 'trusted.url.domains' => ['sp.example.com', 'app.example.com'], */ 'trusted.url.domains' => [], /* * Enable regular expression matching of trusted.url.domains. * * Set to true to treat the values in trusted.url.domains as regular * expressions. Set to false to do exact string matching. * * If enabled, the start and end delimiters ('^' and '$') will be added to * all regular expressions in trusted.url.domains. */ 'trusted.url.regex' => false, /* * Enable secure POST from HTTPS to HTTP. * * If you have some SP's on HTTP and IdP is normally on HTTPS, this option * enables secure POSTing to HTTP endpoint without warning from browser. * * For this to work, module.php/core/postredirect.php must be accessible * also via HTTP on IdP, e.g. if your IdP is on * https://idp.example.org/ssp/, then * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. */ 'enable.http_post' => false, /* * Set the allowed clock skew between encrypting/decrypting assertions * * If you have an server that is constantly out of sync, this option * allows you to adjust the allowed clock-skew. * * Allowed range: 180 - 300 * Defaults to 180. */ 'assertion.allowed_clock_skew' => 180, /************************ | ERRORS AND DEBUGGING | ************************/ /* * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain * situations where further action may be taken * * It can be left unset, in which case, debugging is switched off for all actions. * If set, it MUST be an array containing the actions that you want to enable, or * alternatively a hashed array where the keys are the actions and their * corresponding values are booleans enabling or disabling each particular action. * * SimpleSAMLphp provides some pre-defined actions, though modules could add new * actions here. Refer to the documentation of every module to learn if they * allow you to set any more debugging actions. * * The pre-defined actions are: * * - 'saml': this action controls the logging of SAML messages exchanged with other * entities. When enabled ('saml' is present in this option, or set to true), all * SAML messages will be logged, including plaintext versions of encrypted * messages. * * - 'backtraces': this action controls the logging of error backtraces so you * can debug any possible errors happening in SimpleSAMLphp. * * - 'validatexml': this action allows you to validate SAML documents against all * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with * the XML to SimpleSAMLphp metadata converter or the metaedit module will * validate the SAML documents if this option is enabled. * * If you want to disable debugging completely, unset this option or set it to an * empty array. */ 'debug' => [ 'saml' => false, 'backtraces' => true, 'validatexml' => false, ], /* * When 'showerrors' is enabled, all error messages and stack traces will be output * to the browser. * * When 'errorreporting' is enabled, a form will be presented for the user to report * the error to 'technicalcontact_email'. */ 'showerrors' => true, 'errorreporting' => true, /* * Custom error show function called from SimpleSAML\Error\Error::show. * See docs/simplesamlphp-errorhandling.txt for function code example. * * Example: * 'errors.show_function' => ['SimpleSAML\Module\example\Error', 'show'], */ /************************** | LOGGING AND STATISTICS | **************************/ /* * Define the minimum log level to log. Available levels: * - SimpleSAML\Logger::ERR No statistics, only errors * - SimpleSAML\Logger::WARNING No statistics, only warnings/errors * - SimpleSAML\Logger::NOTICE Statistics and errors * - SimpleSAML\Logger::INFO Verbose logs * - SimpleSAML\Logger::DEBUG Full debug logs - not recommended for production * * Choose logging handler. * * Options: [syslog,file,errorlog,stderr] * */ 'logging.level' => SimpleSAML\Logger::NOTICE, 'logging.handler' => 'syslog', /* * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options * are: * * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation * of the strftime() function for more information on the format. If the brackets are omitted, the standard * format is applied. This can be useful if you just want to control the placement of the date, but don't care * about the format. * * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' * option below. * * - %level: the log level (name or number depending on the handler used). * * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind * the trailing space). * * - %trackid: the track ID, an identifier that allows you to track a single session. * * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. * * - %msg: the message to be logged. * */ //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', /* * Choose which facility should be used when logging with syslog. * * These can be used for filtering the syslog output from SimpleSAMLphp into its * own file by configuring the syslog daemon. * * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available * facilities. Note that only LOG_USER is valid on windows. * * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. */ 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, /* * The process name that should be used when logging to syslog. * The value is also written out by the other logging handlers. */ 'logging.processname' => 'simplesamlphp', /* * Logging: file - Logfilename in the loggingdir from above. */ 'logging.logfile' => 'simplesamlphp.log', /* * This is an array of outputs. Each output has at least a 'class' option, which * selects the output. */ 'statistics.out' => [// Log statistics to the normal log. /* [ 'class' => 'core:Log', 'level' => 'notice', ], */ // Log statistics to files in a directory. One file per day. /* [ 'class' => 'core:File', 'directory' => '/var/log/stats', ], */ ], /*********************** | PROXY CONFIGURATION | ***********************/ /* * Proxy to use for retrieving URLs. * * Example: * 'proxy' => 'tcp://proxy.example.com:5100' */ 'proxy' => null, /* * Username/password authentication to proxy (Proxy-Authorization: Basic) * Example: * 'proxy.auth' = 'myuser:password' */ //'proxy.auth' => 'myuser:password', /************************** | DATABASE CONFIGURATION | **************************/ /* * This database configuration is optional. If you are not using * core functionality or modules that require a database, you can * skip this configuration. */ /* * Database connection string. * Ensure that you have the required PDO database driver installed * for your connection string. */ 'database.dsn' => 'mysql:host=localhost;dbname=saml', /* * SQL database credentials */ 'database.username' => 'simplesamlphp', 'database.password' => 'secret', 'database.options' => [], /* * (Optional) Table prefix */ 'database.prefix' => '', /* * (Optional) Driver options */ 'database.driver_options' => [], /* * True or false if you would like a persistent database connection */ 'database.persistent' => false, /* * Database slave configuration is optional as well. If you are only * running a single database server, leave this blank. If you have * a master/slave configuration, you can define as many slave servers * as you want here. Slaves will be picked at random to be queried from. * * Configuration options in the slave array are exactly the same as the * options for the master (shown above) with the exception of the table * prefix and driver options. */ 'database.slaves' => [ /* [ 'dsn' => 'mysql:host=myslave;dbname=saml', 'username' => 'simplesamlphp', 'password' => 'secret', 'persistent' => false, ], */ ], /************* | PROTOCOLS | *************/ /* * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only * one of the functionalities below, but in some cases you could run multiple functionalities. * In example when you are setting up a federation bridge. * * Note that shib13-idp has been deprecated and will be removed in SimpleSAMLphp 2.0. */ 'enable.saml20-idp' => false, 'enable.shib13-idp' => false, 'enable.adfs-idp' => false, /* * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication * responses. * * The default is to sign the assertion element, but that can be overridden by setting this * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the * same name to the metadata of the SP. */ 'shib13.signresponse' => true, /*********** | MODULES | ***********/ /* * Configuration to override module enabling/disabling. * * Example: * * 'module.enable' => [ * 'exampleauth' => true, // Setting to TRUE enables. * 'consent' => false, // Setting to FALSE disables. * 'core' => null, // Unset or NULL uses default. * ], * */ 'module.enable' => [ 'exampleauth' => false, 'core' => true, 'saml' => true ], /************************* | SESSION CONFIGURATION | *************************/ /* * This value is the duration of the session in seconds. Make sure that the time duration of * cookies both at the SP and the IdP exceeds this duration. */ 'session.duration' => 8 * (60 * 60), // 8 hours. /* * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for * login and logout requests, this option will control the maximum time these operations can take. * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. */ 'session.datastore.timeout' => (4 * 60 * 60), // 4 hours /* * Sets the duration, in seconds, auth state should be stored. */ 'session.state.timeout' => (60 * 60), // 1 hour /* * Option to override the default settings for the session cookie name */ 'session.cookie.name' => 'SimpleSAMLSessionID', /* * Expiration time for the session cookie, in seconds. * * Defaults to 0, which means that the cookie expires when the browser is closed. * * Example: * 'session.cookie.lifetime' => 30*60, */ 'session.cookie.lifetime' => 0, /* * Limit the path of the cookies. * * Can be used to limit the path of the cookies to a specific subdirectory. * * Example: * 'session.cookie.path' => '/simplesaml/', */ 'session.cookie.path' => '/', /* * Cookie domain. * * Can be used to make the session cookie available to several domains. * * Example: * 'session.cookie.domain' => '.example.org', */ 'session.cookie.domain' => null, /* * Set the secure flag in the cookie. * * Set this to TRUE if the user only accesses your service * through https. If the user can access the service through * both http and https, this must be set to FALSE. */ 'session.cookie.secure' => true, /* * Set the SameSite attribute in the cookie. * * You can set this to the strings 'None', 'Lax', or 'Strict' to support * the RFC6265bis SameSite cookie attribute. If set to null, no SameSite * attribute will be sent. * * Example: * 'session.cookie.samesite' => 'None', */ 'session.cookie.samesite' => \SimpleSAML\Utils\HTTP::canSetSameSiteNone() ? 'None' : null, /* * Options to override the default settings for php sessions. */ 'session.phpsession.cookiename' => 'SimpleSAML', 'session.phpsession.savepath' => null, 'session.phpsession.httponly' => true, /* * Option to override the default settings for the auth token cookie */ 'session.authtoken.cookiename' => 'SimpleSAMLAuthToken', /* * Options for remember me feature for IdP sessions. Remember me feature * has to be also implemented in authentication source used. * * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie * expires on browser session if remember me is not checked. * * Session duration ('session.duration' option) should be set according to * 'session.rememberme.lifetime' option. * * It's advised to use remember me feature with session checking function * defined with 'session.check_function' option. */ 'session.rememberme.enable' => false, 'session.rememberme.checked' => false, 'session.rememberme.lifetime' => (14 * 86400), /* * Custom function for session checking called on session init and loading. * See docs/simplesamlphp-advancedfeatures.txt for function code example. * * Example: * 'session.check_function' => ['\SimpleSAML\Module\example\Util', 'checkSession'], */ /************************** | MEMCACHE CONFIGURATION | **************************/ /* * Configuration for the 'memcache' session store. This allows you to store * multiple redundant copies of sessions on different memcache servers. * * 'memcache_store.servers' is an array of server groups. Every data * item will be mirrored in every server group. * * Each server group is an array of servers. The data items will be * load-balanced between all servers in each server group. * * Each server is an array of parameters for the server. The following * options are available: * - 'hostname': This is the hostname or ip address where the * memcache server runs. This is the only required option. * - 'port': This is the port number of the memcache server. If this * option isn't set, then we will use the 'memcache.default_port' * ini setting. This is 11211 by default. * * When using the "memcache" extension, the following options are also * supported: * - 'weight': This sets the weight of this server in this server * group. http://php.net/manual/en/function.Memcache-addServer.php * contains more information about the weight option. * - 'timeout': The timeout for this server. By default, the timeout * is 3 seconds. * * Example of redundant configuration with load balancing: * This configuration makes it possible to lose both servers in the * a-group or both servers in the b-group without losing any sessions. * Note that sessions will be lost if one server is lost from both the * a-group and the b-group. * * 'memcache_store.servers' => [ * [ * ['hostname' => 'mc_a1'], * ['hostname' => 'mc_a2'], * ], * [ * ['hostname' => 'mc_b1'], * ['hostname' => 'mc_b2'], * ], * ], * * Example of simple configuration with only one memcache server, * running on the same computer as the web server: * Note that all sessions will be lost if the memcache server crashes. * * 'memcache_store.servers' => [ * [ * ['hostname' => 'localhost'], * ], * ], * * Additionally, when using the "memcached" extension, unique keys must * be provided for each group of servers if persistent connections are * desired. Each server group can also have an "options" indexed array * with the options desired for the given group: * * 'memcache_store.servers' => [ * 'memcache_group_1' => [ * 'options' => [ * \Memcached::OPT_BINARY_PROTOCOL => true, * \Memcached::OPT_NO_BLOCK => true, * \Memcached::OPT_TCP_NODELAY => true, * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, * ], * ['hostname' => '127.0.0.1', 'port' => 11211], * ['hostname' => '127.0.0.2', 'port' => 11211], * ], * * 'memcache_group_2' => [ * 'options' => [ * \Memcached::OPT_BINARY_PROTOCOL => true, * \Memcached::OPT_NO_BLOCK => true, * \Memcached::OPT_TCP_NODELAY => true, * \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, * ], * ['hostname' => '127.0.0.3', 'port' => 11211], * ['hostname' => '127.0.0.4', 'port' => 11211], * ], * ], * */ 'memcache_store.servers' => [ [ ['hostname' => 'localhost'], ], ], /* * This value allows you to set a prefix for memcache-keys. The default * for this value is 'simpleSAMLphp', which is fine in most cases. * * When running multiple instances of SSP on the same host, and more * than one instance is using memcache, you probably want to assign * a unique value per instance to this setting to avoid data collision. */ 'memcache_store.prefix' => '', /* * This value is the duration data should be stored in memcache. Data * will be dropped from the memcache servers when this time expires. * The time will be reset every time the data is written to the * memcache servers. * * This value should always be larger than the 'session.duration' * option. Not doing this may result in the session being deleted from * the memcache servers while it is still in use. * * Set this value to 0 if you don't want data to expire. * * Note: The oldest data will always be deleted if the memcache server * runs out of storage space. */ 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. /************************************* | LANGUAGE AND INTERNATIONALIZATION | *************************************/ /* * Language-related options. */ 'language' => [ /* * An array in the form 'language' => . * * Each key in the array is the ISO 639 two-letter code for a language, * and its value is an array with a list of alternative languages that * can be used if the given language is not available at some point. * Each alternative language is also specified by its ISO 639 code. * * For example, for the "no" language code (Norwegian), we would have: * * 'priorities' => [ * 'no' => ['nb', 'nn', 'en', 'se'], * ... * ], * * establishing that if a translation for the "no" language code is * not available, we look for translations in "nb", * and so on, in that order. */ 'priorities' => [ 'no' => ['nb', 'nn', 'en', 'se'], 'nb' => ['no', 'nn', 'en', 'se'], 'nn' => ['no', 'nb', 'en', 'se'], 'se' => ['nb', 'no', 'nn', 'en'], 'nr' => ['zu', 'en'], 'nd' => ['zu', 'en'], 'tw' => ['st', 'en'], 'nso' => ['st', 'en'], ], ], /* * Languages available, RTL languages, and what language is the default. */ 'language.available' => [ 'en', 'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'ca', 'fr', 'it', 'nl', 'lb', 'cs', 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', 'et', 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af', 'zu', 'xh', 'st', ], 'language.rtl' => ['ar', 'dv', 'fa', 'ur', 'he'], 'language.default' => 'en', /* * Options to override the default settings for the language parameter */ 'language.parameter.name' => 'language', 'language.parameter.setcookie' => true, /* * Options to override the default settings for the language cookie */ 'language.cookie.name' => 'language', 'language.cookie.domain' => null, 'language.cookie.path' => '/', 'language.cookie.secure' => true, 'language.cookie.httponly' => false, 'language.cookie.lifetime' => (60 * 60 * 24 * 900), 'language.cookie.samesite' => \SimpleSAML\Utils\HTTP::canSetSameSiteNone() ? 'None' : null, /** * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). * Function should return language code of one of the available languages or NULL. * See SimpleSAML\Locale\Language::getLanguage() source code for more info. * * This option can be used to implement a custom function for determining * the default language for the user. * * Example: * 'language.get_language_function' => ['\SimpleSAML\Module\example\Template', 'getLanguage'], */ /* * Extra dictionary for attribute names. * This can be used to define local attributes. * * The format of the parameter is a string with :. * * Specifying this option will cause us to look for modules//dictionaries/.definition.json * The dictionary should look something like: * * { * "firstattribute": { * "en": "English name", * "no": "Norwegian name" * }, * "secondattribute": { * "en": "English name", * "no": "Norwegian name" * } * } * * Note that all attribute names in the dictionary must in lowercase. * * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', */ 'attributes.extradictionary' => null, /************** | APPEARANCE | **************/ /* * Which theme directory should be used? */ 'theme.use' => 'default', /* * Set this option to the text you would like to appear at the header of each page. Set to false if you don't want * any text to appear in the header. */ //'theme.header' => 'SimpleSAMLphp' /** * A template controller, if any. * * Used to intercept certain parts of the template handling, while keeping away unwanted/unexpected hooks. Set * the 'theme.controller' configuration option to a class that implements the * \SimpleSAML\XHTML\TemplateControllerInterface interface to use it. */ //'theme.controller' => '', /* * Templating options * * By default, twig templates are not cached. To turn on template caching: * Set 'template.cache' to an absolute path pointing to a directory that * SimpleSAMLphp has read and write permissions to. */ //'template.cache' => '', /* * Set the 'template.auto_reload' to true if you would like SimpleSAMLphp to * recompile the templates (when using the template cache) if the templates * change. If you don't want to check the source templates for every request, * set it to false. */ 'template.auto_reload' => false, /* * Set this option to true to indicate that your installation of SimpleSAMLphp * is running in a production environment. This will affect the way resources * are used, offering an optimized version when running in production, and an * easy-to-debug one when not. Set it to false when you are testing or * developing the software, in which case a banner will be displayed to remind * users that they're dealing with a non-production instance. * * Defaults to true. */ 'production' => true, /* * SimpleSAMLphp modules can host static resources which are served through PHP. * The serving of the resources can be configured through these settings. */ 'assets' => [ /* * These settings adjust the caching headers that are sent * when serving static resources. */ 'caching' => [ /* * Amount of seconds before the resource should be fetched again */ 'max_age' => 86400, /* * Calculate a checksum of every file and send it to the browser * This allows the browser to avoid downloading assets again in situations * where the Last-Modified header cannot be trusted, * for example in cluster setups * * Defaults false */ 'etag' => false, ], ], /********************* | DISCOVERY SERVICE | *********************/ /* * Whether the discovery service should allow the user to save his choice of IdP. */ 'idpdisco.enableremember' => true, 'idpdisco.rememberchecked' => true, /* * The disco service only accepts entities it knows. */ 'idpdisco.validate' => true, 'idpdisco.extDiscoveryStorage' => null, /* * IdP Discovery service look configuration. * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box * gives the best use experience. * * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. * This makes it easier for the user to choose the IdP * * Options: [links,dropdown] */ 'idpdisco.layout' => 'dropdown', /************************************* | AUTHENTICATION PROCESSING FILTERS | *************************************/ /* * Authentication processing filters that will be executed for all IdPs * Both Shibboleth and SAML 2.0 */ 'authproc.idp' => [ /* Enable the authproc filter below to add URN prefixes to all attributes 10 => array[ 'class' => 'core:AttributeMap', 'addurnprefix' ], */ /* Enable the authproc filter below to automatically generated eduPersonTargetedID. 20 => 'core:TargetedID', */ // Adopts language from attribute to use in UI 30 => 'core:LanguageAdaptor', 45 => [ 'class' => 'core:StatisticsWithAttribute', 'attributename' => 'realm', 'type' => 'saml20-idp-SSO', ], /* When called without parameters, it will fallback to filter attributes 'the old way' * by checking the 'attributes' parameter in metadata on IdP hosted and SP remote. */ 50 => 'core:AttributeLimit', /* * Search attribute "distinguishedName" for pattern and replaces if found */ /* 60 => [ 'class' => 'core:AttributeAlter', 'pattern' => '/OU=studerende/', 'replacement' => 'Student', 'subject' => 'distinguishedName', '%replace', ], */ /* * Consent module is enabled (with no permanent storage, using cookies). */ /* 90 => [ 'class' => 'consent:Consent', 'store' => 'consent:Cookie', 'focus' => 'yes', 'checked' => true ], */ // If language is set in Consent module it will be added as an attribute. 99 => 'core:LanguageAdaptor', ], /* * Authentication processing filters that will be executed for all SPs * Both Shibboleth and SAML 2.0 */ 'authproc.sp' => [ /* 10 => [ 'class' => 'core:AttributeMap', 'removeurnprefix' ], */ /* * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. 60 => [ 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' ], */ /* * All users will be members of 'users' and 'members' */ /* 61 => [ 'class' => 'core:AttributeAdd', 'groups' => ['users', 'members'] ], */ // Adopts language from attribute to use in UI 90 => 'core:LanguageAdaptor', ], /************************** | METADATA CONFIGURATION | **************************/ /* * This option allows you to specify a directory for your metadata outside of the standard metadata directory * included in the standard distribution of the software. */ 'metadatadir' => 'metadata', /* * This option configures the metadata sources. The metadata sources is given as an array with * different metadata sources. When searching for metadata, SimpleSAMLphp will search through * the array from start to end. * * Each element in the array is an associative array which configures the metadata source. * The type of the metadata source is given by the 'type' element. For each type we have * different configuration options. * * Flat file metadata handler: * - 'type': This is always 'flatfile'. * - 'directory': The directory we will load the metadata files from. The default value for * this option is the value of the 'metadatadir' configuration option, or * 'metadata/' if that option is unset. * * XML metadata handler: * This metadata handler parses an XML file with either an EntityDescriptor element or an * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote * web server. * The XML metadata handler defines the following options: * - 'type': This is always 'xml'. * - 'file': Path to the XML file with the metadata. * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. * * MDQ metadata handler: * This metadata handler looks up for the metadata of an entity at the given MDQ server. * The MDQ metadata handler defines the following options: * - 'type': This is always 'mdq'. * - 'server': Base URL of the MDQ server. Mandatory. * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this * option if you don't want to validate the signature on the metadata. Optional. * - 'cachedir': Directory where metadata can be cached. Optional. * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 * hours (86400 seconds). Optional. * * PDO metadata handler: * This metadata handler looks up metadata of an entity stored in a database. * * Note: If you are using the PDO metadata handler, you must configure the database * options in this configuration file. * * The PDO metadata handler defines the following options: * - 'type': This is always 'pdo'. * * Examples: * * This example defines two flatfile sources. One is the default metadata directory, the other * is a metadata directory with auto-generated metadata files. * * 'metadata.sources' => [ * ['type' => 'flatfile'], * ['type' => 'flatfile', 'directory' => 'metadata-generated'], * ], * * This example defines a flatfile source and an XML source. * 'metadata.sources' => [ * ['type' => 'flatfile'], * ['type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'], * ], * * This example defines an mdq source. * 'metadata.sources' => [ * [ * 'type' => 'mdq', * 'server' => 'http://mdq.server.com:8080', * 'cachedir' => '/var/simplesamlphp/mdq-cache', * 'cachelength' => 86400 * ] * ], * * This example defines an pdo source. * 'metadata.sources' => [ * ['type' => 'pdo'] * ], * * Default: * 'metadata.sources' => [ * ['type' => 'flatfile'] * ], */ 'metadata.sources' => [ ['type' => 'flatfile'], ], /* * Should signing of generated metadata be enabled by default. * * Metadata signing can also be enabled for a individual SP or IdP by setting the * same option in the metadata for the SP or IdP. */ 'metadata.sign.enable' => false, /* * The default key & certificate which should be used to sign generated metadata. These * are files stored in the cert dir. * These values can be overridden by the options with the same names in the SP or * IdP metadata. * * If these aren't specified here or in the metadata for the SP or IdP, then * the 'certificate' and 'privatekey' option in the metadata will be used. * if those aren't set, signing of metadata will fail. */ 'metadata.sign.privatekey' => null, 'metadata.sign.privatekey_pass' => null, 'metadata.sign.certificate' => null, /**************************** | DATA STORE CONFIGURATION | ****************************/ /* * Configure the data store for SimpleSAMLphp. * * - 'phpsession': Limited datastore, which uses the PHP session. * - 'memcache': Key-value datastore, based on memcache. * - 'sql': SQL datastore, using PDO. * - 'redis': Key-value datastore, based on redis. * * The default datastore is 'phpsession'. */ 'store.type' => 'phpsession', /* * The DSN the sql datastore should connect to. * * See http://www.php.net/manual/en/pdo.drivers.php for the various * syntaxes. */ 'store.sql.dsn' => 'sqlite:/path/to/sqlitedatabase.sq3', /* * The username and password to use when connecting to the database. */ 'store.sql.username' => null, 'store.sql.password' => null, /* * The prefix we should use on our tables. */ 'store.sql.prefix' => 'SimpleSAMLphp', /* * The hostname and port of the Redis datastore instance. */ 'store.redis.host' => 'localhost', 'store.redis.port' => 6379, /* * The prefix we should use on our Redis datastore. */ 'store.redis.prefix' => 'SimpleSAMLphp', ]; simplesamlphp-1.19.1/config/acl.php0000644000000000000000000000316414042503574015704 0ustar rootroot [ //['allow', 'equals', 'mail', 'admin1@example.org'], //['allow', 'has', 'groups', 'admin'], // The default action is to deny access. ], 'example-simple' => [ ['allow', 'equals', 'mail', 'admin1@example.org'], ['allow', 'equals', 'mail', 'admin2@example.org'], // The default action is to deny access. ], 'example-deny-some' => [ ['deny', 'equals', 'mail', 'eviluser@example.org'], ['allow'], // Allow everybody else. ], 'example-maildomain' => [ ['allow', 'equals-preg', 'mail', '/@example\.org$/'], // The default action is to deny access. ], 'example-allow-employees' => [ ['allow', 'has', 'eduPersonAffiliation', 'employee'], // The default action is to deny access. ], 'example-allow-employees-not-students' => [ ['deny', 'has', 'eduPersonAffiliation', 'student'], ['allow', 'has', 'eduPersonAffiliation', 'employee'], // The default action is to deny access. ], 'example-deny-student-except-one' => [ ['deny', 'and', ['has', 'eduPersonAffiliation', 'student'], ['not', 'equals', 'mail', 'user@example.org'], ], ['allow'], ], 'example-allow-or' => [ ['allow', 'or', ['equals', 'eduPersonAffiliation', 'student', 'member'], ['equals', 'mail', 'someuser@example2.org'], ], ], 'example-allow-all' => [ ['allow'], ], ]; simplesamlphp-1.19.1/config/authsources.php0000644000000000000000000003030114042503574017503 0ustar rootroot [ // The default is to use core:AdminPassword, but it can be replaced with // any authentication source. 'core:AdminPassword', ], // An authentication source which can authenticate against both SAML 2.0 // and Shibboleth 1.3 IdPs. 'default-sp' => [ 'saml:SP', // The entity ID of this SP. // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL. 'entityID' => null, // The entity ID of the IdP this SP should contact. // Can be NULL/unset, in which case the user will be shown a list of available IdPs. 'idp' => null, // The URL to the discovery service. // Can be NULL/unset, in which case a builtin discovery service will be used. 'discoURL' => null, /* * The attributes parameter must contain an array of desired attributes by the SP. * The attributes can be expressed as an array of names or as an associative array * in the form of 'friendlyName' => 'name'. This feature requires 'name' to be set. * The metadata will then be created as follows: * */ /* 'name' => [ 'en' => 'A service', 'no' => 'En tjeneste', ], 'attributes' => [ 'attrname' => 'urn:oid:x.x.x.x', ], 'attributes.required' => [ 'urn:oid:x.x.x.x', ], */ ], /* 'example-sql' => [ 'sqlauth:SQL', 'dsn' => 'pgsql:host=sql.example.org;port=5432;dbname=simplesaml', 'username' => 'simplesaml', 'password' => 'secretpassword', 'query' => 'SELECT uid, givenName, email, eduPersonPrincipalName FROM users WHERE uid = :username ' . 'AND password = SHA2(CONCAT((SELECT salt FROM users WHERE uid = :username), :password), 256);', ], */ /* 'example-static' => [ 'exampleauth:StaticSource', 'uid' => ['testuser'], 'eduPersonAffiliation' => ['member', 'employee'], 'cn' => ['Test User'], ], */ /* 'example-userpass' => [ 'exampleauth:UserPass', // Give the user an option to save their username for future login attempts // And when enabled, what should the default be, to save the username or not //'remember.username.enabled' => false, //'remember.username.checked' => false, 'student:studentpass' => [ 'uid' => ['test'], 'eduPersonAffiliation' => ['member', 'student'], ], 'employee:employeepass' => [ 'uid' => ['employee'], 'eduPersonAffiliation' => ['member', 'employee'], ], ], */ /* 'crypto-hash' => [ 'authcrypt:Hash', // hashed version of 'verysecret', made with bin/pwgen.php 'professor:{SSHA256}P6FDTEEIY2EnER9a6P2GwHhI5JDrwBgjQ913oVQjBngmCtrNBUMowA==' => [ 'uid' => ['prof_a'], 'eduPersonAffiliation' => ['member', 'employee', 'board'], ], ], */ /* 'htpasswd' => [ 'authcrypt:Htpasswd', 'htpasswd_file' => '/var/www/foo.edu/legacy_app/.htpasswd', 'static_attributes' => [ 'eduPersonAffiliation' => ['member', 'employee'], 'Organization' => ['University of Foo'], ], ], */ /* // This authentication source serves as an example of integration with an // external authentication engine. Take a look at the comment in the beginning // of modules/exampleauth/lib/Auth/Source/External.php for a description of // how to adjust it to your own site. 'example-external' => [ 'exampleauth:External', ], */ /* 'yubikey' => [ 'authYubiKey:YubiKey', 'id' => '000', // 'key' => '012345678', ], */ /* 'facebook' => [ 'authfacebook:Facebook', // Register your Facebook application on http://www.facebook.com/developers // App ID or API key (requests with App ID should be faster; https://github.com/facebook/php-sdk/issues/214) 'api_key' => 'xxxxxxxxxxxxxxxx', // App Secret 'secret' => 'xxxxxxxxxxxxxxxx', // which additional data permissions to request from user // see http://developers.facebook.com/docs/authentication/permissions/ for the full list // 'req_perms' => 'email,user_birthday', // Which additional user profile fields to request. // When empty, only the app-specific user id and name will be returned // See https://developers.facebook.com/docs/graph-api/reference/v2.6/user for the full list // 'user_fields' => 'email,birthday,third_party_id,name,first_name,last_name', ], */ /* // Twitter OAuth Authentication API. // Register your application to get an API key here: // http://twitter.com/oauth_clients 'twitter' => [ 'authtwitter:Twitter', 'key' => 'xxxxxxxxxxxxxxxx', 'secret' => 'xxxxxxxxxxxxxxxx', // Forces the user to enter their credentials to ensure the correct users account is authorized. // Details: https://dev.twitter.com/docs/api/1/get/oauth/authenticate 'force_login' => false, ], */ /* // Microsoft Account (Windows Live ID) Authentication API. // Register your application to get an API key here: // https://apps.dev.microsoft.com/ 'windowslive' => [ 'authwindowslive:LiveID', 'key' => 'xxxxxxxxxxxxxxxx', 'secret' => 'xxxxxxxxxxxxxxxx', ], */ /* // Example of a LDAP authentication source. 'example-ldap' => [ 'ldap:LDAP', // Give the user an option to save their username for future login attempts // And when enabled, what should the default be, to save the username or not //'remember.username.enabled' => false, //'remember.username.checked' => false, // The hostname of the LDAP server. 'hostname' => 'ldap.example.org', // Whether SSL/TLS should be used when contacting the LDAP server. 'enable_tls' => true, // Whether debug output from the LDAP library should be enabled. // Default is FALSE. 'debug' => false, // The timeout for accessing the LDAP server, in seconds. // The default is 0, which means no timeout. 'timeout' => 0, // The port used when accessing the LDAP server. // The default is 389. 'port' => 389, // Set whether to follow referrals. AD Controllers may require FALSE to function. 'referrals' => true, // Which attributes should be retrieved from the LDAP server. // This can be an array of attribute names, or NULL, in which case // all attributes are fetched. 'attributes' => null, // The pattern which should be used to create the users DN given the username. // %username% in this pattern will be replaced with the users username. // // This option is not used if the search.enable option is set to TRUE. 'dnpattern' => 'uid=%username%,ou=people,dc=example,dc=org', // As an alternative to specifying a pattern for the users DN, it is possible to // search for the username in a set of attributes. This is enabled by this option. 'search.enable' => false, // The DN which will be used as a base for the search. // This can be a single string, in which case only that DN is searched, or an // array of strings, in which case they will be searched in the order given. 'search.base' => 'ou=people,dc=example,dc=org', // The attribute(s) the username should match against. // // This is an array with one or more attribute names. Any of the attributes in // the array may match the value the username. 'search.attributes' => ['uid', 'mail'], // Additional LDAP filters appended to the search attributes //'search.filter' => '(objectclass=inetorgperson)', // The username & password the SimpleSAMLphp should bind to before searching. If // this is left as NULL, no bind will be performed before searching. 'search.username' => null, 'search.password' => null, // If the directory uses privilege separation, // the authenticated user may not be able to retrieve // all required attribures, a privileged entity is required // to get them. This is enabled with this option. 'priv.read' => false, // The DN & password the SimpleSAMLphp should bind to before // retrieving attributes. These options are required if // 'priv.read' is set to TRUE. 'priv.username' => null, 'priv.password' => null, ], */ /* // Example of an LDAPMulti authentication source. 'example-ldapmulti' => [ 'ldap:LDAPMulti', // Give the user an option to save their username for future login attempts // And when enabled, what should the default be, to save the username or not //'remember.username.enabled' => false, //'remember.username.checked' => false, // Give the user an option to save their organization choice for future login // attempts. And when enabled, what should the default be, checked or not. //'remember.organization.enabled' => false, //'remember.organization.checked' => false, // The way the organization as part of the username should be handled. // Three possible values: // - 'none': No handling of the organization. Allows '@' to be part // of the username. // - 'allow': Will allow users to type 'username@organization'. // - 'force': Force users to type 'username@organization'. The dropdown // list will be hidden. // // The default is 'none'. 'username_organization_method' => 'none', // Whether the organization should be included as part of the username // when authenticating. If this is set to TRUE, the username will be on // the form @. If this is FALSE, the // username will be used as the user enters it. // // The default is FALSE. 'include_organization_in_username' => false, // A list of available LDAP servers. // // The index is an identifier for the organization/group. When // 'username_organization_method' is set to something other than 'none', // the organization-part of the username is matched against the index. // // The value of each element is an array in the same format as an LDAP // authentication source. 'employees' => [ // A short name/description for this group. Will be shown in a dropdown list // when the user logs on. // // This option can be a string or an array with language => text mappings. 'description' => 'Employees', // The rest of the options are the same as those available for // the LDAP authentication source. 'hostname' => 'ldap.employees.example.org', 'dnpattern' => 'uid=%username%,ou=employees,dc=example,dc=org', ], 'students' => [ 'description' => 'Students', 'hostname' => 'ldap.students.example.org', 'dnpattern' => 'uid=%username%,ou=students,dc=example,dc=org', ], ], */ ]; simplesamlphp-1.19.1/docs/0000755000000000000000000000000014042503475014113 5ustar rootrootsimplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.6.md0000644000000000000000000000273714042503475022401 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.6 =================================== * This release requires PHP version >= 5.2.0, as that was the first version to include `json_decode()`. It is possible that it may work with version of PHP >= 5.1.2 if the [JSON PECL extesion](http://pecl.php.net/package/json) is enabled, but this is untested. * The secure-flag is no longer automatically set on the session cookie. This was changed to avoid hard to diagnose session problems. There is a new option `session.cookie.secure` in `config.php`, which can be used to enable secure cookies. * Dictionaries have moved to JSON format. The PHP format is still supported, but all dictionaries included with SimpleSAMLphp are in JSON format. * The iframe-specific logout endpoints on the IdP have been merged into the normal logout endpoints. This means that the metadata no longer needs to be changed when switching between logout handlers. The old iframe logout endpoints are now deprecated, and the generated metadata will only include the normal logout endpoint. * As a result of the changed metadata classes, all metadata elements now have a `md:`-prefix. This does not change the content of the metadata, just its expression. * The deprecated functions `init(...)` and `setAuthenticated(...)` in the `SimpleSAML_Session` class have been removed. Code which relies on those functions should move to using `SimpleSAML_Session::getInstance()` and `$session->doLogin(...)`. simplesamlphp-1.19.1/docs/simplesamlphp-sp.md0000644000000000000000000002234714042503475017743 0ustar rootrootSimpleSAMLphp Service Provider QuickStart ========================================= This guide will describe how to configure SimpleSAMLphp as a service provider (SP). You should previously have installed SimpleSAMLphp as described in [the SimpleSAMLphp installation instructions](simplesamlphp-install). Configuring the SP ------------------ The SP is configured by an entry in `config/authsources.php`. This is a minimal `authsources.php` for a SP: [ 'saml:SP', ], ]; For more information about additional options available for the SP, see the [`saml:SP` reference](./saml:sp). If you want multiple Service Providers in the same site and installation, you can add more entries in the `authsources.php` configuration. If so remember to set the EntityID explicitly. Here is an example: 'sp1' => [ 'saml:SP', 'entityID' => 'https://sp1.example.org/', ], 'sp2' => [ 'saml:SP', 'entityID' => 'https://sp2.example.org/', ], ### Enabling a certificate for your Service Provider Some Identity Providers / Federations may require that your Service Providers holds a certificate. If you enable a certificate for your Service Provider, it may be able to sign requests and response sent to the Identity Provider, as well as receiving encrypted responses. Create a self-signed certificate in the `cert/` directory. cd cert openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.pem Then edit your `authsources.php` entry, and add references to your certificate: 'default-sp' => [ 'saml:SP', 'privatekey' => 'saml.pem', 'certificate' => 'saml.crt', ], Adding IdPs to the SP --------------------- The service provider you are configuring needs to know about the identity providers you are going to connect to it. This is configured by metadata stored in `metadata/saml20-idp-remote.php` and `metadata/shib13-idp-remote.php`. This is a minimal example of a `metadata/saml20-idp-remote.php` metadata file: 'https://example.com/simplesaml/saml2/idp/SSOService.php', 'SingleLogoutService' => 'https://example.com/simplesaml/saml2/idp/SingleLogoutService.php', 'certificate' => 'example.pem', ]; `example.pem` under your `cert/` directory contains the certificate the identity provider uses for signing assertions. For more information about available options in the idp-remote metadata files, see the [IdP remote reference](simplesamlphp-reference-idp-remote). If you have the metadata of the remote IdP as an XML file, you can use the built-in XML to SimpleSAMLphp metadata converter, which by default is available as `/admin/metadata-converter.php` in your SimpleSAMLphp installation. Note that the idp-remote file lists all IdPs you trust. You should remove all IdPs that you don't use. Setting the default IdP ----------------------- An option in the authentication source allows you to configure which IdP should be used. This is the `idp` option. [ 'saml:SP', /* * The entity ID of the IdP this should SP should contact. * Can be NULL/unset, in which case the user will be shown a list of available IdPs. */ 'idp' => 'https://idp.example.com', ], ]; Exchange metadata with the IdP ------------------------------ In order to complete the connection between your SP and an IdP, you must exchange the metadata of your SP with the IdP. The metadata of your SP can be found in the *Federation* tab of the web interface. Copy the SAML 2.0 XML Metadata document automatically generated by SimpleSAMLphp and send it to the administrator of the IdP. You can also send them the dedicated URL of your metadata, so that they can fetch it periodically and obtain automatically any changes that you may perform to your SP. You will also need to add the metadata of the IdP. Ask them to provide you with their metadata, and parse it using the *XML to SimpleSAMLphp metadata converter* tool available also in the *Federation* tab of the web interface. Copy the resulting parsed metadata and paste it with a text editor into the `metadata/saml20-idp-remote.php` file in your SimpleSAMLphp directory. If you intend to add your SP to a federation, the procedure for managing trust in federations will differ, but the common part is that you would need to provide the *SAML 2.0 metadata of your SP*, and register that with the federation administration. You will probably be required too to consume the federation metadata periodically. Read more about [automated metadata management](https://github.com/simplesamlphp/simplesamlphp-module-metarefresh/blob/master/docs/simplesamlphp-automated_metadata.md) to learn more about that. Test the SP ----------------------------- After the metadata is configured on the IdP, you should be able to test the configuration. The installation page of SimpleSAMLphp has a link to test authentication sources. When you click the link, you should receive a list of authentication sources, including the one you have created for the SP. After you click the link for that authentication source, you will be redirected to the IdP. After entering your credentials, you should be redirected back to the test page. The test page should contain a list of your attributes: ![Screenshot of the status page after a user has succesfully authenticated](resources/simplesamlphp-sp/screenshot-example.png) For a better looking, more advanced Discovery Service with tabs and live search, you may want to use the `discopower` module contained in the SimpleSAMLphp distribution. Integrating authentication with your own application ---------------------------------------------------- The API is documented in [the SP API reference](simplesamlphp-sp-api). For those web resources you want to protect, you must add a few lines of PHP code: - Register the SimpleSAMLphp classes with the PHP autoloader. - Require authentication of the user for those places it is required. - Access the users attributes. Example code: We start off with loading a file which registers the SimpleSAMLphp classes with the autoloader. require_once('../../lib/_autoload.php'); We select our authentication source: $as = new \SimpleSAML\Auth\Simple('default-sp'); We then require authentication: $as->requireAuth(); And print the attributes: $attributes = $as->getAttributes(); print_r($attributes); Each attribute name can be used as an index into $attributes to obtain the value. Every attribute value is an array - a single-valued attribute is an array of a single element. We can also request authentication with a specific IdP: $as->login([ 'saml:idp' => 'https://idp.example.org/', ]); Other options are also available. Take a look in the documentation for the [SP module](./saml:sp) for a list of all parameters. If we are using PHP sessions in SimpleSAMLphp and in the application we are protecting, SimpleSAMLphp will close any existing session when invoked for the first time, and its own session will prevail afterwards. If you want to restore your own session after calling SimpleSAMLphp, you can do so by cleaning up the session like this: $session = \SimpleSAML\Session::getSessionFromRequest(); $session->cleanup(); If you don't cleanup SimpleSAMLphp's session and try to use $_SESSION afterwards, you won't be using your own session and all your data is likely to get lost or inaccessible. Note that if your application uses a [custom session handler](https://www.php.net/manual/en/function.session-set-save-handler.php), SimpleSAMLphp will use it as well. This can lead to problems because SimpleSAMLphp's stand-alone web UI uses the default PHP session handlers. Therefore, you may need to unset the custom handler before making any calls to SimpleSAMLphp: // use custom save handler session_set_save_handler($handler); session_start(); // close session and restore default handler session_write_close(); session_set_save_handler(new SessionHandler(), true); // use SimpleSAML\Session $session = \SimpleSAML\Session::getSessionFromRequest(); $session->cleanup(); session_write_close(); // back to custom save handler session_set_save_handler($handler); session_start(); Support ------- If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are fortunate: Around SimpleSAMLphp there is a great Open source community, and you are welcome to join! The forums are open for you to ask questions, contribute answers other further questions, request improvements or contribute with code or plugins of your own. - [SimpleSAMLphp homepage](https://simplesamlphp.org) - [List of all available SimpleSAMLphp documentation](https://simplesamlphp.org/docs/) - [Join the SimpleSAMLphp user's mailing list](https://simplesamlphp.org/lists) simplesamlphp-1.19.1/docs/simplesamlphp-artifact-sp.md0000644000000000000000000000257214042503475021534 0ustar rootrootUsing HTTP-Artifact from a SimpleSAMLphp SP =========================================== This document describes how to use the HTTP-Artifact binding to receive authentication responses from the IdP. Which binding the IdP should use when sending authentication responses is controlled by the `ProtocolBinding` in the SP configuration. To make your Service Provider (SP) request that the response from the IdP is sent using the HTTP-Artifact binding, this option must be set to the HTTP-Artifact binding. In addition to selecting the binding, you must also add a private key and certificate to your SP. This is used for SSL client authentication when contacting the IdP. To generate a private key and certificate, you may use the `openssl` commandline utility: openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out sp.example.org.crt -keyout sp.example.org.pem You can then add the private key and certificate to the SP configuration. When this is done, you can add the metadata of your SP to the IdP, and test the authentication. Example configuration --------------------- 'artifact-sp' => [ 'saml:SP', 'ProtocolBinding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact', 'privatekey' => 'sp.example.org.pem', 'certificate' => 'sp.example.org.crt', ], See the [SP configuration reference](./saml:sp) for a description of the options. simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.14.md0000644000000000000000000001732414042503475022456 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.14 ==================================== The `mcrypt` extension is no longer required by SimpleSAMLphp, so if no signatures or encryption are being used, it can be skipped. It is still a requirement for `xmlseclibs` though, so for those verifying or creating signed documents, or using encryption, it is still needed. The `mbstring` extension is now required starting on SimpleSAMLphp 1.14.12. PHP session cookies are now set to HTTP-only by default. This relates to the `session.phpsession.httponly` configuration option. The default value for the 'trusted.url.domains' option in the config file has been changed from null to an empty array, making SimpleSAMLphp secure to open redirection attacks by default. Setting it explicitly to null will re-allow insecure redirections. The jQuery version in use has been bumped to the latest 1.8.X version. Service Providers using the eduPersonTargetedID attribute, will get a DOMNodeList object instead of the NameID value. In order to process the NameID, a SAML2_XML_saml_NameID object can be used: ``` $attributes = $as->getAttributes(); $eptid = $attributes['eduPersonTargetedID'][0]->item(0); $nameID = new SAML2_XML_saml_NameID($eptid); ``` The following deprecated files, directories and endpoints have been removed: * `bin/pack.php` * `docs/pack.txt` * `docs/simplesamlphp-features.txt` * `docs/simplesamlphp-reference-sp-hosted.txt` * `docs/simplesamlphp-subversion.txt` * `lib/SimpleSAML/Auth/BWC.php` (`SimpleSAML_Auth_BWC`) * `lib/SimpleSAML/MemcacheStore.php` (`SimpleSAML_MemcacheStore`) * `lib/SimpleSAML/Metadata/MetaDataStorageHandlerDynamicXML.php` (`SimpleSAML_Metadata_MetaDataStorageHandlerDynamicXML`) * `modules/aselect/www/linkback.php` * `modules/core/lib/ModuleDefinition.php` (`sspmod_core_ModuleDefinition`) * `modules/core/lib/ModuleInstaller.php` (`sspmod_core_ModuleInstaller`) * `modules/core/www/bwc_resumeauth.php` * `modules/core/www/idp/resumeauth.php` * `modules/oauth/lib/OauthSignatureMethodRSASHA1.php` (`sspmod_oauth_OauthSignatureMethodRSASHA1`) * `modules/oauth/www/accessToken.php` * `modules/oauth/www/authorize.php` * `modules/oauth/www/requestToken.php` * `modules/smartnameattribute/` * `www/resources/jquery.js` * `www/resources/jquery-ui.js` * `www/resources/uitheme/` * `www/shib13/sp/` * `www/saml2/idp/idpInitSingleLogoutServiceiFrame.php` * `www/saml2/idp/SingleLogoutServiceiFrame.php` * `www/saml2/idp/SingleLogoutServiceiFrameResponse.php` * `www/saml2/sp/` * `www/wsfed/` * `www/example-simple/` * `www/auth/` The following deprecated methods and constants have been removed: * `SimpleSAML_AuthMemCookie::getLoginMethod()` * `SimpleSAML_Session::DATA_TIMEOUT_LOGOUT` * `SimpleSAML_Session::expireDataLogout()` * `SimpleSAML_Session::get_sp_list()` * `SimpleSAML_Session::getAttribute()` * `SimpleSAML_Session::getAttributes()` * `SimpleSAML_Session::getAuthnInstant()` * `SimpleSAML_Session::getAuthnRequest()` * `SimpleSAML_Session::getAuthority()` * `SimpleSAML_Session::getIdP()` * `SimpleSAML_Session::getInstance()` * `SimpleSAML_Session::getLogoutState()` * `SimpleSAML_Session::getNameID()` * `SimpleSAML_Session::getSessionIndex()` * `SimpleSAML_Session::getSize()` * `SimpleSAML_Session::isAuthenticated()` * `SimpleSAML_Session::remainingTime()` * `SimpleSAML_Session::setAttribute()` * `SimpleSAML_Session::setAttributes()` * `SimpleSAML_Session::setAuthnRequest()` * `SimpleSAML_Session::setIdP()` * `SimpleSAML_Session::setLogoutState()` * `SimpleSAML_Session::setNameID()` * `SimpleSAML_Session::setSessionDuration()` * `SimpleSAML_Session::setSessionIndex()` * `SimpleSAML_Utilities::generateRandomBytesMTrand()` The following methods have changed their signature. Refer to the code for the updated signatures: * `SimpleSAML_Auth_Default::initLogin()` * `SimpleSAML_Metadata_MetaDataStorageHandler::getGenerated()` * `SimpleSAML_Metadata_MetaDataStorageHandler::getMetaData()` * `SimpleSAML_Metadata_MetaDataStorageHandler::getMetaDataCurrent()` * `SimpleSAML_Metadata_MetaDataStorageHandler::getMetaDataCurrentEntityID()` * `SimpleSAML_Session::doLogout()` * `SimpleSAML_Session::getAuthState()` * `SimpleSAML_Session::registerLogoutHandler()` * `SimpleSAML_Utilities::generateRandomBytes()` * `SimpleSAML_XML_Shib13_AuthnRequest::createRedirect()` The following methods and classes have been deprecated. Refer to the code for alternatives: * `SimpleSAML_Auth_Default`, together with all the `SimpleSAML_Auth_Default.*` keys in the state array. * `SimpleSAML_Auth_Default::extractPersistentAuthState()` * `SimpleSAML_Auth_Default::handleUnsolicitedAuth()` * `SimpleSAML_Auth_Default::initLogin()` * `SimpleSAML_Auth_Default::initLogout()` * `SimpleSAML_Auth_Default::initLogoutReturn()` * `SimpleSAML_Auth_Default::loginCompleted()` * `SimpleSAML_Auth_Default::logoutCallback()` * `SimpleSAML_Auth_Default::logoutCompleted()` * `SimpleSAML_Utilities` * `SimpleSAML_Utilities::addURLParameter()` * `SimpleSAML_Utilities::aesDecrypt()` * `SimpleSAML_Utilities::aesEncrypt()` * `SimpleSAML_Utilities::arrayize()` * `SimpleSAML_Utilities::checkCookie()` * `SimpleSAML_Utilities::checkDateConditions()` * `SimpleSAML_Utilities::checkURLAllowed()` * `SimpleSAML_Utilities::createHttpPostRedirectLink()` * `SimpleSAML_Utilities::createPostRedirectLink()` * `SimpleSAML_Utilities::debugMessage()` * `SimpleSAML_Utilities::doRedirect()` * `SimpleSAML_Utilities::fatalError()` * `SimpleSAML_Utilities::fetch()` * `SimpleSAML_Utilities::formatDOMElement()` * `SimpleSAML_Utilities::formatXMLString()` * `SimpleSAML_Utilities::generateID()` * `SimpleSAML_Utilities::generateRandomBytes()` * `SimpleSAML_Utilities::generateTimestamp()` * `SimpleSAML_Utilities::getAcceptLanguage()` * `SimpleSAML_Utilities::getAdminLogoutURL()` * `SimpleSAML_Utilities::getBaseURL()` * `SimpleSAML_Utilities::getDefaultEndpoint()` * `SimpleSAML_Utilities::getDOMChildren()` * `SimpleSAML_Utilities::getDOMText()` * `SimpleSAML_Utilities::getFirstPathElement()` * `SimpleSAML_Utilities::getLastError()` * `SimpleSAML_Utilities::getSecretSalt()` * `SimpleSAML_Utilities::getSelfHost()` * `SimpleSAML_Utilities::getSelfHostWithPath()` * `SimpleSAML_Utilities::getTempDir()` * `SimpleSAML_Utilities::initTimezone()` * `SimpleSAML_Utilities::ipCIDRcheck()` * `SimpleSAML_Utilities::isAdmin()` * `SimpleSAML_Utilities::isDOMElementOfType()` * `SimpleSAML_Utilities::isHTTPS()` * `SimpleSAML_Utilities::isWindowsOS()` * `SimpleSAML_Utilities::loadPrivateKey()` * `SimpleSAML_Utilities::loadPublicKey()` * `SimpleSAML_Utilities::maskErrors()` * `SimpleSAML_Utilities::normalizeURL()` * `SimpleSAML_Utilities::parseAttributes()` * `SimpleSAML_Utilities::parseDuration()` * `SimpleSAML_Utilities::parseQueryString()` * `SimpleSAML_Utilities::parseStateID()` * `SimpleSAML_Utilities::popErrorMask()` * `SimpleSAML_Utilities::postRedirect()` * `SimpleSAML_Utilities::redirect()` * `SimpleSAML_Utilities::redirectTrustedURL()` * `SimpleSAML_Utilities::redirectUntrustedURL()` * `SimpleSAML_Utilities::requireAdmin()` * `SimpleSAML_Utilities::resolveCert()` * `SimpleSAML_Utilities::resolvePath()` * `SimpleSAML_Utilities::resolveURL()` * `SimpleSAML_Utilities::selfURL()` * `SimpleSAML_Utilities::selfURLHost()` * `SimpleSAML_Utilities::selfURLNoQuery()` * `SimpleSAML_Utilities::setCookie()` * `SimpleSAML_Utilities::stringToHex()` * `SimpleSAML_Utilities::transposeArray()` * `SimpleSAML_Utilities::validateCA()` * `SimpleSAML_Utilities::validateXML()` * `SimpleSAML_Utilities::validateXMLDocument()` * `SimpleSAML_Utilities::writeFile()` The following modules will no longer be shipped with the next version of SimpleSAMLphp: * `aggregator` * `aggregator2` * `aselect` * `autotest` * `casserver` * `consentSimpleAdmin` * `discojuice` * `InfoCard` * `logpeek` * `metaedit` * `modinfo` * `papi` * `oauth` * `openid` * `openidProvider` * `saml2debug` * `themefeidernd` simplesamlphp-1.19.1/docs/simplesamlphp-ecp-idp.md0000644000000000000000000000613514042503475020637 0ustar rootrootAdding Enhanced Client or Proxy (ECP) Profile support to the IdP =============================================================== This document describes the necessary steps to enable support for the [SAML V2.0 Enhanced Client or Proxy Profile Version 2.0](http://docs.oasis-open.org/security/saml/Post2.0/saml-ecp/v2.0/cs01/saml-ecp-v2.0-cs01.pdf) on a simpleSAMLphp Identity Provider (IdP). The SAML V2.0 Enhanced Client or Proxy (ECP) profile is a SSO profile for use with HTTP, and clients with the capability to directly contact a principal's identity provider(s) without requiring discovery and redirection by the service provider, as in the case of a browser. It is particularly useful for desktop or server-side HTTP clients. Limitations ----------- * Authentication must be done via [HTTP Basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme). * Authentication must not require user interaction (e.g. auth filters that require user input). * Channel Bindings are unsupported. * "Holder of Key" Subject Confirmation is unsupported. This feature has been tested to work with Microsoft Office 365, but other service providers may require features of the ECP profile that are currently unsupported! Enabling ECP Profile on the IdP ----------------------------------- To enable the IdP to send ECP assertions you must add the `saml20.ecp` option to the `saml20-idp-hosted` metadata file: $metadata['__DYNAMIC:1__'] = [ [....] 'auth' => 'example-userpass', 'saml20.ecp' => true, ]; Note: authentication filters that require interaction with the user will not work with ECP. Add new metadata to SPs ----------------------- After enabling the ECP Profile your IdP metadata will change. An additional ECP `SingleSignOnService` endpoint is added. You therefore need to update the metadata for your IdP at your SPs. The `saml20-idp-remote` metadata for simpleSAMLphp SPs should contain something like the following code: 'SingleSignOnService' => array ( 0 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'https://idp.example.org/simplesaml/saml2/idp/SSOService.php', ), 1 => array ( 'index' => 0, 'Location' => 'https://didp.example.org/simplesaml/saml2/idp/SSOService.php', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP', ), ), SP metadata on the IdP ---------------------- A SP using the ECP Profile must have an `AssertionConsumerService` endpoint supporting that profile. This means that you have to use the complex endpoint format in `saml20-sp-remote` metadata. In general, this should look like the following code: 'AssertionConsumerService' => array ( 0 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://sp.example.org/Shibboleth.sso/SAML2/POST', 'index' => 1, ), 1 => array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS', 'Location' => 'https://sp.example.org/ECP', 'index' => 2, ), ), simplesamlphp-1.19.1/docs/conf.py0000644000000000000000000000014314042503475015410 0ustar rootrootimport sphinx_rtd_theme extensions = [ 'sphinx_rtd_theme', ] html_theme = "sphinx_rtd_theme" simplesamlphp-1.19.1/docs/simplesamlphp-artifact-idp.md0000644000000000000000000000725614042503475021672 0ustar rootrootAdding HTTP-Artifact support to the IdP ======================================= This document describes the necessary steps to enable support for the HTTP-Artifact binding on a SimpleSAMLphp IdP: 1. Configure SimpleSAMLphp to use memcache to store the session. 2. Enable support for sending artifacts in `saml20-idp-hosted`. 3. Add the webserver certificate to the generated metadata. Memcache -------- To enable memcache, you must first install and configure memcache on the server hosting your IdP. You need both a memcache server and a the PHP memcached client (extension). How this is done depends on the distribution. If you are running Debian or Ubuntu, you can install this by running: apt install memcached php-memcached simpleSAMLphp also supports the legacy `php-memcache` (without `d`) variant. *Note*: For security, you must make sure that the memcache server is inaccessible to other hosts. The default configuration on Debian is for the memcache server to be accessible to only the local host. Once the memcache server is configured, you can configure simplesamlphp to use it to store sessions. You can do this by setting the `store.type` option in `config.php` to `memcache`. If you are running memcache on a different server than the IdP, you must also change the `memcache_store.servers` option in `config.php`. Enabling artifact on the IdP ---------------------------- To enable the IdP to send artifacts, you must add the `saml20.sendartifact` option to the `saml20-idp-hosted` metadata file: $metadata['__DYNAMIC:1__'] = [ [....] 'auth' => 'example-userpass', 'saml20.sendartifact' => TRUE, ]; Add new metadata to SPs ----------------------- After enabling the Artifact binding, your IdP metadata will change to add a ArtifactResolutionService endpoint. You therefore need to update the metadata for your IdP at your SPs. `saml20-idp-remote` metadata for SimpleSAMLphp SPs should contain something like: 'ArtifactResolutionService' => [ [ 'index' => 0, 'Location' => 'https://idp.example.org/simplesaml/saml2/idp/ArtifactResolutionService.php', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP', ], ], SP metadata on the IdP ---------------------- An SP using the HTTP-Artifact binding must have an AssertionConsumerService endpoint supporting that binding. This means that you must use the complex endpoint format in `saml20-sp-remote` metadata. In general, that should look something like: 'AssertionConsumerService' => array ( [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'index' => 0, ], [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact', 'Location' => 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'index' => 2, ], ), (The specific values of the various fields will vary depending on the SP.) Certificate in metadata ----------------------- Some SPs validates the SSL certificate on the ArtifactResolutionService using the certificates in the metadata. You may therefore have to add the webserver certificate to the metadata that your IdP generates. To do this, you need to set the `https.certificate` option in the `saml20-idp-hosted` metadata file. That option should refer to a file containing the webserver certificate. $metadata['__DYNAMIC:1__'] = [ [....] 'auth' => 'example-userpass', 'saml20.sendartifact' => TRUE, 'https.certificate' => '/etc/apache2/webserver.crt', ]; simplesamlphp-1.19.1/docs/simplesamlphp-googleapps.md0000644000000000000000000002511514042503475021455 0ustar rootrootSetting up a SimpleSAMLphp SAML 2.0 IdP to use with Google Workspace (G Suite / Google Apps) for Education ============================================ SimpleSAMLphp news and documentation ------------------------------------ This document is part of the SimpleSAMLphp documentation suite. * [List of all SimpleSAMLphp documentation](https://simplesamlphp.org/docs) * [SimpleSAMLphp homepage](https://simplesamlphp.org) ## Introduction This article describes how to configure a Google Workspace (formerly G Suite, formerly Google Apps) instance as a service provider to use with a SimpleSAMLphp identity provider. This article assumes that you have already read the SimpleSAMLphp installation manual, and installed a version of SimpleSAMLphp at your server. In this example we will setup this server as an IdP for Google Workspace: dev2.andreas.feide.no ## Enabling the Identity Provider functionality Edit `config.php`, and enable the SAML 2.0 IdP: 'enable.saml20-idp' => true, 'enable.shib13-idp' => false, ## Setting up a signing certificate You must generate a certificate for your IdP. Here is an example of an openssl command to generate a new key and a self signed certificate to use for signing SAML messages: openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out googleworkspaceidp.crt -keyout googleworkspaceidp.pem The certificate above will be valid for 10 years. Here is an example of typical user input when creating a certificate request: Country Name (2 letter code) [AU]:NO State or Province Name (full name) [Some-State]:Trondheim Locality Name (eg, city) []:Trondheim Organization Name (eg, company) [Internet Widgits Pty Ltd]:UNINETT Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:dev2.andreas.feide.no Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: **Note**: SimpleSAMLphp will only work with RSA and not DSA certificates. Authentication source --------------------- The next step is to configure the way users authenticate on your IdP. Various modules in the `modules/` directory provides methods for authenticating your users. This is an overview of those that are included in the SimpleSAMLphp distribution: `exampleauth:UserPass` : Authenticate against a list of usernames and passwords. `exampleauth:Static` : Automatically log in as a user with a set of attributes. [`ldap:LDAP`](./ldap:ldap) : Authenticates an user to a LDAP server. For more authentication modules, see [SimpleSAMLphp Identity Provider QuickStart](simplesamlphp-idp). In this guide, we will use the `exampleauth:UserPass` authentication module. This module does not have any dependencies, and is therefore simple to set up. After you have successfuly tested that everything is working with the simple `exampleauth:UserPass`, you are encouraged to setup SimpleSAMLphp IdP towards your user storage, such as an LDAP directory. (Use the links on the authentication sources above to read more about these setups. `ldap:LDAP` is the most common authentication source.) Configuring the authentication source ------------------------------------- The `exampleauth:UserPass` authentication source is part of the `exampleauth` module. This module isn't enabled by default, so you will have to enable it. This is done by creating a file named `enable` in `modules/exampleauth/`. On unix, this can be done by running (from the SimpleSAMLphp installation directory): touch modules/exampleauth/enable The next step is to create an authentication source with this module. An authentication source is an authentication module with a specific configuration. Each authentication source has a name, which is used to refer to this specific configuration in the IdP configuration. Configuration for authentication sources can be found in `config/authsources.php`. In this example we will use `example-userpass`, and hence that section is what matters and will be used. [ 'exampleauth:UserPass', 'student:studentpass' => [ 'uid' => ['student'], ], 'employee:employeepass' => [ 'uid' => ['employee'], ], ], ]; ?> This configuration creates two users - `student` and `employee`, with the passwords `studentpass` and `employeepass`. The username and password are stored in the array index `student:studentpass` for the `student`-user. The attributes (only `uid` in this example) will be returned by the IdP when the user logs on. ## Configuring metadata for an SAML 2.0 IdP If you want to setup a SAML 2.0 IdP for Google Workspace, you need to configure two metadata files: `saml20-idp-hosted.php` and `saml20-sp-remote.php`. ### Configuring SAML 2.0 IdP Hosted metadata This is the configuration of the IdP itself. Here is some example config: // The SAML entity ID is the index of this config. Dynamic:X will automatically generate an entity ID (recommended) $metadata['__DYNAMIC:1__'] => [ // The hostname of the server (VHOST) that this SAML entity will use. 'host' => '__DEFAULT__', // X.509 key and certificate. Relative to the cert directory. 'privatekey' => 'googleworkspaceidp.pem', 'certificate' => 'googleappsidp.crt', 'auth' => 'example-userpass', ] **Note**: You can only have one entry in the file with host equal to `__DEFAULT__`, therefore you should replace the existing entry with this one, instead of adding this entry as a new entry in the file. ### Configuring SAML 2.0 SP Remote metadata In the `saml20-sp-remote.php` file we will configure an entry for Google Workspace for Education. There is already an entry for Google Workspace in the template, but we will change the domain name: /* * This example shows an example config that works with Google Workspace (G Suite / Google Apps) for education. * What is important is that you have an attribute in your IdP that maps to the local part of the email address * at Google Workspace. E.g. if your google account is foo.com, and you have a user with email john@foo.com, then you * must set the simplesaml.nameidattribute to be the name of an attribute that for this user has the value of 'john'. */ $metadata['https://www.google.com/a/g.feide.no'] => [ 'AssertionConsumerService' => 'https://www.google.com/a/g.feide.no/acs', 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', 'simplesaml.nameidattribute' => 'uid', 'simplesaml.attributes' => false ]; You must also map some attributes received from the authentication module into email field sent to Google Workspace. In this example, the `uid` attribute is set. When you later configure the IdP to connect to a LDAP directory or some other authentication source, make sure that the `uid` attribute is set properly, or you can configure another attribute to use here. The `uid` attribute contains the local part of the user name. For an e-mail address `student@g.feide.no`, the `uid` should be set to `student`. You should modify the `AssertionConsumerService` to include your G Suite domain name instead of `g.feide.no`. For an explanation of the parameters, see the [SimpleSAMLphp Identity Provider QuickStart](simplesamlphp-idp). ## Configure Google Workspace Start by logging in to our Google Workspace for education account panel. Then select "Advanced tools": **Figure 1. We go to advanced tools** ![We go to advanced tools](resources/simplesamlphp-googleapps/googleapps-menu.png) Then select "Set up single sign-on (SSO)": **Figure 2. We go to setup SSO** ![We go to setup SSO](resources/simplesamlphp-googleapps/googleapps-sso.png) Upload a certificate, such as the googleworkspaceidp.crt created above: **Figure 3. Uploading certificate** ![Uploading certificate](resources/simplesamlphp-googleapps/googleapps-cert.png) Fill out the remaining fields: The most important field is the Sign-in page URL. You can find the correct value in your IdP metadata. Browse to your simpleSAMLphp installation, go to the "Federation" tab, under "SAML 2.0 IdP Metadata" select "show metadata". You will find in the metadata the XML tag `` which contains the right URL to input in the field, it will look something like this: https://dev2.andreas.feide.no/simplesaml/saml2/idp/SSOService.php You must also configure the IdP initiated Single LogOut endpoint of your server. You will find this in your metadata XML in the tag ``. It will look something like: http://dev2.andreas.feide.no/simplesaml/saml2/idp/SingleLogoutService.php again, using the host name of your IdP server. The Sign-out page or change password URL can be static pages on your server. The network mask determines which IP addresses will be asked for SSO login. IP addresses not matching this mask will be presented with the normal Google Workspace login page. It is normally best to leave this field empty to enable authentication for all URLs. **Figure 4. Fill out the remaining fields** ![Fill out the remaining fields](resources/simplesamlphp-googleapps/googleapps-ssoconfig.png) ### Add a user in G Suite that is known to the IdP Before we can test login, a new user must be defined in Google Workspace. This user must have a mail field matching the email prefix mapped from the attribute as described above in the metadata section. ## Test to login to G Suite for education Go to the URL of your mail account for this domain, the URL is similar to the following: http://mail.google.com/a/yourgoogleappsdomain.com replacing the last part with your own Google Workspace domain name. ## Security Considerations Make sure that your IdP server runs HTTPS (TLS). The Apache documentation contains information for how to configure HTTPS. Support ------- If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are fortunate: Around SimpleSAMLphp there is a great Open source community, and you are welcome to join! The forums are open for you to ask questions, contribute answers other further questions, request improvements or contribute with code or plugins of your own. - [SimpleSAMLphp homepage](https://simplesamlphp.org) - [List of all available SimpleSAMLphp documentation](https://simplesamlphp.org/docs/) - [Join the SimpleSAMLphp user's mailing list](https://simplesamlphp.org/lists) simplesamlphp-1.19.1/docs/simplesamlphp-metadata-pdostoragehandler.md0000644000000000000000000000754314042503475024605 0ustar rootrootPDO Metadata Storage Handler ============================= Introduction ------------ If you want to run a clustered SimpleSAMLphp IdP service and you would like to have centralized storage for metadata, you can use the PDO metadata storage handler. The present document explains how to configure SimpleSAMLphp and your database. Preparations ------------ You will need to have the appropriate PDO drivers for your database and you will have to configure the database section within the config/config.php file. Configuring SimpleSAMLphp ----------------------------- You will first need to configure a PDO metadata source. [root@simplesamlphp simplesamlphp]# vi config/config.php Here is an example of flatfile plus PDO: 'metadata.sources' => [ ['type' => 'flatfile'], ['type' => 'pdo'], ], Initializing the Database ------------------------- Once you have configured your metadata sources to include a PDO source, you will need to initialize the database. This process will create tables in the database for each type of metadata set (saml20-idp-hosted, saml20-idp-remote, saml20-sp-remote, etc). [root@simplesamlphp simplesamlphp]# php bin/initMDSPdo.php If you connect to your database, you will see 11 new empty tables; one for each metadata set. Adding Metadata --------------- With the PDO metadata storage handler, metadata is stored in the table for the appropriate set and is stored in JSON format. As an example, here is the saml20_idp_hosted table: entity_id | entity_data ----------------|------------------------------------------------------------------------------------------------------------------------- `__DEFAULT:1__` | {"host":"\_\_DEFAULT\_\_","privatekey":"idp.key","certificate":"idp.crt","auth":"example-ldap","userid.attribute":"uid"} Another example is the saml20_idp_remote table: entity_id | entity_data -------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- https://openidp.feide.no | {"name":{"en":"Feide OpenIdP - guest users","no":"Feide Gjestebrukere"},"description":"Here you can login with your account on Feide RnD OpenID. If you do not already have an account on this identity provider, you can create a new one by following the create new account link and follow the instructions.","SingleSignOnService":"https:\/\/openidp.feide.no\/simplesaml\/saml2\/idp\/SSOService.php","SingleLogoutService":"https:\/\/openidp.feide.no\/simplesaml\/saml2\/idp\/SingleLogoutService.php","certFingerprint":"c9ed4dfb07caf13fc21e0fec1572047eb8a7a4cb"} There is an included script in the `bin` directory that will import all flatfile metadata files and store them in the database, but you can use an external tool to maintain the metadata in the database. This document will only cover adding metadata using the included utility, but the tables above should provide enough information if you would like to create a utility to manage your metadata externally. To import all flatfile metadata files into the PDO database, run the following script [root@simplesamlphp simplesamlphp]# php bin/importPdoMetadata.php In the event that you import a metadata for an entity id that already exists in the database, it will be overwritten. simplesamlphp-1.19.1/docs/simplesamlphp-idp-more.md0000644000000000000000000001127414042503475021032 0ustar rootrootSimpleSAMLphp Identity Provider Advanced Topics =============================================== AJAX iFrame Single Log-Out -------------------------- If you have read about the AJAX iFrame Single Log-Out approach at Andreas' blog and want to enable it, edit your saml20-idp-hosted.php metadata, and add this configuration line for the IdP: 'logouttype' => 'iframe', Attribute Release Consent ------------------------- The attribute release consent is documented in a [separate document](./consent:consent). Support for bookmarking the login page -------------------------------------- Most SAML software crash fatally when users bookmark the login page and return later on when the cached session information is lost. This is natural as the login page happens in the middle of a SAML transaction, and the SAML software needs some references to the original request in order to be able to produce the SAML Response. SimpleSAMLphp has implemented a graceful fallback to tackle this situation. When SimpleSAMLphp is not able to lookup a session during the login process, it falls back to the *IdP-first flow*, described in the next section, where the reference to the request is not needed. What happens in the IdP-first flow is that a *SAML unsolicited response* is sent directly to the SP. An *unsolicited response* is a SAML Response with no reference to a SAML Request (no `InReplyTo` field). When a SimpleSAMLphp IdP falls back to IdP-first flow, the `RelayState` parameter sent by the SP in the SAML request is also lost. The RelayState information contain a reference key for the SP to lookup where to send the user after successful authentication. The SimpleSAMLphp Service Provider supports configuring a static URL to redirect the user after a unsolicited response is received. See more information about the `RelayState` parameter in the next section: *IdP-first flow*. IdP-first flow -------------- If you do not want to start the SSO flow at the SP, you may use the IdP-first setup. To do this, redirect the user to the SSOService endpoint on the IdP with a `spentityid` parameter that matches the SP EntityID that the user should be authenticated for. Here is an example of such a URL: https://idp.example.org/simplesaml/saml2/idp/SSOService.php?spentityid=urn:mace:feide.no:someservice You can also add a `RelayState` parameter to the IdP-first URL: https://idp.example.org/simplesaml/saml2/idp/SSOService.php?spentityid=urn:mace:feide.no:someservice&RelayState=https://sp.example.org/somepage The `RelayState` parameter is often used to carry the URL the SP should redirect to after authentication. It is also possible to specify the Assertion Consumer URL with the `ConsumerURL` parameter. For compatibility with certain SPs, SimpleSAMLphp will also accept the `providerId`, `target` and `shire` parameters as aliases for `spentityid`, `RelayState` and `ConsumerURL`, respectively. ### IdP first with SAML 1.1 A SAML 1.1 SP does not send an authentication request to the IdP, but instead triggers IdP initiated authentication directly. If you want to do it manually, you can access the following URL: https://idp.example.org/simplesaml/shib13/idp/SSOService.php?providerId=urn:mace:feide.no:someservice&shire=https://sp.example.org/acs-endpoint&target=https://sp.example.org/somepage The parameters are as follows: `providerID` : The entityID of the SP. This parameter is required. `shire` : The AssertionConsumerService endpoint of the SP. This parameter is required. `target` : The target parameter the SP should receive with the authentication response. This is often the page the user should be sent to after authentication. This parameter is optional for the IdP, but must be specified if the SP you are targeting is running SimpleSAMLphp. : *Note*: This parameter must be sent as `target` (with lowercase letters) when starting the authentication, while it is sent as `TARGET` (with uppercase letters) in the authentication response. IdP-initiated logout -------------------- IdP-initiated logout can be initiated by visiting the URL: https://idp.example.org/simplesaml/saml2/idp/SingleLogoutService.php?ReturnTo= It will send a logout request to each SP, and afterwards return the user to the URL specified in the `ReturnTo` parameter. Bear in mind that IdPs might disallow redirecting to URLs other than those of their own for security reasons, so in order to get the redirection to work, it might be necessary to ask the IdP to whitelist the URL we are planning to redirect to. simplesamlphp-1.19.1/docs/simplesamlphp-metadata-extensions-ui.md0000644000000000000000000002512614042503475023707 0ustar rootrootSAML V2.0 Metadata Extensions for Login and Discovery User Interface ============================= * Author: Timothy Ace [tace@synacor.com](mailto:tace@synacor.com) This is a reference for the SimpleSAMLphp implementation of the [SAML V2.0 Metadata Extensions for Login and Discovery User Interface](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-metadata-ui/v1.0/sstc-saml-metadata-ui-v1.0.pdf) defined by OASIS. The metadata extensions are available to both IdP and SP usage of SimpleSAMLphp. For an IdP, the entries are placed in `metadata/saml20-idp-hosted.php`, for an SP, they are put inside the relevant entry in `authsources.php`. An example for an IdP: [ 'DisplayName' => [ 'en' => 'English name', 'es' => 'Nombre en Español', ], 'Description' => [ 'en' => 'English description', 'es' => 'Descripción en Español', ], 'InformationURL' => [ 'en' => 'http://example.com/info/en', 'es' => 'http://example.com/info/es', ], 'PrivacyStatementURL' => [ 'en' => 'http://example.com/privacy/en', 'es' => 'http://example.com/privacy/es', ], 'Keywords' => [ 'en' => ['communication', 'federated session'], 'es' => ['comunicación', 'sesión federated'], ], 'Logo' => [ [ 'url' => 'http://example.com/logo1.png', 'height' => 200, 'width' => 400, 'lang' => 'en', ], [ 'url' => 'http://example.com/logo2.png', 'height' => 201, 'width' => 401, ], ], ], 'DiscoHints' => [ 'IPHint' => ['130.59.0.0/16', '2001:620::0/96'], 'DomainHint' => ['example.com', 'www.example.com'], 'GeolocationHint' => ['geo:47.37328,8.531126', 'geo:19.34343,12.342514'], ], /* ... */ ]; And for an SP it could look like this: [ 'saml:SP', 'UIInfo' => [ 'DisplayName' => [ 'en' => 'English name', 'es' => 'Nombre en Español' ], 'Description' => [ 'en' => 'English description', 'es' => 'Descripción en Español' ], ], /* ... */ ], ]; The OASIS specification primarily defines how an entity can communicate metadata related to IdP or service discovery and identification. There are two different types of extensions defined. There are the ``elements that define how an IdP or SP should be displayed and there are the `` elements that define when an IdP should be chosen/displayed. UIInfo Items -------------- These elements are used for IdP and SP discovery to determine what to display about an IdP or SP. These properties are all children of the `UIInfo` key. *Note*: Most elements are localized strings that specify the language using the array key as the language-code: 'DisplayName' => [ 'en' => 'English name', 'es' => 'Nombre en Español', ], `DisplayName` : The localized list of names for this entity 'DisplayName' => [ 'en' => 'English name', 'es' => 'Nombre en Español', ], `Description` : The localized list of statements used to describe this entity 'Description' => [ 'en' => 'English description', 'es' => 'Descripción en Español', ], `InformationURL` : A localized list of URLs where more information about the entity is located. 'InformationURL' => [ 'en' => 'http://example.com/info/en', 'es' => 'http://example.com/info/es', ], `PrivacyStatementURL` : A localized list of URLs where the entity's privacy statement is located. 'PrivacyStatementURL' => [ 'en' => 'http://example.com/privacy/en', 'es' => 'http://example.com/privacy/es', ], `Keywords` : A localized list of keywords used to describe the entity 'Keywords' => [ 'en' => ['communication', 'federated session'], 'es' => ['comunicación', 'sesión federated'], ], : *Note*: The `+` (plus) character is forbidden by specification from being part of a Keyword. `Logo` : The logos used to represent the entity 'Logo' => [ [ 'url' => 'http://example.com/logo1.png', 'height' => 200, 'width' => 400, 'lang' => 'en', ], [ 'url' => 'http://example.com/logo2.png', 'height' => 201, 'width' => 401, ], ], : An optional `lang` key containing a language-code is supported for localized logos. DiscoHints Items -------------- These elements are only relevant when operating in the IdP role; they assist IdP discovery to determine when to choose or present an IdP. These properties are all children of the `DiscoHints` key. `IPHint` : This is a list of both IPv4 and IPv6 addresses in CIDR notation services by or associated with this entity. 'IPHint' => ['130.59.0.0/16', '2001:620::0/96'], `DomainHint` : This specifies a list of domain names serviced by or associated with this entity. 'DomainHint' => ['example.com', 'www.example.com'], `GeolocationHint` : This specifies a list of geographic coordinates associated with, or serviced by, the entity. Coordinates are given in URI form using the geo URI scheme [RFC5870](http://www.ietf.org/rfc/rfc5870.txt). 'GeolocationHint' => ['geo:47.37328,8.531126', 'geo:19.34343,12.342514'], Generated XML Metadata Examples ---------------- If given the following configuration... $metadata['https://www.example.com/saml/saml2/idp/metadata.php'] = [ 'host' => 'www.example.com', 'certificate' => 'example.com.crt', 'privatekey' => 'example.com.pem', 'auth' => 'example-userpass', 'UIInfo' => [ 'DisplayName' => [ 'en' => 'English name', 'es' => 'Nombre en Español', ], 'Description' => [ 'en' => 'English description', 'es' => 'Descripción en Español', ], 'InformationURL' => [ 'en' => 'http://example.com/info/en', 'es' => 'http://example.com/info/es', ], 'PrivacyStatementURL' => [ 'en' => 'http://example.com/privacy/en', 'es' => 'http://example.com/privacy/es', ], 'Keywords' => [ 'en' => ['communication', 'federated session'], 'es' => ['comunicación', 'sesión federated'], ], 'Logo' => [ [ 'url' => 'http://example.com/logo1.png', 'height' => 200, 'width' => 400, ], [ 'url' => 'http://example.com/logo2.png', 'height' => 201, 'width' => 401, ], ], ], 'DiscoHints' => [ 'IPHint' => ['130.59.0.0/16', '2001:620::0/96'], 'DomainHint' => ['example.com', 'www.example.com'], 'GeolocationHint' => ['geo:47.37328,8.531126', 'geo:19.34343,12.342514'], ], ]; ... will generate the following XML metadata: English name Nombre en Español English description Descripción en Español http://example.com/info/en http://example.com/info/es http://example.com/privacy/en http://example.com/privacy/es communication federated+session comunicación sesión+federated http://example.com/logo1.png http://example.com/logo2.png 130.59.0.0/16 2001:620::0/96 example.com www.example.com geo:47.37328,8.531126 geo:19.34343,12.342514 ... simplesamlphp-1.19.1/docs/README0000644000000000000000000000041214042503475014770 0ustar rootrootUpdated: January 15th, 2015 All you need to know to install and configure simpleSAMLphp is available at: https://simplesamlphp.org/docs/ simpleSAMLphp homepage: https://simplesamlphp.org/ simpleSAMLphp mailinglist (for support): https://simplesamlphp.org/lists simplesamlphp-1.19.1/docs/simplesamlphp-maintenance.md0000644000000000000000000003164014042503475021577 0ustar rootrootSimpleSAMLphp Maintenance ========================= SimpleSAMLphp news and documentation ------------------------------------ Please check the following sources of information to stay up to date with regard to SimpleSAMLphp: * [SimpleSAMLphp documentation](http://simplesamlphp.org/docs) * [SimpleSAMLphp homepage](https://simplesamlphp.org) * [SimpleSAMLphp mailing lists](https://simplesamlphp.org/lists) * [SimpleSAMLphp in twitter](https://twitter.com/simplesamlphp) ## Session management SimpleSAMLphp has an abstraction layer for session management. That means it is possible to choose between different kind of session stores, as well as write new session store plugins. The `store.type` configuration option in `config.php` allows you to select which method SimpleSAMLphp should use to store the session information. Currently, three session handlers are included in the distribution: * `phpsession` uses the built in session management in PHP. This is the default, and is simplest to use. It will not work in a load-balanced environment in most configurations. * `memcache` uses the memcache software to cache sessions in memory. Sessions can be distributed and replicated among several memcache servers, enabling both load-balancing and fail-over. * `sql` stores the session in an SQL database. * `redis` stores the session in Redis. 'store.type' => 'phpsession', ### Configuring PHP sessions To use the PHP session handler, set the `store.type` configuration option in `config.php`: 'store.type' => 'phpsession', Keep in mind that **PHP does not allow two sessions to be open at the same time**. This means if you are using PHP sessions both in your application and in SimpleSAMLphp at the same time, **they need to have different names**. When using the PHP session handler in SimpleSAMLphp, it is configured with different options than for other session handlers: 'session.phpsession.cookiename' => null, 'session.phpsession.savepath' => null, 'session.phpsession.httponly' => true, Make sure to set `session.phpsession.cookiename` to a name different than the one in use by any other applications. If you are using SimpleSAMLphp as an Identity Provider, or any other applications using it are not using the default session name, you can use the default settings by leaving these options unset or setting them to `null`. If you need to restore your session's application after calling SimpleSAMLphp, you can do it by calling the `cleanup()` method of the `\SimpleSAML\Session` class, like described [here](simplesamlphp-sp#section_6). ### Configuring memcache To use the memcache session handler, set the `store.type` parameter in `config.php`: 'store.type' => 'memcache', memcache allows you to store multiple redundant copies of sessions on different memcache servers. The configuration parameter `memcache_store.servers` is an array of server groups. Every data item will be mirrored in every server group. Each server group is an array of servers. The data items will be load-balanced between all servers in each server group. Each server is an array of parameters for the server. The following options are available: `hostname` : Host name or ip address where the memcache server runs, or specify other transports like *unix:///path/ssp.sock* to use UNIX domain sockets. In that case, port will be ignored and forced to *0*. This is the only required option. `port` : Port number of the memcache server. If not set, the `memcache.default_port` ini setting is used. This is 11211 by default. The port will be forced to *0* when a UNIX domain socket is specified in *hostname*. `weight` : Weight of this server in this server group. [http://php.net/manual/en/function.Memcache-addServer.php](http://php.net/manual/en/function.Memcache-addServer.php) has more information about the weight option. `timeout` : Timeout for this server. By default, the timeout is 3 seconds. Here are two examples of configuration of memcache session handling: **Example 1. Example of redundant configuration with load balancing** Example of redundant configuration with load balancing: This configuration makes it possible to lose both servers in the a-group or both servers in the b-group without losing any sessions. Note that sessions will be lost if one server is lost from both the a-group and the b-group. 'memcache_store.servers' => [ [ ['hostname' => 'mc_a1'], ['hostname' => 'mc_a2'], ], [ ['hostname' => 'mc_b1'], ['hostname' => 'mc_b2'], ], ], **Example 2. Example of simple configuration with only one memcache server** Example of simple configuration with only one memcache server, running on the same computer as the web server: Note that all sessions will be lost if the memcache server crashes. 'memcache_store.servers' => [ [ ['hostname' => 'localhost'], ], ], The expiration value (`memcache_store.expires`) is the duration for which data should be retained in memcache. Data are dropped from the memcache servers when this time expires. The time will be reset every time the data is written to the memcache servers. This value should always be larger than the `session.duration` option. Not doing this may result in the session being deleted from the memcache servers while it is still in use. Set this value to 0 if you don't want data to expire. #### Note The oldest data will always be deleted if the memcache server runs out of storage space. **Example 3. Example of configuration setting for session expiration** Here is an example of this configuration parameter: 'memcache_store.expires' => 36 * (60*60), // 36 hours. #### Memcache PHP configuration Configure memcache to not do internal failover. This parameter is configured in `php.ini`. memcache.allow_failover = Off #### Environmental configuration Setup a firewall restricting access to the memcache server. Because SimpleSAMLphp uses a timestamp to check which session is most recent in a fail-over setup, it is very important to run synchronized clocks on all web servers where you run SimpleSAMLphp. ### Configuring SQL storage To store session to a SQL database, set the `store.type` option to `sql`. SimpleSAMLphp uses [PDO](http://www.php.net/manual/en/book.pdo.php) when accessing the database server, so the database source is configured as with a DSN. The DSN is stored in the `store.sql.dsn` option. See the [PDO driver manual](http://www.php.net/manual/en/pdo.drivers.php) for the DSN syntax used by the different databases. Username and password for accessing the database can be configured in the `store.sql.username` and `store.sql.password` options. The required tables are created automatically. If you are storing data from multiple separate SimpleSAMLphp installations in the same database, you can use the `store.sql.prefix` option to prevent conflicts. ### Configuring Redis storage To store sessions in Redis, set the `store.type` option to `redis`. By default SimpleSAMLphp will attempt to connect to Redis on the `localhost` at port `6379`. These can be configured via the `store.redis.host` and `store.redis.port` options, respectively. You may also set a key prefix with the `store.redis.prefix` option. For Redis instances that [require authentication](https://redis.io/commands/auth), use the `store.redis.password` option. ## Metadata storage Several metadata storage backends are available by default, including `flatfile`, `serialize`, `mdq` and [`pdo`](https://simplesamlphp.org/docs/stable/simplesamlphp-metadata-pdostoragehandler). Here you have an example configuration of different metadata sources in use at the same time: ``` 'metadata.sources' => [ ['type' => 'flatfile'], ['type' => 'flatfile', 'directory' => 'metadata/metarefresh-kalmar'], ['type' => 'serialize', 'directory' => 'metadata/metarefresh-ukaccess'], ], ``` You may also implement your own metadata storage handler, in a very similar way to how you would implement your own session handler. Your class **must** extend the `\SimpleSAML\Metadata\MetaDataStorageSource` class and override the methods needed to change the backend used. This class **must** also be located in the `lib/MetadataStore/` directory of your custom module. Bear in mind that **your class name must follow the PSR-0 autoloading standard**. This means it needs to be named in a particular way, with the use of namespaces being the preferred convention. For example, if your module is named _mymodule_ and your class is named _MyMetadataHandler_, you should define it like this: ``` ['en', 'no', 'da', 'es', 'xx'], 'language.default' => 'en', Please use the standardized two-character [language codes as specified in ISO-639-1](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). You also can set the default language. You should ensure that the default language is complete, as it is used as a fallback when a text is not available in the language selected by the user. All strings that can be localized are found in the files `dictionaries/`. Add a new entry for each string, with your language code, like this: 'user_pass_header' => [ 'en' => 'Enter your username and password', 'no' => 'Skriv inn brukernavn og passord', 'xx' => 'Pooa jujjique jamba', ], You can translate as many of the texts as you would like; a full translation is not required unless you want to make this the default language. From the end users point of view, it looks best if all text fragments used in a given screen or form is in one single language. ## Customizing the web frontend with themes Documentation on theming is moved [to a separate document](simplesamlphp-theming). Support ------- If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are fortunate: Around SimpleSAMLphp there is a great Open source community, and you are welcome to join! The forums are open for you to ask questions, contribute answers other further questions, request improvements or contribute with code or plugins of your own. - [SimpleSAMLphp homepage](https://simplesamlphp.org) - [List of all available SimpleSAMLphp documentation](http://simplesamlphp.org/docs/) - [Join the SimpleSAMLphp user's mailing list](https://simplesamlphp.org/lists) simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.19.md0000644000000000000000000000135214042503475022455 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.19 ==================================== The minimum PHP version required is now PHP 7.1. SAML 1 / Shib 1.3 support is now deprecated and will start logging notices when used. It will be removed in SimpleSAMLphp 2.0. SimpleSAMLphp 1.19 will automatically try to determine whether to set the sameSite-flag on cookies. Some browser require to set the Secure-flag as well for sameSite to work. Therefore, the default for the `session.cookie.secure` setting has been changed to TRUE. This will be the right setting for most setups anyway, however if you really need to use insecure cookies, you have to manually set it to false and figure out a value for `session.cookie.samesite` that works for your environment. simplesamlphp-1.19.1/docs/simplesamlphp-idp.md0000644000000000000000000002504514042503475020073 0ustar rootrootSimpleSAMLphp Identity Provider QuickStart =========================================== This guide will describe how to configure SimpleSAMLphp as an identity provider (IdP). You should previously have installed SimpleSAMLphp as described in [the SimpleSAMLphp installation instructions](simplesamlphp-install) Enabling the Identity Provider functionality -------------------------------------------- The first that must be done is to enable the identity provider functionality. This is done by editing `config/config.php`. The option `enable.saml20-idp` controls whether SAML 2.0 IdP support is enabled. Enable it by assigning `true` to them: 'enable.saml20-idp' => true, Authentication module --------------------- The next step is to configure the way users authenticate on your IdP. Various modules in the `modules/` directory provides methods for authenticating your users. This is an overview of those that are included in the SimpleSAMLphp distribution: [`authcrypt:Hash`](./authcrypt:authcrypt) : Username & password authentication with hashed passwords. [`authcrypt:Htpasswd`](./authcrypt:authcrypt) : Username & password authentication against .htpasswd file. [`authX509:authX509userCert`](./authX509:authX509) : Authenticate against a LDAP database with a SSL client certificate. `exampleauth:UserPass` : Authenticate against a list of usernames and passwords. `exampleauth:Static` : Automatically log in as a user with a set of attributes. [`ldap:LDAP`](./ldap:ldap) : Authenticates an user to a LDAP server. [`ldap:LDAPMulti`](./ldap:ldap) : Authenticates an user to one of several LDAP server. The user can choose the LDAP server from a dropdown list. [`sqlauth:SQL`](./sqlauth:sql) : Authenticate an user against a database. [`radius:Radius`](./radius:radius) : Authenticates an user to a Radius server. [`InfoCard:ICAuth`](https://github.com/simplesamlphp/simplesamlphp-module-infocard/blob/master/README.md) : Authenticate with an InfoCard. [`multiauth:MultiAuth`](./multiauth:multiauth) : Allow the user to select from a list of authentication sources. `openid:OpenIDConsumer` : Authenticate against an OpenID provider. [`saml:SP`](./saml:sp) : Authenticate against a SAML IdP. Can be used for bridging. `authYubiKey:YubiKey` : Authenticate with [an YubiKey](http://www.yubico.com/products/yubikey/). [`authfacebook:Facebook`](./authfacebook:authfacebook) : Authenticate with a Facebook ID. [`authtwitter:Twitter`](./authtwitter:oauthtwitter) : Authenticate with your Twitter account using the Twitter OAuth API. [`papi:PAPI`](https://github.com/rediris-es/simplesamlphp-module-papi/blog/master/README.md) : Authenticate by means of the PAPI protocol. In this guide, we will use the `exampleauth:UserPass` authentication module. This module does not have any dependencies, and is therefore simple to set up. Configuring the authentication module ------------------------------------- The `exampleauth:UserPass` authentication module is part of the `exampleauth` module. This module isn't enabled by default, so you will have to enable it. This is done by creating a file named `enable` in `modules/exampleauth/`. On unix, this can be done by running (from the SimpleSAMLphp installation directory): touch modules/exampleauth/enable The next step is to create an authentication source with this module. An authentication source is an authentication module with a specific configuration. Each authentication source has a name, which is used to refer to this specific configuration in the IdP configuration. Configuration for authentication sources can be found in `config/authsources.php`. In this setup, this file should contain a single entry: [ 'exampleauth:UserPass', 'student:studentpass' => [ 'uid' => ['student'], 'eduPersonAffiliation' => ['member', 'student'], ], 'employee:employeepass' => [ 'uid' => ['employee'], 'eduPersonAffiliation' => ['member', 'employee'], ], ], ]; This configuration creates two users - `student` and `employee`, with the passwords `studentpass` and `employeepass`. The username and password are stored in the array index (`student:studentpass` for the `student`-user). The attributes for each user are configured in the array referenced by the index. So for the student user, these are: [ 'uid' => ['student'], 'eduPersonAffiliation' => ['member', 'student'], ], The attributes will be returned by the IdP when the user logs on. Creating a self signed certificate ---------------------------------- The IdP needs a certificate to sign its SAML assertions with. Here is an example of an `openssl`-command which can be used to generate a new private key key and the corresponding self-signed certificate. The private key and certificate go into the directory defined in the certdir setting (defaults to `cert/`) This key and certificate can be used to sign SAML messages: openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out example.org.crt -keyout example.org.pem The certificate above will be valid for 10 years. ### Note ### SimpleSAMLphp will only work with RSA certificates. DSA certificates are not supported. Configuring the IdP ------------------- The SAML 2.0 IdP is configured by the metadata stored in `metadata/saml20-idp-hosted.php`. This is a minimal configuration: '__DEFAULT__', /* * The private key and certificate to use when signing responses. * These are stored in the cert-directory. */ 'privatekey' => 'example.org.pem', 'certificate' => 'example.org.crt', /* * The authentication source which should be used to authenticate the * user. This must match one of the entries in config/authsources.php. */ 'auth' => 'example-userpass', ]; For more information about available options in the idp-hosted metadata files, see the [IdP hosted reference](simplesamlphp-reference-idp-hosted). Using the `uri` NameFormat on attributes ---------------------------------------- The [interoperable SAML 2 profile](https://kantarainitiative.github.io/SAMLprofiles/saml2int.html) specifies that attributes should be delivered using the `urn:oasis:names:tc:SAML:2.0:attrname-format:uri` NameFormat. We therefore recommended enabling this in new installations. This can be done by adding the following to the saml20-idp-hosted configuration: 'attributes.NameFormat' => 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri', 'authproc' => [ // Convert LDAP names to oids. 100 => ['class' => 'core:AttributeMap', 'name2oid'], ], Adding SPs to the IdP --------------------- The identity provider you are configuring needs to know about the service providers you are going to connect to it. This is configured by metadata stored in `metadata/saml20-sp-remote.php`. This is a minimal example of a `metadata/saml20-sp-remote.php` metadata file for a SimpleSAMLphp SP: 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'SingleLogoutService' => 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp', ]; Note that the URI in the entityID and the URLs to the AssertionConsumerService and SingleLogoutService endpoints change between different service providers. If you have the metadata of the remote SP as an XML file, you can use the built-in XML to SimpleSAMLphp metadata converter, which by default is available as `/admin/metadata-converter.php` in your SimpleSAMLphp installation. For more information about available options in the sp-remote metadata files, see the [SP remote reference](simplesamlphp-reference-sp-remote). Adding this IdP to other SPs ---------------------------- The method for adding this IdP to a SP varies between different types of SPs. In general, most SPs need some metadata from the IdP. This should be available from `/saml2/idp/metadata.php`. Testing the IdP --------------- The simplest way to test the IdP is to configure a SimpleSAMLphp SP on the same machine. See the instructions for [configuring SimpleSAMLphp as an SP](simplesamlphp-sp). ### Note ### When running a SimpleSAMLphp IdP and a SimpleSAMLphp SP on the same computer, the SP and IdP **MUST** be configured with different hostnames. This prevents cookies from the SP to interfere with cookies from the IdP. Support ------- If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are fortunate: Around SimpleSAMLphp there is a great Open source community, and you are welcome to join! The forums are open for you to ask questions, contribute answers other further questions, request improvements or contribute with code or plugins of your own. - [SimpleSAMLphp homepage](https://simplesamlphp.org) - [List of all available SimpleSAMLphp documentation](https://simplesamlphp.org/docs/) - [Join the SimpleSAMLphp user's mailing list](https://simplesamlphp.org/lists) A. IdP-first setup ------------------ If you do not want to start the SSO flow at the SP, you may use the IdP-first setup. To do this, redirect the user to the SSOService endpoint on the IdP with one parameter `spentityid` that match the SP EntityId that the user should be logged into. Here is an example of such a URL: https://idp.example.org/simplesaml/saml2/idp/SSOService.php?spentityid=sp.example.org If the SP is a SimpleSAMLphp SP, you must also specify a `RelayState` parameter for the SP. This must be set to a URL the user should be redirected to after authentication. The `RelayState` parameter can be specified in the [SP configuration](./saml:sp), or it can be sent from the IdP. To send the RelayState parameter from a SimpleSAMLphp IdP, specify it in the query string to SSOService.php: https://idp.example.org/simplesaml/saml2/idp/SSOService.php?spentityid=sp.example.org&RelayState=https://sp.example.org/welcome.php To set it in the SP configuration, add it to `authsources.php`: 'default-sp' => [ 'saml:SP', 'RelayState' => 'https://sp.example.org/welcome.php', ], simplesamlphp-1.19.1/docs/simplesamlphp-customauth.md0000644000000000000000000003354014042503475021512 0ustar rootrootImplementing custom username/password authentication ==================================================== This is a step-by-step guide for creating a custom username/password [authentication source](./simplesamlphp-authsource) for SimpleSAMLphp. An authentication source is responsible for authenticating the user, typically by getting a username and password, and looking it up in some sort of database. Create a custom module ---------------------- All custom code for SimpleSAMLphp should be contained in a [module](./simplesamlphp-modules). This ensures that you can upgrade your SimpleSAMLphp installation without overwriting your own code. In this example, we will call the module `mymodule`. It will be located under `modules/mymodule`. First we need to create the module directory: cd modules mkdir mymodule Since this is a custom module, it should always be enabled. Therefore we create a `default-enable` file in the module. We do that by copying the `default-enable` file from the `core` module. cd mymodule cp ../core/default-enable . Now that we have our own module, we can move on to creating an authentication source. Creating a basic authentication source -------------------------------------- Authentication sources are implemented using PHP classes. We are going to create an authentication source named `mymodule:MyAuth`. It will be implemented in the file `modules/mymodule/lib/Auth/Source/MyAuth.php`. To begin with, we will create a very simple authentication source, where the username and password is hardcoded into the source code. Create the file `modules/mymodule/lib/Auth/Source/MyAuth.php` with the following contents: ['theusername'], 'displayName' => ['Some Random User'], 'eduPersonAffiliation' => ['member', 'employee'], ]; } } Some things to note: - The classname is `\SimpleSAML\Module\mymodule\Auth\Source\MyAuth`. This tells SimpleSAMLphp to look for the class in `modules/mymodule/lib/Auth/Source/MyAuth.php`. - Our authentication source subclasses `\SimpleSAML\Module\core\Auth\UserPassBase`. This is a helper-class that implements much of the common code needed for username/password authentication. - The `login` function receives the username and password the user enters. It is expected to authenticate the user. If the username or password is correct, it must return a set of attributes for the user. Otherwise, it must throw the `\SimpleSAML\Error\Error('WRONGUSERPASS');` exception. - Attributes are returned as an associative array of `name => values` pairs. All attributes can have multiple values, so the values are always stored in an array. Configuring our authentication source ------------------------------------- Before we can test our authentication source, we must add an entry for it in `config/authsources.php`. `config/authsources.php` contains an list of enabled authentication sources. The entry looks like this: 'myauthinstance' => [ 'mymodule:MyAuth', ], You can add it to the beginning of the list, so that the file looks something like this: [ 'mymodule:MyAuth', ], /* Other authentication sources follow. */ ]; `myauthinstance` is the name of this instance of the authentication source. (You are allowed to have multiple instances of an authentication source with different configuration.) The instance name is used to refer to this authentication source in other configuration files. The first element of the configuration of the authentication source must be `'mymodule:MyAuth'`. This tells SimpleSAMLphp to look for the `\SimpleSAML\Module\mymodule\Auth\Source\MyAuth` class. Testing our authentication source --------------------------------- Now that we have configured the authentication source, we can test it by accessing "authentication"-page of the SimpleSAMLphp web interface. By default, the web interface can be found on `http://yourhostname.com/simplesaml/`. (Obviously, "yourhostname.com" should be replaced with your real hostname.) Then select the "Authentication"-tab, and choose "Test configured authentication sources". You should then receive a list of authentication sources from `config/authsources.php`. Select `myauthinstance`, and log in using "theusername" as the username, and "thepassword" as the password. You should then arrive on a page listing the attributes we return from the `login` function. Next, you should log out by following the log out link. Using our authentication source in an IdP ----------------------------------------- To use our new authentication source in an IdP we just need to update the IdP configuration to use it. Open `metadata/saml20-idp-hosted.php`. In that file you should locate the `auth`-option for your IdP, and change it to `myauthinstance`: 'myauthinstance', /* ... */ ]; You can then test logging in to the IdP. If you have logged in previously, you may need to log out first. Adding configuration to our authentication source ------------------------------------------------- Instead of hardcoding options in our authentication source, they should be configurable. We are now going to extend our authentication source to allow us to configure the username and password in `config/authsources.php`. First, we need to define the properties in the class that should hold our configuration: private $username; private $password; Next, we create a constructor for the class. The constructor is responsible for parsing the configuration and storing it in the properties. public function __construct($info, $config) { parent::__construct($info, $config); if (!is_string($config['username'])) { throw new Exception('Missing or invalid username option in config.'); } $this->username = $config['username']; if (!is_string($config['password'])) { throw new Exception('Missing or invalid password option in config.'); } $this->password = $config['password']; } We can then use the properties in the `login` function. The complete class file should look like this: username = $config['username']; if (!is_string($config['password'])) { throw new Exception('Missing or invalid password option in config.'); } $this->password = $config['password']; } protected function login($username, $password) { if ($username !== $this->username || $password !== $this->password) { throw new \SimpleSAML\Error\Error('WRONGUSERPASS'); } return [ 'uid' => [$this->username], 'displayName' => ['Some Random User'], 'eduPersonAffiliation' => ['member', 'employee'], ]; } } We can then update our entry in `config/authsources.php` with the configuration options: 'myauthinstance' => [ 'mymodule:MyAuth', 'username' => 'theconfigusername', 'password' => 'theconfigpassword', ], Next, you should go to the "Test configured authentication sources" page again, and test logging in. Note that we have updated the username & password to "theconfigusername" and "theconfigpassword". (You may need to log out first before you can log in again.) A more complete example - custom database authentication -------------------------------------------------------- The [sqlauth:SQL](./sqlauth:sql) authentication source can do simple authentication against SQL databases. However, in some cases it cannot be used, for example because the database layout is too complex, or because the password validation routines cannot be implemented in SQL. What follows is an example of an authentication source that fetches an user from a database, and validates the password using a custom function. This code assumes that the database contains a table that looks like this: CREATE TABLE userdb ( username VARCHAR(32) PRIMARY KEY NOT NULL, password_hash VARCHAR(64) NOT NULL, full_name TEXT NOT NULL); An example user (with password "secret"): INSERT INTO userdb (username, password_hash, full_name) VALUES('exampleuser', 'QwVYkvlrAMsXIgULyQ/pDDwDI3dF2aJD4XeVxg==', 'Example User'); In this example, the `password_hash` contains a base64 encoded SSHA password. A SSHA password is created like this: $password = 'secret'; $numSalt = 8; /* Number of bytes with salt. */ $salt = ''; for ($i = 0; $i < $numSalt; $i++) { $salt .= chr(mt_rand(0, 255)); } $digest = sha1($password . $salt, TRUE); $password_hash = base64_encode($digest . $salt); The class follows: dsn = $config['dsn']; if (!is_string($config['username'])) { throw new Exception('Missing or invalid username option in config.'); } $this->username = $config['username']; if (!is_string($config['password'])) { throw new Exception('Missing or invalid password option in config.'); } $this->password = $config['password']; if (isset($config['options']) { if (!is_array($config['options])) { throw new Exception('Missing or invalid options option in config.'); } $this->options = $config['options']; } } /** * A helper function for validating a password hash. * * In this example we check a SSHA-password, where the database * contains a base64 encoded byte string, where the first 20 bytes * from the byte string is the SHA1 sum, and the remaining bytes is * the salt. */ private function checkPassword($passwordHash, $password) { $passwordHash = base64_decode($passwordHash); $digest = substr($passwordHash, 0, 20); $salt = substr($passwordHash, 20); $checkDigest = sha1($password . $salt, TRUE); return $digest === $checkDigest; } protected function login($username, $password) { /* Connect to the database. */ $db = new PDO($this->dsn, $this->username, $this->password, $this->options); $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(['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 = [ 'uid' => [$username], 'displayName' => [$row['full_name']], 'eduPersonAffiliation' => ['member', 'employee'], ]; /* Return the attributes. */ return $attributes; } } And configured in `config/authsources.php`: 'myauthinstance' => [ 'mymodule:MyAuth', 'dsn' => 'mysql:host=sql.example.org;dbname=userdatabase', 'username' => 'db_username', 'password' => 'secret_db_password', ], simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.15.md0000644000000000000000000000305314042503475022451 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.15 ==================================== The minimum required PHP version is now 5.4. The dependency on mcrypt has been dropped. A new templating system based on Twig has been introduced. The old templating system is still available but should be considered deprecated. Custom themes may need to be updated to include Twig-style templates as well. See the [theming documentation](simplesamlphp-theming). A new internationalization system based on Gettext has been introduced. While old templates can use either the old or the new system (refer to the "language.i18n.backend" configuration option for more information on how to choose the internationalization backend), new Twig templates can only use the new Gettext internationalization system. The integrated _Auth Memcookie_ support is now deprecated and will no longer be available starting in SimpleSAMLphp 2.0. Please use the new [memcookie module](https://github.com/simplesamlphp/simplesamlphp-module-memcookie) instead. The option to specify a SAML certificate by its fingerprint, `certFingerprint` has been deprecated and will be removed in a future release. Please use the full certificate in `certData` instead. The `core:AttributeRealm` authproc filter has been deprecated. Please use `core:ScopeFromAttribute`, which is a generalised version of this. simpleSAMLphp will now send the eduPersonTargetedID attribute in the correct NameID XML form, instead of the incorrect simple string. It will also refuse to parse an assertion with an eduPersonTargetedID in 'string' format. simplesamlphp-1.19.1/docs/simplesamlphp-hok-idp.md0000644000000000000000000000710314042503475020645 0ustar rootrootAdding Holder-of-Key Web Browser SSO Profile support to the IdP =============================================================== This document describes the necessary steps to enable support for the [SAML V2.0 Holder-of-Key (HoK) Web Browser SSO Profile](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-holder-of-key-browser-sso.pdf) on a SimpleSAMLphp Identity Provider (IdP). The SAML V2.0 HoK Web Browser SSO Profile is an alternate version of the standard SAML Web Browser SSO Profile. Its primary benefit is the enhanced security of the SSO process while preserving maximum compatibility with existing deployments on client and server side. When using this profile the communication between the user and the IdP is required to be protected by the TLS protocol. Additionally, the user needs a TLS client certificate. This certificate is usually selfsigned and stored in the certificate store of the browser or the underlying operating system. Configuring Apache ------------------ The IdP requests a client certificate from the user agent during the TLS handshake. This behaviour is enabled with the following Apache webserver configuration: SSLEngine on SSLCertificateFile /etc/openssl/certs/server.crt SSLCertificateKeyFile /etc/openssl/private/server.key SSLVerifyClient optional_no_ca SSLOptions +ExportCertData If the user agent can successfully prove possession of the private key associated to the public key from the certificate, the received certificate is stored in the environment variable `SSL_CLIENT_CERT` of the webserver. The IdP embeds the client certificate into the created HoK assertion. Enabling HoK SSO Profile on the IdP ----------------------------------- To enable the IdP to send HoK assertions you must add the `saml20.hok.assertion` option to the `saml20-idp-hosted` metadata file: $metadata['__DYNAMIC:1__'] = [ [....] 'auth' => 'example-userpass', 'saml20.hok.assertion' => TRUE, ]; Add new metadata to SPs ----------------------- After enabling the Holder-of-Key Web Browser SSO Profile your IdP metadata will change. An additional HoK `SingleSignOnService` endpoint is added. You therefore need to update the metadata for your IdP at your SPs. The `saml20-idp-remote` metadata for SimpleSAMLphp SPs should contain something like the following code: 'SingleSignOnService' => array ( array ( 'hoksso:ProtocolBinding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser', 'Location' => 'https://idp.example.org/simplesaml/saml2/idp/SSOService.php', ), array ( 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'Location' => 'https://idp.example.org/simplesaml/saml2/idp/SSOService.php', ), ), SP metadata on the IdP ---------------------- A SP using the HoK Web Browser SSO Profile must have an `AssertionConsumerService` endpoint supporting that profile. This means that you have to use the complex endpoint format in `saml20-sp-remote` metadata. In general, this should look like the following code: 'AssertionConsumerService' => array ( [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Location' => 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'index' => 0, ], [ 'Binding' => 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser', 'Location' => 'https://sp.example.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp', 'index' => 4, ], ), (The specific values of the various fields will vary depending on the SP.) simplesamlphp-1.19.1/docs/simplesamlphp-reference-sp-remote.md0000644000000000000000000004170214042503475023164 0ustar rootrootSP remote metadata reference ============================ This is a reference for metadata options available for `metadata/saml20-sp-remote.php` and `metadata/shib13-sp-remote.php`. Both files have the following format: [ 'en' => 'A service', 'no' => 'En tjeneste', ], `OrganizationName` : The name of the organization responsible for this SPP. This name does not need to be suitable for display to end users. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated name: 'OrganizationName' => [ 'en' => 'Example organization', 'no' => 'Eksempel organisation', ], : *Note*: If you specify this option, you must also specify the `OrganizationURL` option. `OrganizationDisplayName` : The name of the organization responsible for this IdP. This name must be suitable for display to end users. If this option isn't specified, `OrganizationName` will be used instead. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated name. : *Note*: If you specify this option, you must also specify the `OrganizationName` option. `OrganizationURL` : A URL the end user can access for more information about the organization. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL. : *Note*: If you specify this option, you must also specify the `OrganizationName` option. `privacypolicy` : This is an absolute URL for where an user can find a privacypolicy for this SP. If set, this will be shown on the consent page. `%SPENTITYID%` in the URL will be replaced with the entity id of this service provider. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option in the IdP-hosted metadata. : *Note*: **deprecated** Will be removed in a future release; use the MDUI-extension instead `userid.attribute` : The attribute name of an attribute which uniquely identifies the user. This attribute is used if SimpleSAMLphp needs to generate a persistent unique identifier for the user. This option can be set in both the IdP-hosted and the SP-remote metadata. The value in the SP-remote metadata has the highest priority. The default value is `eduPersonPrincipalName`. SAML 2.0 options ---------------- The following SAML 2.0 options are available: `AssertionConsumerService` : The URL of the AssertionConsumerService endpoint for this SP. This option is required - without it you will not be able to send responses back to the SP. : The value of this option is specified in one of several [endpoint formats](./simplesamlphp-metadata-endpoints). `attributeencodings` : What encoding should be used for the different attributes. This is an array which maps attribute names to attribute encodings. There are three different encodings: : - `string`: Will include the attribute as a normal string. This is the default. : - `base64`: Store the attribute as a base64 encoded string. This is the default when the `base64attributes`-option is set to `TRUE`. : - `raw`: Store the attribute without any modifications. This makes it possible to include raw XML in the response. `attributes.NameFormat` : What value will be set in the Format field of attribute statements. This parameter can be configured multiple places, and the actual value used is fetched from metadata by the following priority: : 1. SP Remote Metadata 2. IdP Hosted Metadata : The default value is: `urn:oasis:names:tc:SAML:2.0:attrname-format:basic` : Some examples of values specified in the SAML 2.0 Core Specification: : - `urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified` - `urn:oasis:names:tc:SAML:2.0:attrname-format:uri` (The default in Shibboleth 2.0) - `urn:oasis:names:tc:SAML:2.0:attrname-format:basic` (The default in Sun Access Manager) : You can also define your own value. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option in the IdP-hosted metadata. : (This option was previously named `AttributeNameFormat`.) `audience` : An array of additional entities to be added to the AudienceRestriction. By default the only audience is the SP's entityID. `certData` : The base64 encoded certificate for this SP. This is an alternative to storing the certificate in a file on disk and specifying the filename in the `certificate`-option. `certificate` : Name of certificate file for this SP. The certificate is used to verify the signature of messages received from the SP (if `redirect.validate`is set to `TRUE`), and to encrypting assertions (if `assertion.encryption` is set to TRUE and `sharedkey` is unset.) `encryption.blacklisted-algorithms` : Blacklisted encryption algorithms. This is an array containing the algorithm identifiers. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option in the [IdP-hosted metadata](./simplesamlphp-reference-idp-hosted). : The RSA encryption algorithm with PKCS#1 v1.5 padding is blacklisted by default for security reasons. Any assertions encrypted with this algorithm will therefore fail to decrypt. You can override this limitation by defining an empty array in this option (or blacklisting any other algorithms not including that one). However, it is strongly discouraged to do so. For your own safety, please include the string 'http://www.w3.org/2001/04/xmlenc#rsa-1_5' if you make use of this option. `ForceAuthn` : Set this `TRUE` to force the user to reauthenticate when the IdP receives authentication requests from this SP. The default is `FALSE`. `NameIDFormat` : The `NameIDFormat` this SP should receive. This may be specified as either a string or an array. : The three most commonly used values are: : 1. `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` 2. `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` 3. `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` : The `transient` format will generate a new unique ID every time the SP logs in. : To properly support the `persistent` and `emailAddress` formats, you should configure [NameID generation filters](./saml:nameid) on your IdP. `nameid.encryption` : Whether NameIDs sent to this SP should be encrypted. The default value is `FALSE`. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option in the [IdP-hosted metadata](./simplesamlphp-reference-idp-hosted). `saml20.sign.response` : Whether `` messages should be signed. Defaults to `TRUE`. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. `saml20.sign.assertion` : Whether `` elements should be signed. Defaults to `TRUE`. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. `signature.algorithm` : The algorithm to use when signing any message sent to this specific service provider. Defaults to RSA-SHA256. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. : Possible values: * `http://www.w3.org/2000/09/xmldsig#rsa-sha1` *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future. * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256` The default. * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384` * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512` `signature.privatekey` : Name of private key file for this IdP, in PEM format. The filename is relative to the cert/-directory. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option `privatekey` in the IdP-hosted metadata. `signature.privatekey_pass` : Passphrase for the private key. Leave this option out if the private key is unencrypted. : Note that this option only is used if `signature.privatekey` is present. `signature.certificate` : Certificate file included by IdP for KeyInfo within the signature for the SP, in PEM format. The filename is relative to the cert/-directory. : If `signature.privatekey` is present and `signature.certificate` is left blank, X509Certificate will not be included with the signature. `sign.logout` : Whether to sign logout messages sent to this SP. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. `simplesaml.nameidattribute` : When the value of the `NameIDFormat`-option is set to either `email` or `persistent`, this is the name of the attribute which should be used as the value of the `NameID`. The attribute must be in the set of attributes exported to the SP (that is, be in the `attributes` array). For more advanced control over `NameID`, including the ability to specify any attribute regardless of the set sent to the SP, see the [NameID processing filters](./saml:nameid). Note that the value of the attribute is collected **after** authproc-filters have run. : Typical values can be `mail` for when using the `email` format, and `eduPersonTargetedID` when using the `persistent` format. `simplesaml.attributes` : Whether the SP should receive any attributes from the IdP. The default value is `TRUE`. `SingleLogoutService` : The URL of the SingleLogoutService endpoint for this SP. This option is required if you want to implement single logout for this SP. If the option isn't specified, this SP will not be logged out automatically when a single logout operation is initialized. : The value of this option is specified in one of several [endpoint formats](./simplesamlphp-metadata-endpoints). `SingleLogoutServiceResponse` : The URL logout responses to this SP should be sent. If this option is unspecified, the `SingleLogoutService` endpoint will be used as the recipient of logout responses. `SPNameQualifier` : SP NameQualifier for this SP. If not set, the IdP will set the SPNameQualifier to be the SP entity ID. `validate.authnrequest` : Whether we require signatures on authentication requests sent from this SP. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. `validate.logout` : Whether we require signatures on logout messages sent from this SP. : Note that this option also exists in the IdP-hosted metadata. The value in the SP-remote metadata overrides the value in the IdP-hosted metadata. ### Encrypting assertions It is possible to encrypt the assertions sent to a SP. Currently the only algorithm supported is `AES128_CBC` or `RIJNDAEL_128`. There are two modes of encryption supported by SimpleSAMLphp. One is symmetric encryption, in which case both the SP and the IdP needs to share a key. The other mode is the use of public key encryption. In that mode, the public key of the SP is extracted from the certificate of the SP. `assertion.encryption` : Whether assertions sent to this SP should be encrypted. The default value is `FALSE`. : Note that this option also exists in the IdP-hosted metadata. This entry in the SP-remote metadata overrides the option in the IdP-hosted metadata. `sharedkey` : Symmetric key which should be used for encryption. This should be a 128-bit, 192-bit or 256-bit key based on the algorithm used. If this option is not specified, public key encryption will be used instead. `sharedkey_algorithm` : Algorithm which should be used for encryption. Possible values are: * http://www.w3.org/2001/04/xmlenc#aes128-cbc * http://www.w3.org/2001/04/xmlenc#aes192-cbc * http://www.w3.org/2001/04/xmlenc#aes256-cbc * http://www.w3.org/2009/xmlenc11#aes128-gcm * http://www.w3.org/2009/xmlenc11#aes192-gcm * http://www.w3.org/2009/xmlenc11#aes256-gcm ### Fields for signing and validating messages SimpleSAMLphp only signs authentication responses by default. Signing of logout requests and logout responses can be enabled by setting the `redirect.sign` option. Validation of received messages can be enabled by the `redirect.validate` option. These options overrides the options set in `saml20-idp-hosted`. `redirect.sign` : Whether logout requests and logout responses sent to this SP should be signed. The default is `FALSE`. `redirect.validate` : Whether authentication requests, logout requests and logout responses received from this SP should be validated. The default is `FALSE` **Example: Configuration for validating messages** 'redirect.validate' => TRUE, 'certificate' => 'example.org.crt', ### Fields for scoping Only relevant if you are a proxy/bridge and wants to limit the idps this sp can use. `IDPList` : The list of scoped idps ie. the list of entityids for idps that are relevant for this sp. The final list is the concatenation of the list given as parameter to InitSSO (at the sp), the list configured at the sp and the list configured at the ipd (here) for this sp. The intersection of the final list and the idps configured at the at this idp will be presented to the user at the discovery service if neccessary. If only one idp is in the intersection the discoveryservice will go directly to the idp. **Example: Configuration for scoping** 'IDPList' => ['https://idp1.wayf.dk', 'https://idp2.wayf.dk'], Shibboleth 1.3 options ---------------------- Note that Shibboleth 1.3 support is deprecated and will be removed in the next major release of SimpleSAMLphp. The following options for Shibboleth 1.3 SP's are avaiblable: `audience` : The value which should be given in the ``-element in the ``-element in the response. The default value is the entity ID of the SP. `AssertionConsumerService` : The URL of the AssertionConsumerService endpoint for this SP. This endpoint must accept the SAML responses encoded with the `urn:oasis:names:tc:SAML:1.0:profiles:browser-post` encoding. This option is required - without it you will not be able to send responses back to the SP. : The value of this option is specified in one of several [endpoint formats](./simplesamlphp-metadata-endpoints). `NameQualifier` : What the value of the `NameQualifier`-attribute of the ``-element should be. The default value is the entity ID of the SP. `scopedattributes` : Array with names of attributes which should be scoped. Scoped attributes will receive a `Scope`-attribute on the `AttributeValue`-element. The value of the Scope-attribute will be taken from the attribute value: : `someuser@example.org` : will be transformed into : `someuser` : By default, no attributes are scoped. This option overrides the option with the same name in the `shib13-idp-hosted.php` metadata file. simplesamlphp-1.19.1/docs/simplesamlphp-nostate.md0000644000000000000000000001556714042503475021004 0ustar rootrootDebugging "State Information Lost" errors ========================================= **"State Information Lost"** (`\SimpleSAML\Error\NoState: NOSTATE`) This is one of the most common errors that you can encounter when configuring SimpleSAMLphp. Unfortunately, it is also a generic error that can have many possible causes. This document will attempt to describe what this error actually means, and some of the situations that can cause it. What is "state information"? ---------------------------- The "state information" is data that SimpleSAMLphp stores in association with a request. The request is typically a SAML 2.0 authentication request sent to the IdP, but it can also be other requests. This state information is given a random ID, e.g. "`_2da56e07840b59191d9797442b6b665d67d855cf77`", and is saved in the session of the user. What does it mean that it was lost? ----------------------------------- This means that we tried to load state information with a specified ID, but were unable to find it in the session of the user. What can cause it to be lost? ----------------------------- There are several ways that this can happen, but most of them have to do with session storage. Here we will outline some generic alternatives, and possible solutions. ### The domain name changed during authentication The domain name the IdP sends the response to is configured in the metadata of the IdP. This means that it may not match up with the domain name the user accessed. For example we may have the following scenario: 1. The user accesses `https://www.example.org/`. A session is created for the user, and the session cookie is set for the current domain (www.example.org). 1. The user needs to be authenticated. We therefore save some information about the current status in the state array, create a SAML 2.0 authentication request, and send it to the IdP. 1. The user logs in on the IdP. The IdP then sends a response to the SP at `example.org`. However, the metadata for the SP that is registered at the IdP uses `https://example.org/` (without `www`) as the domain the response should be sent to. The authentication response is therefore sent to that domain. 1. The SP (now at `https://example.org/`) tries to load the state information associated with the authentication response it received. But, because the domain name has changed, we do not receive the session cookie of the user. We are therefore unable to find the session of the user. When we attempt to load the state information from the session we are therefore unable to find it. There are several ways to solve this. One of the simplest is often to configure your webserver to only use one domain, and redirect all accesses to the other domain to the correct domain. A different solution is to change the session cookie settings, so that they are set for the "`example.org`" domain. If you are using PHP sessions, you should change this in `php.ini`. If not, you should change it with the '`session.cookie.domain`' option in `config/config.php`. In either case, it should be set to the top-level domain with a "dot" in front of it. E.g.: 'session.cookie.domain' => '.example.org', Or in php.ini: session.cookie_domain = ".example.org" Note that if you use PHP sessions, you will also have to make sure that your application uses the same domain when it sets the cookie. How that is done depends on your application. (See the section about mismatch between application PHP session settings and SimpleSAMLphp session settings.) ### Hopping between http and https If a cookie is set during a HTTPS session, it is not available when the same URL is later accessed over http. If your site is available over both http and https, check that you're using https consistently throughout the configuration. The best and most secure is to make your complete site available on https only, and redirect any http requests to https. ### Mismatch between PHP session settings for the application and SimpleSAMLphp If both the application you are trying to add SAML 2.0 support to and SimpleSAMLphp uses PHP session for session storage, and they don't agree on all the parameters, you can end up with this error. By default, SimpleSAMLphp uses the settings from `php.ini`, but these can be overridden in `config/config.php`. If this is the cause of your error, you have two choices: either change SimpleSAMLphp to use a different session storage method (e.g. memcache or sql), or change the session settings to match between the application and SimpleSAMLphp. In many cases it is simplest to adjust the session storage. If you decide to make the session settings match, you should change the settings in `php.ini`. This is to make sure that the settings apply to everything that uses the default settings. The following options in `php.ini` must match the settings used by the application: * `session.save_handler`: This is the method that is used to store the session. The default is "`files`". * `session.save_path`: This is the location the session files are saved. The default depends on your PHP installation. * `session.name`: This is the name of the session cookie. The default is "`PHPSESSID`". * `session.cookie_path`: The path that the session cookie is limited to. The default is "`/`", which means that it is available to all pages on your domain. * `session.cookie_domain`: This is the domain the session cookie is limited to. The default is unset, which makes the cookie available only to the current domain. What those settings should be set to depends on the application. The simplest way to determine it may be to look for calls to `session_set_cookie_params` in the application, and look at what parameters it uses. ### Browsers with SameSite=Lax as default Some browsers, notably Chrome, will default the cookie SameSite attribute to "Lax" if it is not set. Specifically in the context of SAML this means that cookies will not be sent when a POST request is performed between websites, which is typical for the SAML WebSSO flow. The lack of cookies will cause SimpleSAMLphp's session to be lost when receiving an assertion via the HTTP-POST binding. To resolve this, you can set the `session.cookie.samesite` attribute in `config.php` to `None`. Starting with SimpleSAMLphp 1.19, the config template contains a way to set this dynamically based on the user's browser support for this attribute. ### A generic problem saving sessions Sometimes the problem is caused by SimpleSAMLphp being unable to load and/or save sessions. This can be caused by the session settings being incorrect, or by a failure of some service required by the session storage. For example, if you are using memcache for session storage, you need to ensure that the memcache server is running and that the web server is able to connect to it. The same applies if you are saving the sessions to a SQL database. You may want to check your web server error log. If the PHP session handler fails, it may log an error message there. simplesamlphp-1.19.1/docs/simplesamlphp-changelog.md0000644000000000000000000025665014042503475021256 0ustar rootrootSimpleSAMLphp changelog ======================= This document lists the changes between versions of SimpleSAMLphp. See the upgrade notes for specific information about upgrading. ## Version 1.19.1 Released 2021-04-29 * Added authproc-filters for generating the subject-id and pairwise-id (#1435) * Restore support for custom error messages (#1326) * Fixed a bug in the Artifact Resolution Service (#1428) * Fixed compatibility with Composer pre 1.8.5 (Debian 10) (#1427) * Updated npm dependencies up to April 23, 2021 * Fixed a bug where it was impossible to set WantAssertionsSigned=true on SP-metadata (#1433) * Make inResponseTo available in state array (#1447) ### admin * Fixed a bug in the metadata-coverter where the coverted metadata would contain newline-characters ### authorize * Fix a bug in the Twig-template that causes an exception in Twig strict vars mode ### memcacheMonitor * Fix a bug in the Twig-template that causes an exception on newer Twig-versions ### negotiate * Fix a bug that was breaking the module when using the old UI ### statistics * Fix a bug in the Twig-template that causes an exception on newer Twig-versions ### sqlauth * Fix a security bug where in rare cases the database user credentials would be printed in exception messages ## Version 1.19.0 Released 2021-01-21 * This version will be the last of the 1.x branch and will provide a migration path to our new templating system, routing system and translation system. * SAML 1 / Shib 1.3 support is now marked deprecated and will be removed in SimpleSAMLphp 2.0. * Raised minimum PHP version to 7.1 * Dropped support for Symfony 3.x * Update the SAML2 library dependency to 4.1.9 * Fix a bug where SSP wouldn't write to the tmp-directory if it didn't own it, but could write to it (#1314) * Fixed several bugs in saml:NameIDAttribute (#1245) * Fix artifact resolution (#1343) * Allow additional audiences to be specified (#1345) * Allow configurable ProviderName (#1348) * Support saml:Extensions in saml:SP authsources (#1349) * The `attributename`-setting in the core:TargetedID authproc-filter has been deprecated in favour of the `identifyingAttribute`-setting. * Filter multiauth authentication sources from SP using AuthnContextClassRef (#1362) * Allow easy enabling of SameSite = 'None' (#1382) * Do not accept the hashed admin password for authentication (#1418) ## Version 1.18.8 Released 2020-09-02 * Fixed Artifact Resolution due to incorrect use of Issuer objects (#1343). * Fixed some of the German translations (#1331). Thanks @htto! * Harden against CVE-2020-13625; this package is not affected, but 3rd party modules may (#1333). * Harden against sevaral JS issues (npm update & npm audit fix) * Fixed inconsistent configuration of backtraces logging * Support for Symfony 3.x is now deprecated * Support for Twig 1.x is now deprecated ### authcrypt * The dependency for whitehat101/apr1-md5 was moved from the base repository to the module (v0.9.2) ### authx509 * Restore PHP 5.6 compatibility (v0.9.5) ### cron * Fixed old-ui (#1248) ### ldap * Moved array with binary attributes to authsource config (v0.9.9) Instead of having to edit code, you can now set 'attributes.binary' in the authsource configuration. ### metarefresh * Add attributewhitelist to support e.g. R&S+Sirtfi (v0.9.5) * Restore PHP 5.6 compatibility (v0.9.6) ### negotiate ### * Restore PHP 5.6 compatibility (v0.9.8) * Fixed a link (v0.9.9) ### saml2 library * Fixed a bug in the AuthnRequest-class that would raise an InvalidArgumentException when setting the AssertionConsumerServiceIndex as an integer on an saml:SP authsource. Thanks to Andrea @ Oracle for reporting this. ## Version 1.18.7 Released 2020-05-12 * Fix spurious warnings when session_create_id() fails to create ID (#1291) * Fix inconsistency in the way PATH_INFO is being used (#1227). * Fix a potential security issue [CVE-2020-11022](https://nvd.nist.gov/vuln/detail/CVE-2020-11022) by updating jQuery. If any of your custom modules rely on jQuery, make sure you read the following [update notes](https://jquery.com/upgrade-guide/3.5/), since jQuery has solved this in a non-BC way (#1321). * Fix incorrect Polish translations (#1311). * Fix a broken migration query in the LogoutStore (#1324). * Fix an issue with the SameSite cookie parameter when running on PHP versions older than 7.3 (#1320). ### adfs * Fixed a broken link to one of the assets (v0.9.6). ### ldap * Handle binary attributes in a generic way (v0.9.5). ### oauth * Fix PHP 7.4 incompatibility (v0.9.2). ### preprodwarning * Fix Dutch translations (v0.9.2). ### sanitycheck * Fix broken HTML (v0.9.1). ### saml * Fix several issues in the saml:NameIDAttribute authproc filter (#1325). ### saml2 library * fixed a standards compliance issue regarding ContactPerson EMail addresses (v3.4.4). * fixed an issue parsing very large metadata files (v3.4.3). ## Version 1.18.6 Released 2020-04-17 * Fix source code disclosure on case-insensitive file systems. See [SSPSA 202004-01](https://simplesamlphp.org/security/202004-01). * Fix spurious error in logs when using a custom theme (#1312). * Fix broken metadata converter (#1305). ## Version 1.18.5 Released 2020-03-19 * Make the URLs for the cron module work again (#1248). * Email error reports now include metadata again (#1269). * Fix exampleauth module when using the legacy UI (#1275). * Fix authorize module when using custom reject message. * Documentation improvements. * Fix connection persistence for deployments that switched to memcached. ## Version 1.18.4 Released 2020-01-24 * Resolved a security issue in email reports. See [SSPSA 202001-01](https://simplesamlphp.org/security/202001-01). * Resolved a security issue with the logging system. See [SSPSA 202001-02](https://simplesamlphp.org/security/202001-02). * Fixed SQL store index creation for PostgreSQL. * Handle case where cookie 'domain' parameter was not set. * Update versions of included JavaScript dependencies. ## Version 1.18.3 Released 2019-12-09 * Fixed an issue with several modules being enabled by default (#1257). * Fixed an issue with metadata generation for trusted entities (#1247, #1251). ### ldap * Fixed an issue affecting the installation in case-insensitive file systems (#1253). ## Version 1.18.2 Released 2019-11-26 * Fixed an issue with the `ldap` module that prevented installing SimpleSAMLphp from the repository (#1241). ## Version 1.18.1 Released 2019-11-26 * Fixed an issue that prevented custom themes from working (#1240). * Fixed an issue with translations in the discovery service (#1244). * Fixed an issue with schema validation. ## Version 1.18.0 Released 2019-11-19 * Fixed an issue with warnings being logged when using PHP 7.2 or newer (#1168). * Fixed an issue with web server aliases or rewritten URLs not working (#1023, #1093). * Fixed an issue that prevented errors to be logged if the log file was not writeable (#1194). * Fixed an issue with old-style NameIDPolicy configurations that disallowed creating new NameIDs (#1230). * Resolved a security issue that exposed host information to unauthenticated users. See [SSPSA 201911-02](https://simplesamlphp.org/security/201911-02). * Replaced custom Email class with the phpmailer library. * Allow logging to STDERR in the `logging.handler` option by setting it to `stderr`. * Allow use of stream wrappers (e.g. s3://) in paths. * Improved 'update or insert' handling for different SQL drivers. * The default algorithm within the TimeLimitedToken class has been bumped from SHA-1 to SHA-256 as announced by deprecation notice in 1.15-RC1. * Most modules have been externalized. They will not be included in our future releases by default, but will be easily installable using Composer. For now, they are still included in the package. * Many minor fixes to code, css, documentation ### metarefresh * The algorithm to compute the fingerprint of the certificate that signed metadata can be specified with the new `validateFingerprintAlgorithm` configuration option. ### saml * Make the id of the generated signed metadata only change when metadata content changes. * New SP metadata configuration options `AssertionConsumerService` and `SingleLogoutServiceLocation` to allow overriding the default URL paths. * Added support for per-IDP configurable `AuthnContextClassRef`/`AuthnContextComparison`. ## Version 1.17.8 Released 2019-11-20 * Resolved a security issue that exposed host information to unauthenticated users. See [SSPSA 201911-02](https://simplesamlphp.org/security/201911-02). ### consentAdmin * Fixed an issue with CSS and Javascript not loading for the module in the new user interface. ## Version 1.17.7 Released 2019-11-06 * Resolved a security issue that allows to bypass signature validation. See [SSPSA 201911-01](https://simplesamlphp.org/security/201911-01). ## Version 1.17.6 Released 2019-08-29 * Fixed a regression with logout database initialization when using MySQL (#1177). * Fixed an issue with logout when using iframes (#1191). * Fixed an issue causing log entries to be logged with incorrect relative order (#1107). ## Version 1.17.5 Released 2019-08-02 * Fixed a bug in the SP API where NameID objects weren't taken care of (introduced in 1.17.0). * Fixed a regression where MetaDataStorageHandlerPdo::getMetaData() would not return a value (#1165). * Fixed an issue with table indexes (#1089). * Fixed an issue with table migrations on SQlite (#1169). * Fixed an issue with generated eduPersonTargetedID lacking a format specified (#1135). * Updated composer dependencies. ## Version 1.17.4 Released 2019-07-11 * Fix an issue introduced in 1.17.3 with `enable.http_post`. ## Version 1.17.3 Released 2019-07-10 * Resolved a security issue that could lead to a reflected XSS. See [SSPSA 201907-01](https://simplesamlphp.org/security/201907-01). * Add new options `session.cookie.samesite` and `language.cookie.samesite` that can be used to set a specific value for the cookies' SameSite attribute. The default it not to set it. * Upgraded jQuery to version 3.4. * HHVM is no longer supported. * Fixed a bug (#926) where dynamic metadata records where not loaded from a database. * Fixed an issue when an error occurs during a passive authentication request. * Handle duplicate insertions for SQL Server. * Fix a bug in Short SSO Interval warning filter. * Apply a workaround for SIGSEGVs during session creation with PHP-FPM 7.3. ### adfs * Fixed a missing option to supply a passphrase for the ADFS IDP signing certificate. ### authlinkedin * This module has been removed now that LinkedIn no longer supports OAuth1. If you relied on this module, you may consider migrating to the [authoauth2 module](https://github.com/cirrusidentity/simplesamlphp-module-authoauth2). A migration guide for LinkedIn authentication is included in their README. ## Version 1.17.2 Released 2019-04-02 * Fixed that generated metadata was missing some information when PHP's zend.assertions option is set to < 1. * Fixed that MDUI Keywords and Logo were not parsed from metadata. * Fixed DiscoPower module tab display. * Fixed use group name in Attribute Add Users Groups filter. * Add metadatadir setting to the default config template. * Fixed exception processing in loadExceptionState(). * Fixed preferredidp in built-in 'links'-style discovery. ## Version 1.17.1 Released 2019-03-07 * Fixed an issue with composer that made it impossible to install modules if SimpleSAMLphp was installed itself with the provided package (tar.gz file). ## Version 1.17.0 Released 2019-03-07 * Introduce a new experimental user interface based on Twig templates. The new Twig templates co-exist next to the old ones and come with a new look-and-feel for SimpleSAMLphp and independent interfaces for users and administrators. This new interface uses also a new build system to generate bundled assets. * Introduce Symfony-style routing and dependency injection(#966). * Generate session IDs complying with PHP config settings when using the PHP session handler (#569). * Update OpenSSL RSA bit length in docs (#993). * Update all code, configuration templates and documentation to PHP short array syntax. * All classes moved to namespaces and code reformatted to PSR-2. * Use bcrypt for new password hashes, old ones will remain working (#996). * Many code cleanups. * Update the SAML2 library dependency to 3.2.5. * Update the Clipboard.JS library dependency to 2.0.4. * Translated to Zulu and Xhosa. * Multiple bug fixes and corrections. ### Interoperability * The minimum PHP version required is now 5.5. * Fixed compatibility with PHP 7.3 and HVVM. * SimpleSAMLphp can now be used with applications that use Twig 2 and/or Symfony 4. * The SAML2 library now uses getters/setters to manipulate objects properties. ### authfacebook * Fix facebook compatibility (query parameters). ### authorize * Add the possibility to configure a custom rejecttion message. ### consent * The module is now disabled by default. ### core * Allow `core:PHP` to manipulate the entire state array. * IdP initiated login: add compatibility with Shibboleth parameters. ### multiauth * Added a `preselect` configuration option to skip authsource selection (#1005). ### negotiate * The `keytab` setting now allows for relative paths too. ### preprodwarning * This module is now deprecated. Use the `production` configuration option instead; set it to `false` to show a pre-production warning before authentication. ### saml * Add initial support for SAML Subject ID Attributes. * Allow to specify multiple supported NameIdFormats in IdP hosted and SP remote metadata. * Allow to specify NameIDPolicy Format and AllowCreate in hosted SP and remote IdP configuration. Restore the possibility to omit it from AuthnRequests entirely (#984). * Add a `assertion.allowed_clock_skew` setting to influence how lenient we should be with the timestamps in received SAML messages. * If the Issuer of a SAML response does not match the entity we sent the request to, log a warning instead of bailing out with an exception. * Allow setting the AudienceRestriction in SAML2 requests (#998). * Allow disabling the Scoping element in SP and remote IdP configuration with the `disable_scoping` option, for compatibility with ADFS which does not accept the element (#985). * Receiving an eduPersonTargetedID in string form will no longer break parsing of the assertion. ### sanitycheck * Translated into several languages. ## Version 1.16.3 Released 2018-12-20 * Resolved a security issue that could expose the user's credentials locally. See [SSPSA 201812-01](https://simplesamlphp.org/security/201812-01). * Downgraded the level of log messages regarding the `userid.attribute` configuration option from _warning_ to _debug_. * Make the `attr` configuration option of the _negotiate_ allow both a string and an array. * Look for the _keytab_ file used by the _negotiate_ module in the `cert` directory, accepting both absolute and relative paths. * Fixed some broken links. * Other minor bugfixes. ## Version 1.16.2 Released 2018-09-28 * Fixed an issue with PHP sessions in PHP 7.2. * Fixed a bug in the OAuth module. * Make schema validation work again. * Properly document the `saml:AuthnContextClassRef` authentication processing filter. * Fixed an issue that made it impossible to install the software with composer using the "stable" minimum-stability setting. * Changed the default authentication context class to "PasswordProtectedTransport" by default when authentication happened on an HTTPS exchange. ## Version 1.16.1 Released 2018-09-07 * Fix a bug preventing the consent page from showing. * Add Catalan to the list of available languages. ## Version 1.16.0 Released 2018-09-06 ### Changes * Default signature algorithm is now RSA-SHA256. * Renamed class `SimpleSAML_Error_BadUserInnput` to `SimpleSAML_Error_BadUserInput` * PHP 7.2 compatibility, including removing deprecated use of assert with string. * Avoid logging database credentials in backtraces. * Fix edge case in getServerPort. * Updated Spanish translation. * Improvements to documentation, testsuite, code quality and coding style. ### New features * Added support for SAML "Enhanced Client or Proxy" (ECP) protocol, IdP side with HTTP Basic Authentication as authentication method. See the [ECP IdP documentation](./simplesamlphp-ecp-idp) for details. * New option `sendmail_from`, the from address for email sent by SSP. * New option `options` for PDO database connections, e.g. for TLS setup. * New option `search.scope` for LDAP authsources. * Add support for the DiscoHints IPHint metadata property. * Add support to specify metadata XML in config with the `xml` parameter, next to the exising `file` and `url` options. * Also support CGI/RewriteRule setups that set the `REDIRECT_SIMPLESAMLPHP_CONFIG_DIR` environment variable next to regular `SIMPLESAMLPHP_CONFIG_DIR`. * Support creating an AuthSource via factory, for example useful in tests. * Support preloading of a virtual config file via `SimpleSAML_Configuration::setPreLoadedConfig` to allow for dynamic population of authsources.php. * Add basic documentation on Nginx configuration. * Test authentication: optionally show AuthData array. * Improve performance of PDO Metadata Storage handler entity lookup. ### adfs * Make signature algorithm configurable with `signature.algorithm`. * Use configuration assertion lifetime when available. * Use `adfs:wreply` parameter when available. ### authmyspace * Module removed because service is no longer available. ### cas * Respect all LDAP options in LDAP call. ### casserver * Module removed; superseded by externally hosted module. ### consent * Sort attribute values for consent. * Fix table layout for MySQL > 5.6. * Rename `noconsentattributes` to `attributes.exclude`; the former is now considered deprecated. ### consentAdmin * Work better with TargetedIDs when operating as a proxy. * Add `attributes.exclude` option to correspond to the same option in the Consent module. ### core * StatisticsWithAttribute: add `passive-` prefix when logging passive requests, set new option `skipPassive` to skip logging these altogether. * Replace deprecated `create_function` with an anonymous function. * New authproc filter Cardinality to enforce attribute cardinality. * SQLPermanentStorage: proper expiration of stored values. * AttributeLimit: new options `regex` and `ignoreCase`. * AttributeMap: prevent possible infinite loop with some PHP versions. ### ldap * AttributeAddUsersGroups: if `attribute.groupname` is set, use the configured attribute as the group name rather than the DN. * Also base64encode the `ms-ds-consistencyguid` attribute. ### metarefresh * Return XML parser error for better debugging of problems. * Only actually parse metadata types that have been enabled. * Fix missing translation. ### Oauth * Make module HTTP proxy-aware. * Remove unused demo app. ### saml * AttributeConsumingService: allow to set isDefault and index options. * Encrypted attributes in an assertion are now decrypted correctly. * Prefer the HTTP-Redirect binding for AuthnRequests if available. ### smartattributes * Fix to make the `add_authority` option work. ### sqlauth * The module is now disabled by default. ### statistics * Show a decent error message when no data is available. ## Version 1.15.4 Released 2018-03-02 * Resolved a security issue related to signature validation in the SAML2 library. See [SSPSA 201803-01](https://simplesamlphp.org/security/201803-01). ## Version 1.15.3 Released 2018-02-27 * Resolved a security issue related to signature validation in the SAML2 library. See [SSPSA 201802-01](https://simplesamlphp.org/security/201802-01). * Fixed edge-case scenario where an application uses one of the known LoggingHandlers' name as a defined class * Fixed issue #793 in the PHP logging handler. ## Version 1.15.2 Released 2018-01-31 * Resolved a Denial of Service security issue when validating timestamps in the SAML2 library. See [SSPSA 201801-01](https://simplesamlphp.org/security/201801-01). * Resolved a security issue with the open redirect protection mechanism. See [SSPSA 201801-02](https://simplesamlphp.org/security/201801-02). * Fix _undefined method_ error when using memcacheD. ### `authfacebook` * Fix compatibility with Facebook strict URI match. ### `consent` * Fix statistics not being gathered. ### `sqlauth` * Prevented a security issue with the connection charset used for MySQL backends. See [SSPSA 201801-03](https://simplesamlphp.org/security/201801-03). ## Version 1.15.1 Released 2018-01-12 ### Bug fixes * AuthX509 error messages were broken. * Properly calculate supported protocols based on config. * NameIDAttribute filter: update to use SAML2\XML\saml\NameID. * Replace remaining uses of SimpleSAML_Logger with namespace version. * Statistics: prevent mixed content errors. * Add 'no-store' to the cache-control header to avoid Chrome caching redirects. ## Version 1.15.0 Released 2017-11-20 ### New features * Added support for authenticated web proxies with the `proxy.auth` setting. * Added new `AttributeValueMap` authproc filter. * Added attributemaps for OIDs from SIS (Swedish Standards Institute) and for eduPersonUniqueId, eduPersonOrcid and sshPublicKey. * Added an option to specify metadata signing and digest algorithm `metadata.sign.algorithm`. * Added an option for regular expression matching of trusted.url.domains via new `trusted.url.regex` setting. * The `debug` option is more finegrained and allows one to specify whether to log full SAML messages, backtraces or schema validations separately. * Added a check for the latest SimpleSAMLphp version on the front page. It can be disabled via the new setting `admin.checkforupdates`. * Added a warning when there's a probable misconfiguration of PHP sessions. * Added ability to define additional attributes on ContactPerson elements in metatada, e.g. for use in Sirtfi contacts. * Added option to set a secure flag also on the language cookie. * Added option to specify the base URL for the application protected. * Added support for PHP Memcached extension next to Memcache extension. * Added Redis as possible session storage mechanism. * Added support to specify custom metadata storage handlers. * Invalidate opcache after writing a file, so simpleSAMLphp works when `opcache.validate_timestamps` is disabled. * Metadata converter will deal properly with XML with leading whitespace. * Update `ldapwhoami()` call for PHP 7.3. * Made response POST page compatible with strict Content Security Policy on calling webpage. * Updated Greek, Polish, Traditional Chinese and Spanish translations and added Afrikaans. ### Bug fixes * The deprecated OpenIdP has been removed from the metadata template. * Trailing slash is no longer required in `baseurlpath`. * Make redirections more resilient. * Fixed empty protocolSupportEnumeration in AttributeAuthorityDescriptor. * Other bug fixes and numerous documentation enhancements. * Fixed a bug in the Redis store that could lead to incorrect _duplicate assertion_ errors. ### API and user interface * Updated to Xmlseclibs 3.0. Minimum PHP version is now 5.4, mcrypt requirement dropped. * Added a PSR-4 autoloader for modules. Now modules can declare their classes under the SimpleSAML\Module namespace. * Added new hook for module loader exception handling `exception_handler`. * Expose RegistrationInfo in parsed SAML metadata. * The AuthnInstant is now available in the state array. * Introduced Twig templating for user interface. * Lots of refactoring, code cleanup and added many unit tests. ### `adfs` * Fixed POST response form parameter encoding. ### `authYubiKey` * Fixed PHP 7 support. ### `authfacebook` * Updated to work with latest Facebook API. ### `authlinkedin` * Added setting `attributes` to specify which attributes to request from LinkedIn. ### `authtwitter` * Added support for fetching the user's email address as attribute. ### `consent` * Added support for regular expressions in `consent.disable`. ### `core` * Added logging of `REMOTE_ADDR` on successful login. * `AttributeMap`: allow fetching mapping files from modules. * `ScopeAttribute`: added option `onlyIfEmpty` to add a scope only if none was present. * `AttributeCopy`: added option to copy to multiple destination attributes. ### `cron` * Allow invocation via PHP command line interface. ### `discopower` * Added South Africa tab. ### `ldap` * Added `search.filter` setting to limit LDAP queries to a custom search filter. * Added OpenLDAP support in AttributeAddUsersGroups. * Fixed for using non standard LDAP port numbers. * Fixed configuration option of whether to follow LDAP referrals. ### `memcacheMonitor` * Fixed several missing strings. ### `metarefresh` * Fixed several spurious PHP notices. ### `multiauth` * Fixed selected source timeout. ### `negotiate` * Fixed authentication failure on empty attributes-array. * Fixed PHP notices concerning missing arguments. ### `oauth` * Updated library to improve support for OAuth 1.0 Revision A. ### `radius` * Improved error messages. * Added parameter `realm` that will be suffixed to the username entered. ### `saml` * Handle instead of reject assertions that do not contain a NameID. * Added options to configure `AllowCreate` and `SPNameQualifier`. * Added option `saml:NameID` to set the Subject NameID in a SAML AuthnRequest. * Added filter `FilterScopes` to remove values which are not properly scoped. * Make sure we log the user out before reauthenticating. * More robust handling of IDPList support in proxy mode. * Increased `_authSource` field length in Logout Store. * We now send the eduPersonTargetedID attribute in the correct NameID XML form, instead of the incorrect simple string. We will also refuse to parse an assertion with an eduPersonTargetedID in 'string' format. ### `smartattributes` * Fix SmartName authproc that failed to load. ### `sqlauth` * Fixed SQL schema for usergroups table. ## Version 1.14.17 Released 2017-10-25 * Resolved a security issue with the SAML 1.1 Service Provider. See [SSPSA 201710-01](https://simplesamlphp.org/security/201710-01). ## Version 1.14.16 Released 2017-09-04 * Resolved a security issue in the consentAdmin module. See [SSPSA 201709-01](https://simplesamlphp.org/security/201709-01). ## Version 1.14.15 Released 2017-08-08 * Resolved a security issue with the creation and validation of time-limited tokens. See [SSPSA 201708-01](https://simplesamlphp.org/security/201708-01). * Fixed an issue with session handling that could lead to crashes after upgrading from earlier 1.14.x versions. * Fixed issue #557 with instances of SimpleSAMLphp installed from the repository as well as custom modules. * Fixed issue #648 to properly handle SAML responses being sent to reply the same request, but using different response IDs. * Fixed issues #612 and #618 with the mobile view of the web interface. * Fixed issue #639 related to IdP names containing special characters not being properly displayed by discopower. * Fixed issue #571 causing timeouts when using Active Directory as a backend. * Other minor fixes. ## Version 1.14.14 Released 2017-05-05 * Resolved a security issue with in the authcrypt module (Htpasswd authentication source) and in SimpleSAMLphp's session validation. See [SSPSA 201705-01](https://simplesamlphp.org/security/201705-01). * Resolved a security issue with in the multiauth module. See [SSPSA 201704-02](https://simplesamlphp.org/security/201704-02). ## Version 1.14.13 Released 2017-04-27 * Resolved a security issue with unauthenticated encryption in the SimpleSAML\Utils\Crypto class. See [SSPSA 201704-01](https://simplesamlphp.org/security/201704-01). * Added requirement for the Multibyte String PHP extension and the corresponding checks. * Set a default name for SimpleSAMLphp sessions in the configuration template for the PHP session handler. ## Version 1.14.12 Released 2017-03-30 * Resolved a security issue in the authcrypt module (Htpasswd authentication source) and in SimpleSAMLphp's session validation. See [SSPSA 201703-01](https://simplesamlphp.org/security/201703-01). * Resolved a security issue with IV generation in the `SimpleSAML\Utils\Crypto::_aesEncrypt()` method. See [SSPSA 201703-02](https://simplesamlphp.org/security/201703-02). * Fixed an issue with the authfacebook module, broken after a change in Facebook's API. * Fixed an issue in the discopower module that ignored the `hide.from.discovery` metadata option. * Fixed an issue with trusted URLs validation that prevented a URL from being accepted if a standard port was explicitly included but not specified in the configuration. * Fixed an issue that prevented detecting a Memcache server being down when fetching Memcache statistics. * Fixed an issue with operating system detection that made SimpleSAMLphp identify OSX as Windows. ## Version 1.14.11 Released 2016-12-12 * Resolved a security issue involving signature validation of SAML 1.1 messages. See [SSPSA 201612-02](https://simplesamlphp.org/security/201612-02). * Fixed an issue when the user identifier used to generate a persistent NameID was missing due to a misconfiguration, causing SimpleSAMLphp to generate the nameID based on the null data type. * Fixed an issue when persistent NameIDs were generated out of attributes with empty strings or multiple values. * Fixed issue #530. An empty SubjectConfirmation element was causing SimpleSAMLphp to crash. On the other hand, invalid SubjectConfirmation elements were ignored in PHP 7.0. ## Version 1.14.10 Released 2016-12-02 * Resolved a security issue involving signature validation. See [SSPSA 201612-01](https://simplesamlphp.org/security/201612-01). * Fixed issue #517. A misconfigured session when acting as a service provider was leading to a PHP fatal error. * Fixed issue #519. Prevent persistent NameIDs from being generated from empty strings. * Fixed issue #520. It was impossible to verify Apache's custom MD5 passwords when using the Htpasswd authentication source. * Fixed issue #523. Avoid problems caused by different line-ending strategies in the project files. * Other minor fixes and enhancements. ## Version 1.14.9 Released 2016-11-10 * Fixed an issue that resulted in PHP 7 errors being masked. * Fixed the smartattributes:SmartName authentication processing filter. * Fixed issue #500. When parsing metadata, two 'attributes.required' options were generated. * Fixed the list of requirements in composer, the documentation, and the configuration page. * Fixed issue #479. There were several minor issues with XHTML compliance. * Other minor fixes. ## Version 1.14.8 Released 2016-08-23 * Fixed an issue in AuthMemCookie causing it to crash when an attribute received contains XML as its value. * Fixed an issue in AuthMemCookie that made it impossible to set its own cookie. * Fixed an issue when acting as a proxy and receiving attributes that contain XML as their values. * Fixed an issue that led to incorrect URL guessing when a script is invoked with a URI that doesn't include its name. ## Version 1.14.7 Released 2016-08-01 * Fixed issue #424. Attributes containing XML as their values (like eduPersonTargetedID) were empty. ## Version 1.14.6 Released 2016-07-18 * Fixed issue #418. SimpleSAMLphp was unable to obtain the current URL correctly when invoked from third-party applications. ## Version 1.14.5 Released 2016-07-12 * Fixed several issues with session handling when cookies couldn't be set for some reason. * Fixed an issue that caused wrong URLs to be generated in the web interface under certain circumstances. * Fixed the exception handler to be compatible with PHP 7. * Fixed an issue in the dropdown IdP selection page that prevented it to work with PHP 5.3. * Fixed compatibility with Windows machines. * Fixed an issue with the PDO and Serialize metadata storage handlers. * Fixed the authwindowslive module. It stopped working after the former API was discontinued. * Other minor issues and fixes. ## Version 1.14.4 Released 2016-06-08 * Fixed two minor security issues that allowed malicious URLs to be presented to the user in a link. Reported by John Page. * Fixed issue #366. The LDAP class was trying to authenticate even when no password was provided (using the CAS module). * Fixed issue #401. The authenticate.php script was printing exceptions instead of throwing them for the exception handler to capture them. * Fixed issue #399. The size limitation of the TEXT type in MySQL was creating problems in certain setups. * Fixed issue #5. Incoherent population of the $_SERVER variable was creating broken links when running PHP with FastCGI. * Other typos and minor bugs: #389, #392. ## Version 1.14.3 Released 2016-04-19 * Fixed a bug in the login form that prevented the login button to be displayed in mobile devices. * Resolved an issue in the PHP session handler that made it impossible to use PHP sessions simultaneously with other applications. ## Version 1.14.2 Released 2016-03-11 * Use stable versions of the externalized modules to prevent possible issues when further developing them. ## Version 1.14.1 Released 2016-03-08 * Resolved an information leakage security issue in the sanitycheck module. See [SSPSA 201603-01](/security/201603-01). ## Version 1.14.0 Released 2016-02-15 ### Security * Resolved a security issue with multiple modules that were not validating the URLs they were redirecting to. * Added a security check to disable loading external entities in XML documents. * Enforced admin access to the metadata converter tool. * Changed `xmlseclibs` dependency to point to `robrichards/xmlseclibs` version 1.4.1. ### New features * Allow setting the location of the configuration directory with an environment variable. * Added support for the Metadata Query Protocol by means of the new MDX metadata storage handler. * Added support for the Sender-Vouches method. * Added support for WantAssertionsSigned and AuthnRequestsSigned in SAML 2.0 SP metadata. * Added support for file uploads in the metadata converter. * Added support for setting the prefix for Memcache keys. * Added support for the Hide From Discovery REFEDS Entity Category. * Added support for the eduPersonAssurance attribute. * Added support for the full SCHAC 1.5.0 schema. * Added support for UNIX sockets when configuring memcache servers. * Added the SAML NameID to the attributes status page, when available. * Added attribute definitions for schacGender (schac), sisSchoolGrade and sisLegalGuardianFor (skolfederation.se). * Attributes required in metadata are now taken into account when parsing. ### Bug fixes * Fixed an issue with friendly names in the attributes released. * Fixed an issue with memcache that would result in a push for every fetch, when several servers configured. * Fixed an issue with memcache that would result in an endless loop if all servers are down. * Fixed an issue with HTML escaping in error reports. * Fixed an issue with the 'admin.protectmetadata' option not being enforced for SP metadata. * Fixed an issue with SAML 1.X SSO authentications that removed the NameID of the subject from available data. * Fixed an issue with the login form that resulted in a `NOSTATE` error if the user clicked the login button twice. * Fixed an issue with replay detection in IdP-initiated flows. * Fixed an issue with SessionNotOnOrAfter that kept moving forward in the future with every SSO authentication. * Fixed an issue with the session cookie being set twice for the first time. * Fixed an issue with the XXE attack prevention mechanism conflicting with other applications running in the same server. * Fixed an issue that prevented the SAML 1.X IdP to restart when the session is lost. * Fixed an issue that prevented classes using namespaces to be loaded automatically. * Fixed an issue that prevented certain metadata signatures to be verified (fixed upstream in `xmlseclibs`). * Other bug fixes and numerous documentation enhancements. ### API and user interface * Added a new and simple database class to serve as PDO interface for all the database needs. * Added the possibility to copy metadata and other elements by clicking a button in the web interface. * Removed the old, unused `pack` installer tool. * Improved usability by telling users the endpoints are not to be accessed directly. * Moved the hostname, port and protocol diagnostics tool to the admin directory. * Several classes and functions deprecated. * Changed the signature of several functions. * Deleted old and deprecated code, interfaces and endpoints. * Deleted old jQuery remnants. * Deleted the undocumented dynamic XML metadata storage handler. * Deleted the backwards-compatible authentication source. * Updated jQuery to the latest 1.8.X version. * Updated translations. ### `authcrypt` * Added whitehat101/apr1-md5 as a dependency for Apache htpasswd. ### `authX509` * Added an authentication processing filter to warn about certificate expiration. ### `ldap` * Added a new `port` configuration option. * Better error reporting. ### `metaedit` * Removed the `admins` configuration option. ### `metarefresh` * Added the possibility to specify which types of entities to load. * Added the possibility to verify metadata signatures by using the public key present in a certificate. * Fix `certificate` precedence over `fingerprint` in the configuration options when verifying metadata signatures. ### `smartnameattribute` * This module was deprecated long time ago and has now been removed. Use the `smartattributes` module instead. ## Version 1.13.2 Released 2014-11-04 * Solved performance issues when processing large metadata sets. * Fix an issue in the web interface when only one language is enabled. ## Version 1.13.1 Released 2014-10-27 * Solved an issue with empty fields in metadata to cause SimpleSAMLphp to fail with a translation error. Issues #97 and #114. * Added Basque language to the list of known languages. Issue #117. * Optimized the execution of redirections by removing an additional, unnecessary function call. * Solved an issue that caused SimpleSAMLphp to fail when the RelayState parameter was empty or missing on an IdP-initiated authentication. Issues #99 and # 104. * Fixed a certificate check for SubjectConfirmations with Holder of Key methods. ## Version 1.13 Released 2014-09-25. * Added the 'remember me' option to the default login page. * Improved error reporting. * Added a new 'logging.format' option to control the formatting of the logs. * Added support for the 'objectguid' binary attribute in LDAP modules. * Added support for custom search and private attributes read credentials in all LDAP modules. * Added support for the WantAuthnRequestsSigned option in generated SAML metadata. * Tracking identifiers are no longer generated based on MD5. * Several functions, classes and interfaces marked as deprecated. * Bug fixes and documentation enhancements. * Updated translations. * New language: Basque. ### `adfs` * Honour the 'wreply' parameter when redirecting. ### `aggregator` * Fixed an issue when regenerating metadata from certain metadata sources. ### `discopower` * Bug fix. ### `expirycheck` * Translations are now possible for this module. ### `metarefresh` * Use cached metadata if something goes wrong when refreshing feeds. ### `openidProvider` * Fix for compatibility with versions of PHP greater or equal to 5.4. ### `saml` * Make it possible to add friendly names to attributes in SP metadata. * The RSA_1.5 (RSA with PKCS#1 v1.5 padding) encryption algorithm is now blacklisted by default for security reasons. * Stop checking the 'IDPList' parameter in IdPs. * Solved an issue that allowed bypassing authentication status checks when presenting an 'IDPList' parameter. * The 'Destination' attribute is now always sent in logout responses issued by an SP. ### `sqlauth` * Updated documentation to remove bad practice with regard to password storage. ## Version 1.12 Released 2014-03-24. * Removed example authproc filters from configuration template. * Stopped using the 'target-densitydpi' option removed from WebKit. * The SimpleSAML_Utilities::generateRandomBytesMTrand() function is now deprecated. * Removed code for compatibility with PHP versions older than 5.3. * Removed the old interface of SimpleSAML_Session. * Fixed a memory leak in SimpleSAML_Session regarding serialization and unserialization. * Support for RegistrationInfo (MDRPI) elements in the metadata of identity and service providers. * Renamed SimpleSAML_Utilities::parseSAML2Time() function to xsDateTimeToTimestamp(). * New SimpleSAML_Utilities::redirectTrustedURL() and redirectUntrustedURL() functions. * Deprecated the SimpleSAML_Utilities::redirect() function. * Improved Russian translation. * Added Czech translation. * New 'errorreporting' option to enable or disable error reporting feature. * Example certificate removed. * New SimpleSAML_Configuration::getEndpointPrioritizedByBinding() function. * PHP 5.3 or newer required. * Started using Composer as dependency manager. * Detached the basic SAML2 library and moved to a standalone library in github. * Added support for exporting shibmd:Scope metadata with regular expressions. * Remember me option in the IdP. * New SimpleSAML_Utilities::setCookie wrapper. * Custom HTTP codes on error. * Added Romanian translation. * Bug fixes and documentation enhancements. ### `adfs` * Support for exporting metadata. ### `aggregator` * Support for RegistrationInfo (MDRPI) elements in the metadata. * Fix for HTTP header injection vulnerability. * Fix for directory traversal vulnerability. ### `aggregator2` * Support for RegistrationInfo (MDRPI) elements in the metadata. ### `aselect` * License changed to LGPL 2.1. ### `authfacebook` * Updated extlibinc to 3.2.2. ### `authtwitter` * Added 'force_login' configuration option. ### `cdc` * Bugfix related to request validation. ### `core` * The AttributeAlter filter no longer throws an exception if the attribute was not found. * Support for removal of values in the AttributeAlter filter, with '%remove' flag. * Support for empty strings and NULL values as a replacement in the AttributeAlter filter. * Bugfixes in the AttributeAlter filter. * Support for NULL attribute values. * Support for limiting values and not only attributes in the AttributeLimit filter. * Log a message when a user authenticates successfully. * Added %duplicate flag to AttributeMap, to leave original names in place when using map file. * Fix infinite loop when overwriting attributes with AttributeMap. ### `discopower` * Bugfix for incorrect handling of the 'idpdisco.extDiscoveryStorage' option. ### `ldap` * Support for configuring the duplicate attribute handling policy in AttributeAddFromLDAP, 'attribute.policy' option. * Support for binary attributes in the AttributeAddFromLDAP filter. * Support for multiple attributes in the AttributeAddFromLDAP filter. ### `metarefresh` * Support for specifying permissions of the resulting files. ### `negotiate` * Added support for "attributes"-parameter. ### `oauth` * Bugfix related to authorize URL building. ### `openidProvider` * Support for SReg and AX requests. ### `saml` * Send 'isPassive' in passive discovery requests. * Support for generating NameIDFormat in service providers with NameIDPolicy set. * Support for AttributeConsumingService and AssertionConsumingServiceIndex. * Support for the HTTP-POST binding in WebSSO profile. * Fix for entity ID validation problems when using the IDPList configuration option. ### `smartattributes` * New 'add_candidate' option to allow the user to decide whether to prepend or not the candidate attribute name to the resulting value. ### `statistics` * Bugfix in statistics aggregator. ## Version 1.11 Released 2013-06-05. * Support for RSA_SHA256, RSA_SHA384 and RSA_SHA512 in HTTP Redirect binding. * Support for RegistrationInfo element in SAML 2.0 metadata. * Support for AuthnRequestsSigned and WantAssertionsSigned when generating metadata. * Third party OpenID library updated with a bugfix. * Added the Name attribute to EntitiesDescriptor. * Removed deprecated option 'session.requestcache' from config-template. * Workaround for SSL SNI extension not being correctly set. * New language cookie and parameter config options. * Add 'module.enable' configuration option for enabling/disabling modules. * Check for existence of memcache extension. * Initial support for limiting redirects to trusted hosts. * Demo example now shows both friendly and canonical name of the attributes. * Other minor fixes for bugs and typos. * Several translations updated. * Added Latvian translation. ### `authorize` * Added a logout link to the 403 error page. ### `authtwitter` * Updated API endpoint for version 1.1. * Fix for oauth_verifier parameter. ### `authX509` * ldapusercert validation made optional. ### `consent` * Added support for SQLite databases. ### `core` * Fix error propagation in UserPass(Org)Base authentication sources. * MCrypt module marked as required. ### `discopower` * Get the name of an IdP from mdui:DisplayName. ### `expirycheck` * PHP 5.4 compatibility fixes. ### `InfoCard` * PHP 5.4 compatibility fixes. ### `ldap` * Added an option to disable following referrals. ### `metarefresh` * Improved help message. ### `oauth` * PHP 5.4 compatibility fixes. ### `saml` * Verify that the issuer of an AuthnResponse is the same entity ID we sent a request to. * Added separate option to enable Holder of Key support on SP. * Fix for HoK profile metadata. * New filter for storing persistent NameID in eduPersonTargetedID attribute. * Support for UIInfo elements. * Bugfix for SAML SP metadata signing. * Ignore default technical contact. * Support for MDUI elements in SP metadata. * Support for more contact types in SP metadata. * New information in statistics with the time it took for a login to happen. ### `sanitycheck` * Configuration file made optional. ### `smartattributes` * New filter: smartattributes:SmartID. * New filter: smartattributes:SmartName. ### `smartnameattribute` * Deprecated. ### `wsfed` * Support for SLO in WS-Fed. ## Version 1.10 Released 2012-09-25. * Add support for storing data without expiration timestamp in memcache. * Fix for reauthentication in old shib13 authentication handler. * Clean up executable-permissions on files. * Change encryption to use the rsa-oaep-mgf1p key padding instead of PKCS 1.5. * Update translations. * Added Serbian translation. ### `core` * `core:UserPass(Org)Base`: Add "remember username" option. ### `papi` * New authentication module supporting PAPI protocol. ### `radius` * New feature to configure multiple radius servers. ### `riak` * New module for storing sessions in a Riak database. ### `saml` * Add support for overriding SAML 2.0 SP authentication request generation. * Add support for blacklisting encryption algorithms. ## Version 1.9.2 Released 2012-08-29 * Fix related to the security issue addressed in version 1.9.1. ## Version 1.9.1 Released 2012-08-02. * Fix for a new attack against PKCS 1.5 in XML encryption. ## Version 1.9 Released 2012-06-13. * Restructure error templates to share a common base template. * Warnings about URL length limits from Suhosin PHP extension. * New base class for errors from authentication sources. * Support for overriding URL generation when behind a reverse proxy. * New languages: Russian, Estonian, Hebrew, Chinese, Indonesian * Add getAuthSource()-function to SimpleSAML_Auth_Simple. * Add reauthenticate()-function to SimpleSAML_Auth_Source. (Is called when the IdP receives a new authentication request.) * iframe logout: Make it possible to skip the "question-page" for code on the IdP. * RTL text support. * Make SimpleSAMLAuthToken cookie name configurable. * Block writing secure cookies when we are on http. * Fix state information being unavailable to UserPassOrgBase authentication templates. * Make it possible to send POST-messages to http-endpoints without triggering a warning when the IdP supports both http and https. * Add IPv6-support to the SimpleSAML_Utilities::ipCIDRcheck()-function. * Do not allow users to switch to a language that is not enabled. * iframe logout: Add a per-SP timeout option. * SimpleSAML_Auth_LDAP: Better logging of the cause of exceptions. * SimpleSAML_Auth_State: Add $allowMissing-parameter to loadState(). * module.php: More strict URL parsing. * Add support for hashed admin passwords. * Use openssl_random_pseudo_bytes() for better cross-platform random number generation. * Add the current hostname to the error reports. * Make the lifetime of SimpleSAML_Auth_State "state-arrays" configurable (via the `session.state.timeout`-option). * SimpleSAML_Auth_State: Add cloneState()-function. * Fix log levels used on Windows. * SimpleSAML_Auth_LDAP: Clean up some unused code. * core:UserPassOrgBase: Add selected organization to the authentication data that is stored in the session. * Do not warn about missing Radius and LDAP PHP extensions unless those modules are enabled. * Support for overriding the logic to determine the language. * Avoid crashes due to deprecation-warnings issued by PHP. * Use case-insensitive matching of language codes. * Add X-Frame-Options to prevent other sites from loading the SSP-pages in an iframe. * Add SimpleSAML_Utilities::isWindowsOS()-helper function. * chmod() generated files to only be accessible to the owner of the files. * Fix "re-posting" of POST data containing a key named "submit". * Do not attempt to read new sessions from the session handler. * Fix some pass-by-reference uses. (Support removed in PHP 5.4.) * Warn the user if the secretsalt-option isn't set. * A prototype for a new statistics logging core. Provides more structured logging of events, and support for multiple storage backends. * Support for arbitrary namespace-prefixed attributes in md:EndpointType-elements. * Fix invalid HTML for login pages where username is set. * Remove unecessary check for PHP version >= 5.2 when setting cookies. * Better error message when a module is missing a default-enable or default-disable file. * Support for validating RSA-SHA256 signatures. * Fixes for session exipration handling. ### `aselect` * New module that replaces the previous module. * Better error handling. * Support for request signing. * Loses support for A-Select Cross. ### `authcrypt` * `authcrypt:Hash`: New authentication source for checking username & password against a list of usernames and hashed passwords. * `authcrypt:Htpasswd`: New authentication source for checking username & password against a `.htpasswd`-file. ### `authfacebook` * Update to latest Facebook PHP SDK. ### `authorize` * `authorize:Authorize`: Add flag to change the behaviour from default-deny to default-allow. * `authorize:Authorize`: Add flag to do simple string matching instead of regex-matching. ### `authtwitter` * Update to use the correct API endpoint. * Propagate "user aborted" errors back to the caller. * Changes to error handling, throw more relevant exceptions. * Store state information directly in the state array, instead of the session. ### `authYubiKey` * Remove deprecated uses of split(). ### `cas` * Make it possible for subclasses to override finalState(). ### `core` * `core:AttributeCopy`: New filter to copy attributes. ### `consent` * Add a timeout option for the database connection. * Fix disabling of consent when the data store is down. * Simpler configuration for disabling consent for one SP or one IdP. * Do not connect to the database when consent is disabled for the current SP/IdP. ### `consentAdmin` * Fix for bridged IdP setup with `userid.attribute` set in `saml20-idp-hosted` metadata. ### `cron` * Set the From-address to be the technical contact email address. ### `expirycheck` * `expirycheck:ExpiryDate`: New module to check account expiration. ### `ldap` * Add a base class for authentication processing filters which fetch data from LDAP. * `ldap:AttributeAddUsersGroups`: Authentication processing filter that adds group information from LDAP. ### `metarefresh` * Support for blacklisting and whitelisting entities. * Support for conditional GET of metadata files. * Reuse old metadata when fetching metadata fails. ### `multiauth` * Add `multiauth:preselect`-parameter, to skip the page to select authentication source. * Make it possible to configure the names of the authentication sources. * Remember the last selected authentication source. ### `negotiate` * New module implementing "negotiate" authentication, which can be used for Kerberos authentication (including Windows SSO). ### `oauth` * Update to latest version of the OAuth library. * Remove support for older versions of OAuth than OAuth Rev A. ### `openid` * Separate linkback URL from page displaying OpenID URL field. * Throw more relevant exceptions. * Update to latest version of the OpenID library. * Support for sending authentication requests via GET requests (with the prefer_http_redirect option). * Prevent deprecation warnings from the OpenID library from causing deadlocks in the class loader. ### `openidProvider` * Prevent deprecation warnings from the OpenID library from causing deadlocks in the class loader. ### `radius` * Support for setting the "NAS-Identifier" attribute. ### `saml` * Preserve ID-attributes on elements during signing. (Makes it possible to change the binding for some messages.) * Allow SAML artifacts to be received through a POST request. * Log more debug information when we are unable to determine the binding a message was sent with. * Require HTTP-POST messages to be sent as POST data and HTTP-Redirect messages to be sent as query parameters. * Link to download certificates from metadata pages. * Fix canonicalization of <md:EntityDescriptor> and <md:EntitiesDescriptor>. * Support for receiving and sending extension in authentication request messages. * Reuse SimpleSAML_Utilities::postRedirect() to send HTTP-POST messages. * Allow ISO8601 durations with subsecond precision. * Add support for parsing and serializing the <mdrpi:PublicationInfo> metadata extension. * Ignore cacheDuration when validating metadata. * Add support for the Holder-of-Key profile, on both the [SP](./simplesamlphp-hok-sp) and [IdP](./simplesamlphp-hok-idp). * Better error handling when receiving a SAML 2.0 artifact from an unknown entity. * Fix parsing of <md:AssertionIDRequestService> metadata elements. * IdP: Do not always trigger reauthentication when the authentication request contains a IdPList-element. * IdP: Add `saml:AllowCreate` to the state array. This makes it possible to access this parameter from authentication processing filters. * IdP: Sign the artifact response message. * IdP: Allow the "host" metadata option to include more than one path element. * IdP: Support for generating metadata with MDUI extension elements. * SP: Use the discojuice-module as a discovery service if it is enabled. * SP: Add `saml:idp`-parameter to trigger login to a specific IdP to as_login.php. * SP: Do not display error on duplicate response when we have a valid session. * SP: Fix for logout after IdP initiated authentication. * SP: Fix handling of authentication response without a saml:Issuer element. * SP: Support for specifying required attributes in metadata. * SP: Support for limiting the AssertionConsumerService endpoints listed in metadata. * SP: Fix session expiration when the IdP limits the session lifetime. * `saml:PersistentNameID`: Fail when the user has more than one value in the user ID attribute. * `saml:SQLPersistentNameID`: Persistent NameID stored in a SQL database. * `saml:AuthnContextClassRef`: New filter to set the AuthnContextClassRef in responses. * `saml:ExpectedAuthnContextClassRef`: New filter to verify that the SP received the correct authentication class from the IdP. ## Version 1.8.2 Released 2012-01-10. * Fix for user-assisted cross site scripting on a couple of pages. ## Version 1.8.1 Released 2011-10-27. * Fix for key oracle attack against XML encryption on SP. * Fix for IdP initiated logout with IdP-initiated SSO. * Fix a PHP notice if we are unable to open /dev/urandom. * Fix a PHP notice during SAML 1.1 authentication. ## Version 1.8 * New authentication modules: * [`authmyspace`](./authmyspace:oauthmyspace) * [`authlinkedin`](./authlinkedin:oauthlinkedin) * [`authwindowslive`](./authwindowslive:windowsliveid) * Support for custom error handler, replacing the default display function. * Allow error codes to be defined in modules. * Better control of logout what we do after logout request. * This makes it possible for the SP to display a warning when receiving a PartialLogout response from the IdP. * New `cdc` module, for setting and reading common domain cookies. ### `consent` * Support for disabling consent for some attributes. ### `ldap` * `ldap:AttributeAddFromLDAP`: Extract values from multiple matching entries. ### `oauth` * Added support for: * RSASHA1 signatures * consent * callbackurl * verifier code * request parameters ### `openid` * Support for sending custom extension arguments (e.g. UI extensions). ### `saml` * Extract Extensions from AuthnRequest for use by custom modules when authenticating. * Allow signing of SP metadata. * Better control over NameIDPolicy when sending AuthnRequest. * Support encrypting/decrypting NameID in LogoutRequest. * Option to disable client certificate in SOAP client. * Better selection of AssertionConsumerService endpoint based on parameters in AuthnRequest. * Set NotOnOrAfter in IdP LogoutRequest. * Only return PartialLogout from the IdP. ## Version 1.7 * New authentication modules: * `aselect` * `authX509` * Unified cookie configuration settings. * Added protection against session fixation attacks. * Error logging when failing to initialize the Session class. * New session storage framework. * Add and use generic key/value store. * Support for storing sessions in SQL databases (MySQL, PostgreSQL & SQLite). * Support for implementing custom session storage handlers. * Allow loading of multiple sessions simultaneously. * Set headers allowing caching of static files. * More descriptive error pages: * Unable to load $state array because the session was lost. * Unable to find metadata for the given entityID. * Support for multiple keys in metadata. * Allow verification with any of the public keys in metadata. * Allow key rollower by defining new and old certificate in configuration. * Verify with signing keys, encrypt with encryption keys. * Change `debug`-option to log messages instead of displaying them in the browser. * Also logs data before encryption and after decryption. * Support for custom attribute dictionaries. * Add support for several authentication sessions within a single session. * Allows several SPs on a single host. * Allows for combining an SP and an IdP on a single host. * HTTP proxy support. ### Internal API changes & features removed * The `saml2` module has been removed. * The `saml2:SP` authsource has been removed. * The `sspmod_saml2_Error` class has been renamed to `sspmod_saml_Error`. * The `sspmod_saml2_Message` class has been renamed to `sspmod_saml_Message`. * Moved IdP functions from `sspmod_saml_Message` to `sspmod_saml_IdP_SAML2`. * Removed several functions and classes that are unused: * `SimpleSAML_Utilities::strleft` * `SimpleSAML_Utilities::array_values_equal` * `SimpleSAML_Utilities::getRequestURI` * `SimpleSAML_Utilities::getScriptName` * `SimpleSAML_Utilities::getSelfProtocol` * `SimpleSAML_Utilities::cert_fingerprint` * `SimpleSAML_Utilities::generateTrackID` * `SimpleSAML_Utilities::buildBacktrace` * `SimpleSAML_Utilities::formatBacktrace` * `SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta` * `SimpleSAML_ModifiedInfo` * Moved function from Utilities-class to more appropriate locations. * `getAuthority` to `SimpleSAML_IdP` * `generateUserId` to `sspmod_saml_IdP_SAML2`. * Replaced calls to with throwing an `SimpleSAML_Error_Error` exception. * Removed metadata send functionality from old SP code. * Removed bin/test.php and www/admin/test.php. * Removed metashare. * Removed www/auth/login-auto.php. * Removed www/auth/login-feide.php. * Removed optional parameters from `SimpleSAML_XHTML_Template::getLanguage()`. * Removed functions from `SAML2_Assertion`: `get/setDestination`, `get/setInResponseTo`. Replaced with `setSubjectConfirmation`. * Removed several unused files & templates. ### SAML 2 IdP * Support for generation of NameID values via [processing filters](./saml:nameid) * Obey the NameIDPolicy Format in authentication request. * Allow AuthnContextClassRef to be set by processing filters. * Rework iframe logout page to not rely on cookies. ### SAML 2 SP * Support SOAP logout. * Various fixes to adhere more closely to the specification. * Allow multiple SessionIndex-elements in LogoutRequest. * Handle multiple Assertion-elements in Response. * Reject duplicate assertions. * Support for encrypted NameID in LogoutRequest. * Verify Destination-attribute in LogoutRequest messages. * Add specific options for signing and verifying authentication request and logout messages. * `saml:NameIDAttribute` filter for extracting NameID from authentication response. ### SAML 1 IdP * Add `urn:mace:shibboleth:1.0` as supported protocol in generated metadata. ### SAML 1 SP * Support for IdP initiated authentication. ### `aggregator` * Allow metadata generation from command line. ### `authfacebook` * Change attribute names. ### `casserver` * Support for proxying. * Add ttl for tickets. ### `core` * `core:AttributeLimit`: Make it possible to specify a default set of attributes. * Make the SP metadata available on the login pages. ### `discoPower` * Sort IdPs without a name (where we only have an entityID) last in the list. * CDC cookie support. ### `exampleAuth` * Add example of integration with external authentication page. ### `ldap` * Add `ldap:AttributeAddFromLDAP` filter for adding attributes from a LDAP directory. ### `metarefresh` * Don't stop updates on the first exception. ### `openid` * Don't require access to the PHP session. * Remove OpenID test page. (May as well use the normal test pages.) * Support for attribute exchange. * Add `target` option, for directing authentication to a specific OpenID provider. * Add `realm` option, for specifying the realm we should send to the OpenID provider. ### `portal` * Make it possible to register pages from modules, and not only from configuration. ### `statistics` * New y-axis scaling algorithm ### `twitter` * Change attribute names returned from twitter. ## Version 1.6.3 Released 2010-12-17. * Fix for cross site scripting in redirect page. ## Version 1.6.2 Released 2010-07-29. * Various security fixes. ## Version 1.6.1 Released 2010-06-25. * saml:SP: Fix SingleLogoutService endpoint in SSP-format metadata array. * Shib13:IdP: Add urn:mace:shibboleth:1.0 to supported protocols. * Fix SAMLParser::parseElement(). * SAML2:IdP: Fix persistent NameID generation. * Fix scoping on IdP discovery page. * metaedit: Fix endpoints parsed from XML. * Dictionary update. * Documentation fixes. ## Version 1.6 Released 2010-05-31. [Upgrade notes](./simplesamlphp-upgrade-notes-1.6) * Detection of cookies disabled on the IdP. * New IdP core, which makes it simpler to share code between different IdPs, e.g. between SAML 1.1 and SAML 2.0. * Dictionaries moved to JSON format. * New authentication module: [`cas:CAS`](./cas:cas). * All images that doesn't permit non-commercial use have been replaced. * Better support for OrganizationName, OrganizationDisplayName and OrganizationURL in metadata. * Cookie secure flag no longer automatically set. * Cross-protocol logout between ADFS and SAML 2. * New experimental module for aggregating metadata: [`aggregator2`](./aggregator2:aggregator2) * Metadata support for multiple endpoints with [multiple bindings](./simplesamlphp-metadata-endpoints). * The metadata generation is using a new set of classes. As a result, all generated metadata elements now have a `md:`-prefix. * The deprecated functions `init(...)` and `setAuthenticated(...) in the `SimpleSAML_Session` class have been removed. * Configuration check and metadata check was removed, as they were often wrong. ### SAML 2 SP * SAML 2.0 HTTP-Artifact support on the [SP](./simplesamlphp-artifact-sp). ### SAML 2 IdP * SAML 2.0 HTTP-Artifact support on the [IdP](./simplesamlphp-artifact-idp). * Support for sending PartialLogout status code in logout response. * Set AuthnInstant to the timestamp for authentication. * Combine normal and iframe versions of the logout handlers into a single endpoint. * The SessionIndex is now unique per SP. * Statistics for logout failures. * Better generation of persistent NameID when `nameid.attribute` isn't specified. ### The SP API * Support for handling errors from the IdP. * Support for passing parameters to the authentication module. This can be used to specify SAML 2 parameters, such as isPassive and ForceAuthn. ### `adfs` * Move to new IdP core. ### `casserver` * Collect all endpoints in a single file. * Fix prefix on the tickets. ### `consent` * Support for deactivating consent for specific services. ### `consentAdmin` * Support for the SAML SP module. ### `core` * New filter: [`core:PHP`](./core:authproc_php), which allows processing of attributes with arbitrary PHP code. * Support for multiple target attributes in [`core:AttributeMap`](./core:authproc_attributemap). * New filter: [`core:ScopeFromAttribute`](./core:authproc_scopefromattribute), which allows the creation an attribute based on the scope of another attribute. * Support for a target attribute in [`core:AttributeAlter`](./core:authproc_attributealter). ### `discoPower` * Support for new scoring algorithm. ### `ldap` * SASL support in LDAPMulti ### `ldapstatus` * This module was removed, as it was very specific for Feide. ### `multiauth` * Support for specifying the target authentication source through a request parameter. ### `oauth` * Configurable which authentication source should be used. ### `openidProvider` * OpenID 2.0 support. * XRDS generation support. ### `saml` * Support for specifying parameters for authentication request. * Add AttributeConsumingService to generated metadata. * The two SPSSODescriptor elements in the metadata has been merged. ## Version 1.5.1 Released 2010-01-08. * Fix security vulnerability due to insecure temp file creation: * statistics: The logcleaner script outputs to a file in /tmp. * InfoCard: Saves state directly in /tmp. Changed to the SimpleSAMLphp temp directory. * openidProvider: Default configuration saves state information in /tmp. Changed to '/var/lib/simplesamlphp-openid-provider'. * SAML 1 artifact support: Saves certificates temporarily in '/tmp/simplesaml', but directory creation was insecure. * statistics: Handle new year wraparound. * Dictionary updates. * Fix bridged logout. * Some documentation updates. * Fix all metadata to use assignments to arrays. * Fix $session->getIdP(). * Support AuthnContextClassRef in saml-module. * Do not attempt to send logout request to an IdP that does not support logout. * LDAP: Disallow bind with empty password. * LDAP: Assume that LDAP_NO_SUCH_OBJECT is an error due to invalid username/password. * statistics: Fix configuration template. * Handle missing authority in idp-hosted metadata better. ## Version 1.5 Released 2009-11-05. Revision 1937. * New API for SP authentication. * Make use of the portal module on the frontpage. * SQL datastore. * Support for setting timezone in config (instead of php.ini). * Logging of PHP errors and notices to SimpleSAMLphp log file. * Improve handling of unhandled errors and exceptions. * Admin authentication through authentication sources. * Various bugfixes & cleanups. * Translation updates. * Set the dropdown list as default for built in disco service. ### New modules: * `adfs` * [`authorize`](./authorize:authorize) * `authtwitter` * [`autotest`](./autotest:test) * `exampleattributeserver` * `metaedit` * [`multiauth`](./multiauth:multiauth) * `oauth` * [`openidProvider`](./openidProvider:provider) * [`radius`](./radius:radius) * [`saml`](./saml:sp) ### `aggregator`: * Add ARP + ARP signing functionality to the aggregator. * Improvements to the aggregator module. Added documentation, and re-written more OO-oriented. * Add support for reconstructing XML where XML for an entity is already cached. * Add support for excluding tags in metadata aggregator. ### `AuthMemCookie`: * Delete the session cookie when deleting the session. * Support for authentication sources. * Set expiry time of session data when saving to memcache. * Support multiple memcache servers. ### `cas`: * Added support for attributes in . ### `consent`: * Support for hiding some attribute values. ### `consentAdmin`: * Added config option to display description. ### `core`: * New WarnShortSSOInterval filter. ### `discopower`: * Live search in discopower-module. ### `ldap`: * Support for proxy authentication. * Add 'debug' and 'timeout' options. * Privilege separation for LDAP attribute retrieval. * Allow search.base to be an array. * (LDAPMulti) Add support for including the organization as part of the username. ### `ldapstatus`: * Do a connect-test to all ip-addresses for a hostname. * Check wheter hostname exists before attempting to connect. * hobbit output. * Check schema version. * Add command line tab to single LDAP status page for easier debugging. ### `logpeek`: * Blockwise reading of logfile for faster execution. ### `metarefresh`: * Adding support for generating Shibboleth ARP files. * Add 'serialize' metadata format. ### `preprodwarning`: * Don't show warning in passive request. * Focus on continue-button. ### SAML: * Support for multiple AssertionConsumerService endpoints. * SAML 1 artifact support on the SP side. * New SAML authentication module. * Deprecation of www/saml2/sp & www/shib13/sp. * Support for encrypted NameID. * NameIDPolicy replaces NameIDFormat. * Better support for IdP initiated SSO and bookmarked login pages. * Improvements to iframe logout page. * Scoping support. * New library for SAML 2 messages. * Support for transporting errors from the IdP to the SP. * Sign both the assertion and the response element by default. * Support for sending XML attribute values from the IdP. ### `statistics`: * Extended Google chart encoding... Add option of alternative compare plot in graph... * Added support for Ratio type reports in the statistics module.. * Changed default rule to sso. * Added incremental aggregation, independent time resolution from rule def, combined coldefs and more. * Add DST support in date handler. Added summary columns per delimiter. Added pie chart. +++ * Log first SSO to a service during a session. ## Version 1.4 Released 2009-03-12. Revision 1405. Updates to `config.php`. Please check for updates in your local modified configuration. * Language updates * Documentation update. New authencation source API now default and documented. * New authentication source (new API): * LDAP * LDAPMulti * YubiKey authentication source. (Separate module) * Facebook authentication source. (Separate module) * New Authentication Processing Filter: * AttributeAlter * AttributeFilter * AttributeMap * Smartname. does it best to guess the full name of the user based on several attributes. * Language adaptor: allow adopting UI by preferredLanguage SAML 2.0 Attribute both on the IdP and the SP. And if the user selects a lanauge, this can be sent to the SP as an attribute. * New module: portal, allows you to created tabbed interface for custom pages within SimpleSAMLphp. In example user consent management and attribute viewer. * New module: ldapstatus. Used by Feide to monitor connections to a large list of LDAP connections. Contact Feide on details on how to use. * ldapstatus also got certificate check capabilities. * New module: MemcacheMonitor: Show statistics for memcache servers. * New module: DiscoPower. A tabbed discovery service module with alot of functionality. * New module: SAML 2.0 Debugginer. An improved version of the one found on rnd.feide.no earlier is not included in SimpleSAMLphp allowing you to run it locally. * New module: Simple Consent Amdin module that have one button to remove all consent for one user. * New module: Consent Administration. Contribution from Wayf. * We also have a consent adminstration module that we use in Feide that is not checked in to subversion. * New module: logpeek. Lets administrator lookup loglines matching a TRackID. * New module: PreprodWarning: Adding a warning to users that access a preprod system. * New module: CAS Server * New module: Aggregator: Aggregates metadata. Used in Kalmar Union. * New module: Metarefresh, download, parses and consumes metadata. * New module: SanityCheck. Checks if things looks good and reports bad configuration etc. * New module: Cron. Will perform tasks regularly. * Module: SAML2.0. SAML 2.0 SP implemented as an module. Yet not documented how to use, but all SAML 2.0 SP functionality may be moved out to this module for better modularization. * New module: statistics. Parses STAT log files, and aggregates based on a generic rule system. Output is stored in aggregated text files, and a frontend is included to present statistics with tables and graphs. Used sanitycheck and cron. * Added support for IdP initiated SSO. * Added support for IdP-initiated SLO with iFrame type logout. * Major updates to iFrame AJAX SLO. Improved user experience. * iFrame AJAX SLO is not safe against simulanous update of the session. * Added support for bookmarking login pages. By adding enough information in the URL to be able to bootstrap a new IdP-initiated SSO and sending. * Major updates to the infocard module. * Added some handling of isPassive with authentication processing filters. * More localized UI. * New login as administrator link on frontpage. * Tabbed frontpage. Restructured. * Simplifications to the theming and updated documentation on theming SimpleSAMLphp. * Attribute presentation hook allows you to tweak attributes before presentation in the attribute viewers. Used by Feide to group orgUnit information in a hieararchy. * Verification of the Receipient attribute in the response. Will improve security if for some reason an IdP is not includeding sufficient Audience restrictions. * Added hook to let modules tell about themself moduleinfo hook. * Improved cron mails * Improved sanity check exception handling * Preserver line breaks in stack trace UI * Improvements to WS-Federation support: dynamic realms, logout etc. * Better handling of presentation of JPEG photos as attributes. * Support limiting size of attribute retrieved from LDAP. * Added notes about how to aggregate and consume metadata. Just a start. * Large improvements to Configuration class, and config helper functions. * STAT logging is moved into separate authenticaion processing filter. * Fix for NoPassive responses to Google Apps with alternative NameIDFormats. * LDAP module allows to search multiple searchbases. * All documentation is converted from docbook to markdown format. * Added headers to not allow google to index pages. * Added check on frontpage for magic quotes * Added statistic loggging to Consent class. * Improvements to Exception handler in LDAP class, and better logging. * LDAP class supports turning on LDAP-debug logging. * Much improvements to SAML 2.0 Metadata generation and parsing. * Adding more recent jquery library. * Generic interface for including jquery dependencies in template headers. * Improved UI on default theme * Fix for session duration in the Conditions element in the Assertion (SAML 2.0). * Updated with new Feide IdP metadata in metadata-templates ## Version 1.3 Released 2008-11-04. Revision 973. Configuration file `config.php` should not include significant changes, except one language added. ### New features * Documentation update * Added new language. Now there are two different portugese dialects. * Consent "module" modified. Now added support for preselecting the checkbox by a configuration parameter. Consent module supports including attributs values (possible to configure). * CSS and look changed. Removed transparency to fix problem for some browsers. * The login-admin authentication module does not ask for username any more. * Added support for persistent NameID Format. (Added by Hans ZAndbelt) * Added experimental SAML 2.0 SP AuthSource module. * More readable XML output formatting. In example metadata. * Better support for choosing whether or not to sign authnrequest. Possible to specify both at SP hosted and IdP remote. * Adding more example metadata in metadata-templates. * Improved e-mails sent from SimpleSAMLphp. Now both plain text and html. * Configuration class may return information about what version. * iFrame AJAX SLO improved. Now with non-javascript failback handling. ### Bug fixes * Fixed warning with XML validator. * Improved loading of private/public keys in XML/Signer. * Improvements to CAS module. * Fixed memcache stats. ## Version 1.2 Released 2008-09-26. Revision 899. There are some changes in the configuration files from version 1.1 to 1.2. `/simplesaml/admin/config.php` should be used to check what options have changed. When you upgrade from an previous version you should copy `authsources.php` from `config-templates` into `config` directory. There are also some changes to the templates. If you have any custom templates, they should be updated to match the ones included. Of notable changes is that the `t(...)`-functtes, they should be updated to match the ones included. Of notable changes is that the `t(...)`-function has been simplified, and takes far fewer parameters. It is backwardscompatible, but will write a warning to the log until updated. The backwards compatibility will be removed in a future version. ### New features * Experimental support for modules. Currently modules can contain custom authentication sources, authentication processing filters and themes. * An generic SQL autentication module added for those who store their users in an SQL database. * Limited support for validating against a CA root certificate. The current implementation only supports cases where the certificate is directly signed by the CA. * Allow an IdP to have multiple valid certificate fingerprints, to allow for easier updating of certificates. * Shibboleth 1.3 authentication for Auth MemCookie. * Support for link to privacy policy on consent-pages. * Customizable initial focus on consent-page. * Almost all pages should be translateable. * Allow SAML 2.0 SP to handle error replies from IdP. * PostgreSQL support for consent storage. * Add support for encrypted private keys. * Proof-of-concept MetaShare service, for easy publishing and sharing of metadata. ### Bug fixes * Fixed generated SAML 2.0 metadata to be correct. * Fixed logout for Auth MemCookie. * Sign SAML 2.0 authentication response on failure (such as NoPassive). * Fixes for IsPassive in the SAML 2.0 IdP. * Fix default syslog configuration on Windows. * Fix order of signing and encryption of SAML 2.0 responses * Fix generated metadata for Shib 1.3 * Fix order of elements in encrypted assertions to be schema compliant. * Fix session index sent to SAML 2.0 SPs. * Remember SAML 2.0 NameID sent to SPs, and include it in logout requests. ## Version 1.1 Released 2008-06-19. Revision 673. When upgrading to version 1.1 from version 1.0, you should update the configuration files. Many options have been added, and some have moved or removed. The new configuration check page: `/simplesaml/admin/config.php` may be useful for determining what should be updated. Also note that the `language.available` option in `config.php` should be updated to reflect the new languages which have been added. There are also several changes to the template files. If you have done any customizations to these, you should test them to make sure that they still work. Some changes, such as allowing the users to save the IdP choice they make in the discovery service, will not work without updating the templates. New localizations in version 1.1: Sami, Svenska (swedish), Suomeksi (finnish), Nederlands, Luxembourgish, Slovenian, Hrvatski (Croatian), Magyar (Hungarian). ### New features * Add support for saving the users choice of IdP in the IdP discovery service. * Add a config option for whether the Response element or the Assertion element in the response should be signed. * Make it easier to add attribute alteration functions. * Added support for multiple languages in metadata name and description (for IdP discovery service). * Added configuration checker for checking if configuration files should be updated. * Add support for icons in IdP discovery service. * Add support for external IdP discovery services. * Support password encrypted private keys. * Added PHP autoloading as the preferred way of loading the SimpleSAMLphp library. * New error report script which will report errors to the `technicalcontact_email` address. * Support lookup of the DN of the user who is logging in by searching for an attribute when using the LDAP authentication module. * Add support for fetching name and description of entities from XML metadata files. * Support for setting custom AttributeNameFormats. * Support for signing generated metadata. * Support for signature validation of metadata. * Added consent support for Shib 1.3 logging. * Added errorlog logging handler for logging to the default Apache error log. * Added support for WS-Federation single signon. * Allow `session_save_path` to be overridden by setting the `session.phpsession.savepath` option in `config.php`. * Add support for overriding autogenerated metadata values, such as the `AssertionConsumerService` address. * Added IsPassive support in the SAML 2.0 IdP. * Add attribute filter for generating eduPersonTargetedID attribute. * Add support for validation of sent and received messages and metadata. * Add support for dynamic metadata loading with cache. * Add support for dynamic generation of entityid and metadata. * Added wayf.dk login module. * Add support for encrypting and decrypting assertions. * CAS authentication module: Add support for serviceValidate. * CAS authentication module: Add support for getting attributes from response by specifying XPath mappings. * Add support for specifying a certificate in the `saml20-idp-remote` metadata instead of a fingerprint. * Add an attribute alter function for dynamic group generation. * Add support for attribute processing in SAML 2 SP. * Added tlsclient authentication module. * Allow the templates to override the header and footer of pages. * Major improvements to the Feide authentication module. * Add support for ForceAuthn in the SAML 2.0 IdP. * Choose language based on the languages the user has selected in the web browser. * Added fallback to base language if translation isn't found. ### Bug fixes * Modified IdP discovery service to support Shibboleth 2.0 SP. * Fix setcookie warning for PHP version \< 5.2. * Fix logout not being performed for Auth MemCache sometimes. * Preserve case of attribute names during LDAP attribute retrival. * Fix IdP-initiated logout. * Ensure that changed sessions with changed SP associations are written to memcache. * Prevent infinite recursion during logging. * Don't send the relaystate from the SP which initiated the logout to other SPs during logout. * Prevent consent module from revealing DB password when an error occurs. * Fix logout with memcache session handler. * Allow new session to be created in login modules. * Removed the strict parameter from base64\_decode for PHP 5.1 compatibility. ## Version 1.0 Released 2008-03-28. Revision 470. ## Version 0.5 Released 2007-10-15. Revision 28. ### Warning Both `config.php` and metadata format are changed. Look at the templates to understand the new format. * Documentation is updated! * Metadata files made tidier. Unused entries removed. Look at the new templates on how to change your existing metadata. * Support for sending metadata by mail to Feide. Automatically detecting whether you have configured Feide as the default IdP or not. * Improved SAML 2.0 Metadata generation * Added support for Shibboleth 1.3 IdP functionality (beta, contact me if any problems) * Added RADIUS authentication backend * Added support for HTTP-Redirect debugging when enable `debug=true` * SAML 2.0 SP example now contains a logout page. * Added new authentication backend with support for multiple LDAP based on which organization the user selects. * Added SAML 2.0 Discovery Service * Initial 'proof of concept' implementation of "User consent on attribute release" * Fixed some minor bugs. ## Version 0.4 Released 2007-09-14. Revision X. * Improved documentation * Authentication plugin API. Only LDAP authenticaiton plugin is included, but it is now easier to implement your own plugin. * Added support for SAML 2.0 IdP to work with Google Apps for Education. Tested. * Initial implementation of SAML 2.0 Single Log Out functionality both for SP and IdP. Seems to work, but not yet well-tested. * Added support for bridging SAML 2.0 to SAML 2.0. * Added some time skew offset to the NotBefore timestamp on the assertion, to allow some time skew between the SP and IdP. * Fixed Browser/POST page to automaticly submit, and have fall back functionality for user agents with no javascript support. * Fixed some bug with warning traversing Shibboleth 1.3 Assertions. * Fixed tabindex on the login page of the LDAP authentication module to allow you to tab from username, to password and then to submit. * Fixed bug on autodiscovering hostname in multihost environments. * Cleaned out some debug messages, and added a debug option in the configuration file. This debug option let's you turn on the possibility of showing all SAML messages to users in the web browser, and manually submit them. * Several minor bugfixes. simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.5.md0000644000000000000000000000235214042503475022371 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.5 =================================== * `SimpleSAML_Session::isValid()` If your code calls `$session->isValid()` without an argument, you will now have to update it to pass an argument (probably `saml2`). The reason for this change is that calling `$session->isValid()` without an argument can easily create a security hole. * We have introduced a new module for SAML authentication. This authentication module supports both SAML 1.1 and SAML 2.0 IdPs. We have also added a new authentication framework which should replace the previous redirects to the initSSO-scripts. Relating to this change, we have also deprecated the `initSSO`-scripts for SAML 1.1 and SAML 2.0 authentication. The old methods will still be supported for a while, but new code should probably use the new code. See the [migration guide](simplesamlphp-sp-migration) for more information about this. * The `request.signing` option has been removed. That option was replaced with the `redirect.sign` and `redirect.validate` options, and has been depreceated for one year. * The `aggregator` module's configuration file has changed name. It was changed from `aggregator.php` to `module_aggregator.php`. simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.9.md0000644000000000000000000000227714042503475022403 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.9 =================================== * The OpenID client "linkback" URL has changed from `.../module.php/openid/consumer.php` to `.../module.php/openid/linkback.php`. * Support for CA path validation has been removed from SAML 2.0. * The X-Frame-Options has been added to the default templates, to prevent the pages from being loaded in iframes. * Access permissions of generated files are now restricted to the current user. * The code to set cookies now requires PHP version >= 5.2. (PHP version 5.2.0 or newer has been the only supported version for a while, but it has in some cases been possible to run SimpleSAMLphp with older versions.) * It used to be possible to set an array of endpoints for the SingleSignOnService in `saml20-idp-hosted.php`. That is no longer supported. * The `aselect` module has been replaced with a new module. The new module gives us better error handling and support for request signing, but we lose support for A-Select Cross. * There has been various fixes in the session exipration handling. As a result of this, sessions may get a shorter lifetime (if the IdP places a limit on the lifetime, this limit will now be honored). simplesamlphp-1.19.1/docs/simplesamlphp-authproc.md0000644000000000000000000002620014042503475021136 0ustar rootrootAuthentication Processing Filters in SimpleSAMLphp ================================================== In SimpleSAMLphp, there is an API where you can *do stuff* at the IdP after authentication is complete, and just before you are sent back to the SP. The same API is available on the SP, after you have received a successful Authentication Response from the IdP and before you are sent back to the SP application. Authentication processing filters postprocess authentication information received from authentication sources. It is possible to use this for additional authentication checks, requesting the user's consent before delivering attributes about the user, modifying the user's attributes, and other things which should be performed before returning the user to the service provider he came from. Examples of neat things to do using Authentication Processing Filters: * Filter out a subset of available attributes that are sent to a SP. * Modify the name of attributes. * Generate new attributes that are composed of others, for example eduPersonTargetedID. * Ask the user for consent, before the user is sent back to a service. * Implement basic Access Control on the IdP (not neccessarily a good idea), limiting access for some users to some SPs. Be aware that Authentication Proccessing Filters do replace some of the previous features in SimpleSAMLphp, named: * `attributemap` * `attributealter` * `attribute filter` Later in this document, we will desribe in detail the alternative Authentication Proccessing Filters that will replicate these functionalities. How to configure Auth Proc Filters ---------------------------------- *Auth Proc Filters* can be set globally, or to be specific for only one SP or one IdP. That means there are five locations where you can configure *Auth Proc Filters*: * Globally in `config.php` * On the SP: Specific for only the SP in `authsources.php` * On the SP: Specific for only one remote IdP in `saml20-idp-remote` or `shib13-idp-remote` * On the IdP: Specific for only one hosted IdP in `saml20-idp-hosted` or `shib13-idp-hosted` * On the IdP: Specific for only one remote SP in `saml20-sp-remote` or `shib13-sp-remote` The configuration of *Auth Proc Filters* is a list of filters with priority as *index*. Here is an example of *Auth Proc Filters* configured in `config.php`: 'authproc.idp' => [ 10 => [ 'class' => 'core:AttributeMap', 'addurnprefix' ], 20 => 'core:TargetedID', 50 => 'core:AttributeLimit', 90 => [ 'class' => 'consent:Consent', 'store' => 'consent:Cookie', 'focus' => 'yes', 'checked' => TRUE ], ], This configuration will execute *Auth Proc Filters* one by one, with the priority value in increasing order. When *Auth Proc Filters* is configured in multiple places, in example both globally, in the hosted IdP and remote SP metadata, then the list is interleaved sorted by priority. The most important parameter of each item on the list is the *class* of the *Auth Proc Filter*. The syntax of the class is `modulename:classname`. As an example the class definition `core:AttributeLimit` will be expanded to look for the class `\SimpleSAML\Module\core\Auth\Process\AttributeLimit`. The location of this class file *must* then be: `modules/core/lib/Auth/Process/AttributeLimit.php`. You will see that a bunch of useful filters is included in the `core` module. In addition the `consent` module that is included in the SimpleSAMLphp distribution implements a filter. Beyond that, you are encouraged to create your own filters and share with the community. If you have created a cool *Auth Proc Filter* that does something useful, let us know, and we may share it on the [SimpleSAMLphp web site][]. [SimpleSAMLphp web site]: http://simplesamlphp.org When you know the class definition of a filter, and the priority, the simple way to configure the filter is: 20 => 'core:TargetedID', This is analogous to: 20 => [ 'class' => 'core:TargetedID' ], Some *Auth Proc Filters* have optional or required *parameters*. To send parameters to *Auth Proc Filters*, you need to choose the second of the two alernatives above. Here is an example of provided parameters to the consent module: 90 => [ 'class' => 'consent:Consent', 'store' => 'consent:Cookie', 'focus' => 'yes', 'checked' => TRUE ], ### Filters in `config.php` Global *Auth Proc Filters* are configured in the `config.php` file. You will see that the config template already includes an example configuration. There are two config parameters: * `authproc.idp` and * `authproc.sp` The filters in `authproc.idp` will be executed at the IdP side regardless of which IdP and SP entity that is involved. The filters in `authproc.sp` will be executed at the SP side regardless of which SP and IdP entity that is involved. ### Filters in metadata Filters can be added both in `hosted` and `remote` metadata. Here is an example of a filter added in a metadata file: '__DYNAMIC:1__' => [ 'host' => '__DEFAULT_', 'privatekey' => 'example.org.pem', 'certificate' => 'example.org.crt', 'auth' => 'feide', 'authproc' => [ 40 => 'core:TargetedID', ], ] The example above is in `saml20-idp-hosted`. Auth Proc Filters included in the SimpleSAMLphp distribution ------------------------------------------------------------ The following filters are included in the SimpleSAMLphp distribution: - [`core:AttributeAdd`](./core:authproc_attributeadd): Add attributes to the response. - [`core:AttributeCopy`](./core:authproc_attributecopy): Copy existing attributes to the response. - [`core:AttributeAlter`](./core:authproc_attributealter): Do search-and-replace on attributevalues. - [`core:AttributeLimit`](./core:authproc_attributelimit): Limit the attributes in the response. - [`core:AttributeMap`](./core:authproc_attributemap): Change the name of the attributes. - [`core:AttributeRealm`](./core:authproc_attributerealm): (deprecated) Create an attribute with the realm of the user. - [`core:AttributeValueMap`](./core:authproc_attributevaluemap): Map attribute values to new values and attribute name. - [`core:Cardinality`](./core:authproc_cardinality): Ensure the number of attribute values is within the specified multiplicity. - [`core:CardinalitySingle`](./core:authproc_cardinalitysingle): Ensure the correct cardinality of single-valued attributes. - [`core:GenerateGroups`](./core:authproc_generategroups): Generate a `group` attribute for the user. - [`core:LanguageAdaptor`](./core:authproc_languageadaptor): Transfering language setting from IdP to SP. - [`core:PHP`](./core:authproc_php): Modify attributes with custom PHP code. - [`core:ScopeAttribute`](./core:authproc_scopeattribute): Add scope to attribute. - [`core:ScopeFromAttribute`](./core:authproc_scopefromattribute): Create a new attribute based on the scope on a different attribute. - [`core:StatisticsWithAttribute`](./core:authproc_statisticswithattribute): Create a statistics logentry. - [`core:TargetedID`](./core:authproc_targetedid): Generate the `eduPersonTargetedID` attribute. - [`core:WarnShortSSOInterval`](./core:authproc_warnshortssointerval): Give a warning if the user logs into the same SP twice within a few seconds. - [`saml:AttributeNameID`](./saml:nameid): Generate custom NameID with the value of an attribute. - [`saml:AuthnContextClassRef`](./saml:authproc_authncontextclassref): Set the authentication context in the response. - [`saml:ExpectedAuthnContextClassRef`](./saml:authproc_expectedauthncontextclassref): Verify the user's authentication context. - [`saml:FilterScopes`](./saml:filterscopes): Filter attribute values with scopes forbidden for an IdP. - [`saml:NameIDAttribute`](./saml:nameidattribute): Create an attribute based on the NameID we receive from the IdP. - [`saml:PersistentNameID`](./saml:nameid): Generate persistent NameID from an attribute. - [`saml:PersistentNameID2TargetedID`](./saml:nameid): Store persistent NameID as eduPersonTargetedID. - [`saml:TransientNameID`](./saml:nameid): Generate transient NameID. See the [Third-party modules](https://simplesamlphp.org/modules) page on the SimpleSAMLphp website for externally hosted modules that may provide a processing filter. Writing your own Auth Proc Filter --------------------------------- Look at the included *Auth Proc Filters* as examples. Copy the classes into your own module and start playing around. Authentication processing filters are created by creating a class under `Auth/Process/` in a module. This class is expected to subclass `\SimpleSAML\Auth\ProcessingFilter`. A filter must implement at least one function - the `process(&$request)`-function. This function can access the `$request`-array to add, delete and modify attributes, and can also do more advanced processing based on the SP/IdP metadata (which is also included in the `$request`-array). When this function returns, it is assumed that the filter has finished processing. If a filter for some reason needs to redirect the user, for example to show a web page, it should save the current request. Upon completion it should retrieve the request, update it with the changes it is going to make, and call `\SimpleSAML\Auth\ProcessingChain::resumeProcessing`. This function will continue processing the next configured filter. Requirements for authentication processing filters: - Must be derived from the `\SimpleSAML\Auth\ProcessingFilter`-class. - If a constructor is implemented, it must first call the parent constructor, passing along all parameters, before accessing any of the parameters. In general, only the $config parameter should be accessed. - The `process(&$request)`-function must be implemented. If this function completes, it is assumed that processing is completed, and that the $request array has been updated. - If the `process`-function does not return, it must at a later time call `\SimpleSAML\Auth\ProcessingChain::resumeProcessing` with the new request state. The request state must be an update of the array passed to the `process`-function. - No pages may be shown to the user from the `process`-function. Instead, the request state should be saved, and the user should be redirected to a new page. This must be done to prevent unpredictable events if the user for example reloads the page. - No state information should be stored in the filter object. It must instead be stored in the request state array. Any changes to variables in the filter object may be lost. - The filter object must be serializable. It may be serialized between being constructed and the call to the `process`-function. This means that, for example, no database connections should be created in the constructor and later used in the `process`-function. *Note*: An Auth Proc Filter will not work in the "Test authentication sources" option in the web UI of a SimpleSAMLphp IdP. It will only be triggered in conjunction with an actual SP. So you need to set up an IdP *and* and SP when testing your filter. Don't hestitate to ask on the SimpleSAMLphp mailinglist if you have problems or questions, or want to share your *Auth Proc Filter* with others. simplesamlphp-1.19.1/docs/simplesamlphp-authsource.md0000644000000000000000000001332114042503475021473 0ustar rootrootCreating authentication sources =============================== All authentication sources are located in the `lib/Auth/Source/` directory in a module, and the class name is `\SimpleSAML\Module\\Auth\Source\`. The authentication source must extend the `\SimpleSAML\Auth\Source` class or one of its subclasses. The "entry point" of an authentication source is the `authenticate()`-function. Once that function is called, the authentication module can do whatever it wishes to do. There are only two requirements: - Never show any pages to the user directly from within the `authenticate()`-function. (This will lead to problems if the user decides to reload the page.) - Return control to SimpleSAMLphp after authenticating the user. If the module is able to authenticate the user without doing any redirects, it should just update the state-array and return. If the module does a redirect, it must call `\SimpleSAML\Auth\Source::completeAuth()` with the updated state array. Everything else is up to the module. If the module needs to redirect the user, for example because it needs to show the user a page asking for credentials, it needs to save the state array. For that we have the `\SimpleSAML\Auth\State` class. This is only a convenience class, and you are not required to use it (but its use is encouraged, since it handles some potential pitfalls). Saving state ------------ The `\SimpleSAML\Auth\State` class has two functions that you should use: `saveState($state, $stage)`, and `loadState($id, $stage)`. The `$stage` parameter must be an unique identifier for the current position in the authentication. It is used to prevent a malicious user from taking a state you save in one location, and give it to a different location. The `saveState()`-function returns an id, which you should pass to the `loadState()`-function later. Username/password authentication -------------------------------- Since username/password authentication is quite a common operation, a base class has been created for this. This is the `\SimpleSAML\Module\core\Auth\UserPassBase` class, which is can be found as `modules/core/lib/Auth/UserPassBase.php`. The only function you need to implement is the `login($username, $password)`-function. This function receives the username and password the user entered, and is expected to return the attributes of that user. If the username or password is incorrect, it should throw an error saying so: throw new \SimpleSAML\Error\Error('WRONGUSERPASS'); "[Implementing custom username/password authentication](./simplesamlphp-customauth)" describes how to implement username/password authentication using that base class. Generic rules & requirements ---------------------------- - Must be derived from the `\SimpleSAML\Auth\Source`-class. **Rationale**: - Deriving all authentication sources from a single base class allows us extend all authentication sources by extending the base class. - If a constructor is implemented, it must first call the parent constructor, passing along all parameters, before accessing any of the parameters. In general, only the $config parameter should be accessed when implementing the authentication source. **Rationale**: - PHP doesn't automatically call any parent constructor, so it needs to be done manually. - The `$info`-array is used to provide information to the `\SimpleSAML\Auth\Source` base class, and therefore needs to be included. - Including the `$config`-array makes it possible to add generic configuration options that are valid for all authentication sources. - The `authenticate(&$state)`-function must be implemented. If this function completes, it is assumed that the user is authenticated, and that the `$state`-array has been updated with the user's attributes. **Rationale**: - Allowing the `authenticate()`-function to return after updating the `$state`-array enables us to do authentication without redirecting the user. This can be used if the authentication doesn't require user input, for example if the authentication can be done based on the IP-address of the user. - If the `authenticate`-function does not return, it must at a later time call `\SimpleSAML\Auth\Source::completeAuth` with the new state array. The state array must be an update of the array passed to the `authenticate`-function. **Rationale**: - Preserving the same state array allows us to save information in that array before the authentication starts, and restoring it when authentication completes. - No pages may be shown to the user from the `authenticate()`-function. Instead, the state should be saved, and the user should be redirected to a new page. **Rationale**: - The `authenticate()`-function is called in the context of a different PHP page. If the user reloads that page, unpredictable results may occur. - No state information about any authentication should be stored in the authentication source object. It must instead be stored in the state array. Any changes to variables in the authentication source object may be lost. **Rationale**: - This saves us from having to save the entire authentication object between requests. Instead, we can recreate it from the configuration. - The authentication source object must be serializable. It may be serialized between being constructed and the call to the `authenticate()`-function. This means that, for example, no database connections should be created in the constructor and later used in the `authenticate()`-function. **Rationale**: - If parsing the configuration and creating the authentication object is shown to be a bottleneck, we can cache an initialized authentication source. simplesamlphp-1.19.1/docs/simplesamlphp-install.md0000644000000000000000000004723414042503475020771 0ustar rootrootSimpleSAMLphp Installation and Configuration ============================================ This document is part of the SimpleSAMLphp documentation suite. * [List of all SimpleSAMLphp documentation](https://simplesamlphp.org/docs) * [SimpleSAMLphp homepage](https://simplesamlphp.org) This document covers the installation of the latest stable version of SimpleSAMLphp. If you want to install the development version, take a look at the instructions for [installing SimpleSAMLphp from the repository](simplesamlphp-install-repo). Prerequisites ------------- * A web server capable of executing PHP scripts. * PHP version >= 7.1.0. * Support for the following PHP extensions: * Always required: `date`, `dom`, `hash`, `libxml`, `openssl`, `pcre`, `SPL`, `zlib`, `json`, `mbstring` * When automatically checking for latest versions, and used by some modules: `cURL` * When authenticating against an LDAP server: `ldap` * When authenticating against a RADIUS server: `radius` * When using the native PHP session handler: `session` * When saving session information to a memcache server: `memcache` * When using databases: * Always required: `PDO` * Database driver: (`mysql`, `pgsql`, ...) * Support for the following PHP packages: * When saving session information to a Redis server: `predis` What actual packages are required for the various extensions varies between different platforms and distributions. Download and install SimpleSAMLphp ---------------------------------- The most recent release of SimpleSAMLphp can always be found at [https://simplesamlphp.org/download](https://simplesamlphp.org/download). Go to the directory where you want to install SimpleSAMLphp and extract the archive file you just downloaded: ``` cd /var tar xzf simplesamlphp-x.y.z.tar.gz mv simplesamlphp-x.y.z simplesamlphp ``` ## Upgrading from a previous version of SimpleSAMLphp Before starting the upgrade, review the relevant [upgrade notes](simplesamlphp-upgrade-notes) for any relevant changes. Extract the new version: ``` cd /var tar xzf simplesamlphp-x.y.z.tar.gz ``` Copy the configuration files from the previous version (in case the configuration directory is inside SimpleSAMLphp, keep reading for other alternatives): ``` cd /var/simplesamlphp-x.y.z rm -rf config metadata cp -rv ../simplesamlphp/config config cp -rv ../simplesamlphp/metadata metadata ``` If you have installed any [third-party modules](https://simplesamlphp.org/modules) or [customised the theme](simplesamlphp-theming.md), you should check whether your third-party modules need upgrading and then copy or replace those directories too. Replace the old version with the new version: ``` cd /var mv simplesamlphp simplesamlphp.old mv simplesamlphp-x.y.z simplesamlphp ``` If the format of the config files or metadata has changed from your previous version of SimpleSAMLphp (check the upgrade notes), you may have to update your configuration and metadata after updating the SimpleSAMLphp code. ### Upgrading configuration files A good approach is to run a `diff` between your previous `config.php` file and the new `config.php` file located in `config-templates/config.php`, and apply relevant modifications to the new template. This will ensure that all new entries in the latest version of config.php are included, as well as preserve your local modifications. ### Upgrading metadata files Most likely the metadata format is backwards compatible. If not, you should receive a very clear error message at startup indicating how and what you need to update. You should look through the metadata in the `metadata-templates` directory after the upgrade to see whether recommended defaults have been changed. Configuration ------------- ### Location of configuration files By default, SimpleSAMLphp looks for its configuration in the `config` directory in the root of its own directory. This has some drawbacks, like making it harder to update SimpleSAMLphp or to install it as a composer dependency, or to package it for different operating systems. In order to avoid this limitations, it is possible to specify an alternative location for the configuration directory by setting the `SIMPLESAMLPHP_CONFIG_DIR` environment variable to point to this location. This way, the configuration directory doesn't need to be inside the library's directory, making it easier to manage and to update. The simplest way to set this environment variable is to set it in your web server's configuration. See the next section for more information. Configuring Apache ------------------ Examples below assume that SimpleSAMLphp is installed in the default location, `/var/simplesamlphp`. You may choose another location, but this requires a path update in a few files. See Appendix _Installing SimpleSAMLphp in alternative locations_ for more details. The only subdirectory of `SimpleSAMLphp` that needs to be accessible from the web is `www`. There are several ways of exposing SimpleSAMLphp depending on the way web sites are structured on your Apache web server. The following is just one possible configuration. Find the Apache configuration file for the virtual hosts where you want to run SimpleSAMLphp. The configuration may look like this: ``` ServerName service.example.com DocumentRoot /var/www/service.example.com SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/simplesamlphp/config Alias /simplesaml /var/simplesamlphp/www Require all granted ``` Note the `Alias` directive, which gives control to SimpleSAMLphp for all urls matching `http(s)://service.example.com/simplesaml/*`. SimpleSAMLphp makes several SAML interfaces available on the web; all of them are accessible through the `www` subdirectory of your SimpleSAMLphp installation. You can name the alias whatever you want, but the name must be specified in the `baseurlpath` configuration option in the `config.php` file of SimpleSAMLphp as described in [the section called “SimpleSAMLphp configuration: config.php”](#section_6 "SimpleSAMLphp configuration: config.php"). Here is an example of how this configuration may look like in `config.php`: ``` $config = [ [...] 'baseurlpath' => 'simplesaml/', [...] ] ``` Note also the `SetEnv` directive in the Apache configuration. It sets the `SIMPLESAMLPHP_CONFIG_DIR` environment variable, in this case, to the default location for the configuration directory. You can omit this environment variable, and SimpleSAMLphp will then look for the `config` directory inside its own directory. If you need to move your configuration to a different location, you can use this environment variable to tell SimpleSAMLphp where to look for configuration files. This works only for the `config` directory. If you need your metadata to be in a different directory too, use the `metadatadir` configuration option to specify the location. This is just the basic configuration to get things working. For a checklist further completing your documentation, please see [Maintenance and configuration: Apache](simplesamlphp-maintenance#section_5). Configuring Nginx ------------------ Examples below assume that SimpleSAMLphp is installed in the default location, `/var/simplesamlphp`. You may choose another location, but this requires a path update in a few files. See Appendix _Installing SimpleSAMLphp in alternative locations_ for more details. The only subdirectory of `SimpleSAMLphp` that needs to be accessible from the web is `www`. There are several ways of exposing SimpleSAMLphp depending on the way web sites are structured on your Nginx web server. The following is just one possible configuration. Find the Nginx configuration file for the virtual hosts where you want to run SimpleSAMLphp. The configuration may look like this: ``` server { listen 443 ssl; server_name idp.example.com; ssl_certificate /etc/pki/tls/certs/idp.example.com.crt; ssl_certificate_key /etc/pki/tls/private/idp.example.com.key; ssl_protocols TLSv1.3 TLSv1.2; ssl_ciphers EECDH+AESGCM:EDH+AESGCM; location ^~ /simplesaml { alias /var/simplesamlphp/www; location ~ ^(?/simplesaml)(?.+?\.php)(?/.*)?$ { include fastcgi_params; fastcgi_pass $fastcgi_pass; fastcgi_param SCRIPT_FILENAME $document_root$phpfile; # Must be prepended with the baseurlpath fastcgi_param SCRIPT_NAME /simplesaml$phpfile; fastcgi_param PATH_INFO $pathinfo if_not_empty; } } } ``` SimpleSAMLphp configuration: config.php --------------------------------------- There are a few steps that you should complete in the main configuration file, `config.php`, right away: - Set the `baseurlpath` configuration option. Make it point to the canonical URL of your deployment, where SimpleSAMLphp can be reached: ``` 'baseurlpath' => 'https://your.canonical.host.name/simplesaml/', ``` Please note that your canonical URL should always use HTTPS in order to protect your users. Additionally, if you are running behind a **reverse proxy** and you are offloading TLS to it, the proper way to tell SimpleSAMLphp that its base URL should use HTTPS is to set the `baseurlpath` configuration option properly. SimpleSAMLphp deliberately **ignores** the `X-Forwarded-*` set of headers that your proxy might be setting, so **do not rely on those**. - Set an administrator password. This is needed to access some of the pages in your SimpleSAMLphp installation web interface. Hashed passwords can also be used here. See the [`authcrypt`](./authcrypt:authcrypt) documentation for more information. ``` 'auth.adminpassword' => 'setnewpasswordhere', ``` - Set a secret salt. This should be a random string. Some parts of the SimpleSAMLphp needs this salt to generate cryptographically secure hashes. SimpleSAMLphp will give an error if the salt is not changed from the default value. The command below can help you to generated a random string on (some) unix systems: ``` tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo ``` Here is an example of the configuration option: ``` 'secretsalt' => 'randombytesinsertedhere', ``` **Please note that changing the secret salt may break access to services for your users**. - Configure your data storage. You can do this by editing the `store.type` configuration option, and setting it to one of the supported values. Now configure the backend of your choice with the relevant options, if needed. - Configure your sessions. You have to configure your sessions with the appropriate parameters so that the cookies used by SimpleSAMLphp to track users are always delivered to the software. You may do this by editing the `session.*` configuration options. Note that if you are using the `phpsession` data storage, the cookie-related configuration options are configured in the `session.phpsession.*` options. - Set technical contact information. This information will be available in the generated metadata. The e-mail address will also be used for receiving error reports sent automatically by SimpleSAMLphp. Here is an example: ``` 'technicalcontact_name' => 'John Smith', 'technicalcontact_email' => 'john.smith@example.com', ``` - If you use SimpleSAMLphp in a country where English is not widespread, you may want to change the default language from English to something else: ``` 'language.default' => 'no', ``` - Set your timezone ``` 'timezone' => 'Europe/Oslo', ``` You can see [a list of Supported Timezones at php.net](http://php.net/manual/en/timezones.php). Configuring PHP --------------- ### Sending e-mails from PHP Some parts of SimpleSAMLphp will allow you to send e-mails. For example, sending error reports to the technical admin. If you want to make use of this functionality, you should make sure your PHP installation is configured to be able to send e-mails. By default SimpleSAMLphp uses the PHP `mail()` function, which you can configure via `php.ini`. For more advanced configuration, including using a remote SMTP server, see the `mail.*` options in `config.php`. Enabling and disabling modules ------------------------------ If you want to enable some of the modules that are installed with SimpleSAMLphp, but are disabled by default, you can do that in the configuration: ``` 'module.enable' => [ 'exampleauth' => true, // Setting to TRUE enables. 'saml' => false, // Setting to FALSE disables. 'core' => null, // Unset or NULL uses default for this module. ], ``` Set to `true` the modules you want to enable, and to `false` those that you want to disable. Alternatively, you can enable or disable modules by setting empty files with given names in the module's root directory. For example, in order to enable the _consent_ module: ``` cd modules/consent touch enable ``` If you later want to disable the module, you can rename the `enable` file to `disable`. ``` cd modules/consent mv enable disable ``` This is the traditional way of enabling and disabling modules, but it is **deprecated**. Please do not rely on this in new installations of the software. The SimpleSAMLphp installation web page --------------------------------------- After installing SimpleSAMLphp, you can access the homepage of your installation, which contains some information and a few links to the test services. The URL of an installation can be e.g.: https://service.example.org/simplesaml/ The exact URL depends on how you set it up with your web server, and of course on your hostname. **Warning**: before you can actually use SimpleSAMLphp for something useful, you need to configure it either as a Service Provider or as an Identity Provider, depending on your use case. Here is an example screenshot of what the SimpleSAMLphp page looks like: ![Screenshot of the SimpleSAMLphp installation page.](resources/simplesamlphp-install/screenshot-installationpage.png) ### Check your PHP environment At the bottom of the installation page there are some green lights. SimpleSAMLphp runs some tests to see whether the required and recommended prerequisites are met. If any of the lights are red, you may have to install some PHP extensions or external PHP packages (e.g. you need the PHP LDAP extension to use the LDAP authentication module). ## Building assets Run the following commands to build the default theme. ``` npm install npm run build ``` ## Next steps You have now successfully installed SimpleSAMLphp, and the next steps depend on whether you want to setup a Service Provider (in order to protect access to an existing application) or an Identity Provider (which you would connect to a user database where your users can authenticate). Documentation on bridging between federation protocols is found in a separate document. - [Using SimpleSAMLphp as a Service Provider (SP)](simplesamlphp-sp) + [Remote IdP reference](simplesamlphp-reference-idp-remote) + [Connecting to the UK Access Federation or InCommon](simplesamlphp-ukaccess) - [Using SimpleSAMLphp as an Identity Provider (IdP)](simplesamlphp-idp) + [Hosted IdP reference](simplesamlphp-reference-idp-hosted) + [Remote SP reference](simplesamlphp-reference-sp-remote) + [Setting up an IdP for Google Workspace (G Suite / Google Apps)](simplesamlphp-googleapps) + [Advanced Topics](simplesamlphp-idp-more) - [Automated Metadata Management](https://github.com/simplesamlphp/simplesamlphp-module-metarefresh/blob/master/docs/simplesamlphp-automated_metadata.md) - [Maintenance and configuration](simplesamlphp-maintenance) Support ------- If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are in luck: there is a great Open Source community around SimpleSAMLphp, and you are welcome to join! The forums are open for you to ask questions, help others by answering their questions, request improvements or contribute with code or plugins of your own. - [Homepage](https://simplesamlphp.org) - [Documentation](https://simplesamlphp.org/docs/) - [Mailing lists](https://simplesamlphp.org/lists) Appendix: Installing SimpleSAMLphp in alternative locations ------------------------------------------------- There may be several reasons why you want to install SimpleSAMLphp in an alternative way. - You are installing SimpleSAMLphp in a hosted environment where you do not have root access, and cannot change Apache configuration. You can still install SimpleSAMLphp, keep on reading! - You have full permissions to the server, but cannot edit web server configuration for some reason like internal policies. The SimpleSAMLphp package contains one folder named `simplesamlphp-x.y.z` (where `x.y.z` is the version number). In this folder there are a lot of subfolders for library, metadata, configuration, etc. One of these folders is named `www`. **Only this folder should be exposed on the web**. The recommended configuration is to put the whole `simplesamlphp` folder outside the web root, and then link to the `www` folder by using the `Alias` directive, as described in [the section called “Configuring Apache”](#section_4 "Configuring Apache"). This is not the only possible way, though. As an example, let's see how you can install SimpleSAMLphp in your home directory on a shared hosting server. 1. Extract the SimpleSAMLphp archive in your home directory: ``` cd ~ tar xzf simplesamlphp-1.x.y.tar.gz mv simplesamlphp-1.x.y simplesamlphp ``` 2. Then you can try to make a symlink into the `public_html` directory. ``` cd ~/public_html ln -s ../simplesamlphp/www simplesaml ``` 3. Next, you need to set the `baseurlpath` configuration option with the URL pointing to the `simplesaml` link you just created in your `public_html` directory. For example, if your home directory is reachable in `https://host.example/~myaccount/`, set the base URL path accordingly: ``` 'baseurlpath' => 'https://host.example/~myaccount/simplesaml/', ``` Now, you can go to the URL of your installation and check if things work: https://host.example/~myaccount/simplesaml/ #### Tip Symlinking may fail, because some Apache configurations do not allow you to link to files from outside the `public_html` folder. If so, you can move the `www` folder instead of symlinking it: ``` cd ~/public_html mv ../simplesamlphp/www simplesaml ``` Now you have the following directory structure. - `~/simplesamlphp` - `~/public_html/simplesaml` where `simplesaml` is the `www` directory from the `simplesamlphp` installation directory, either moved or a symlink. Now, we need to make a few configuration changes. First, let's edit `~/public_html/simplesaml/_include.php`: Change the two lines from: ``` require_once(dirname(dirname(__FILE__)) . '/lib/_autoload.php'); ``` to something like: ``` require_once(dirname(dirname(dirname(__FILE__))) . '/lib/_autoload.php'); ``` **Warning**: note that this will make upgrading SimpleSAMLphp much more difficult, since you will need to move the `www` directory and manually edit files every time you upgrade. It is also possible that this method does not work in future versions of SimpleSAMLphp, and therefore it is discouraged and should be used only as a last resort. simplesamlphp-1.19.1/docs/simplesamlphp-hok-sp.md0000644000000000000000000000440014042503475020510 0ustar rootrootUsing Holder-of-Key Web Browser SSO Profile on a SimpleSAMLphp SP ================================================================= This document describes how to enable the [SAML V2.0 Holder-of-Key (HoK) Web Browser SSO Profile](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-holder-of-key-browser-sso.pdf) on a SimpleSAMLphp Service Provider (SP). The SAML V2.0 HoK Web Browser SSO Profile is an alternate version of the standard SAML Web Browser SSO Profile. Its primary benefit is the enhanced security of the SSO process while preserving maximum compatibility with existing deployments on client and server side. When using this profile the communication between the user and the SP is required to be protected by the TLS protocol. Additionally, the user needs a TLS client certificate. This certificate is usually selfsigned and stored in the certificate store of the browser or the underlying operating system. Configuring Apache ------------------ The SP requests a client certificate from the user agent during the TLS handshake. This behaviour is enabled with the following Apache webserver configuration: SSLEngine on SSLCertificateFile /etc/openssl/certs/server.crt SSLCertificateKeyFile /etc/openssl/private/server.key SSLVerifyClient optional_no_ca SSLOptions +ExportCertData If the user agent can successfully prove possession of the private key associated to the public key from the certificate, the received certificate is stored in the environment variable `SSL_CLIENT_CERT` of the webserver. Enable HoK on SP ---------------- To enable support for the HoK SSO Profile in the SP, the `saml20.hok.assertion` option must be set to TRUE in the SP configuration. This option can also be enabled in the `saml20-idp-remote` metadata file, but in that case the endpoint will not be added to the SP metadata. You must also send authentication requests specifying the Holder-of-Key profile to the IdP. This is controlled by the `ProtocolBinding` option in the SP configuration. 'hok-sp' => [ 'saml:SP', 'saml20.hok.assertion' => TRUE, 'ProtocolBinding' => 'urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser', ], When this is done, you can add the metadata of your SP to the IdP and test the authentication. simplesamlphp-1.19.1/docs/simplesamlphp-metadata-extensions-rpi.md0000644000000000000000000001025314042503475024057 0ustar rootrootSAML V2.0 Metadata Extensions for Registration and Publication Information ============================= * Author: Jaime Perez [jaime.perez@uninett.no](mailto:jaime.perez@uninett.no) This is a reference for the SimpleSAMLphp implementation of the [SAML V2.0 Metadata Extensions for Registration and Publication Information](http://docs.oasis-open.org/security/saml/Post2.0/saml-metadata-rpi/v1.0/saml-metadata-rpi-v1.0.html) defined by OASIS. This extension aims to provide information about the registrars and publishers of the metadata themselves, and it is therefore available throught different endpoints and modules that provide metadata all along SimpleSAMLphp. More specifically, this extension can be used for: - metadata published for a [hosted service provider](./saml:sp). - metadata published for a [hosted identity provider](./simplesamlphp-reference-idp-hosted). - metadata collected and published by means of the [`aggregator`](./aggregator:aggregator) or [`aggregator2`](./aggregator2:aggregator2) modules. Currently, only the `` element is supported. Depending on the metadata set you want to add this extension to, you will have to configure it on the corresponding configuration file: - `metadata/saml20-idp-hosted.php` for hosted identity providers. - `config/authsources.php` for hosted service providers. - `config/module_aggregator.php` for the `aggregator` module. - `config/module_aggregator2.php` for the `aggregator2` module. RegistrationInfo Items ---------------------- The configuration is the same for all the different files, and consists of a single directive called `RegistrationInfo`, which **must** be an indexed array with the following options: `authority` : A string containing an identifier of the authority who has registered this metadata. This parameter is **mandatory**. `instant` : A string containing the instant when the entity or entities where registered by the authority. This parameter is optional, and must be expressed in the UTC timezone with the *zulu* (`Z`) timezone identifier. If omitted, there will be no `registrationInstant` in the resulting metadata, except in the `aggregator2` module, which will use the instant when the metadata was generated. `policies` : An indexed array containing URLs pointing to the policy under which the entity or entities where registered. Each index must be the language code corresponding to the language of the URL. This parameter is optional, and will be omitted in the resulting metadata if not configured. Examples -------- Service Provider: 'default-sp' => [ 'saml:SP', 'entityID' => NULL, ... 'RegistrationInfo' => [ 'authority' => 'urn:mace:sp.example.org', 'instant' => '2008-01-17T11:28:03.577Z', 'policies' => ['en' => 'http://sp.example.org/policy', 'es' => 'http://sp.example.org/politica'], ], ], Identity Provider: $metadata['__DYNAMIC:1__'] = [ 'host' => '__DEFAULT__', ... 'RegistrationInfo' => [ 'authority' => 'urn:mace:idp.example.org', 'instant' => '2008-01-17T11:28:03.577Z', ], ]; `aggregator` module: $config = [ 'aggregators' => [ ... ], 'maxDuration' => 60*60*24*5, 'reconstruct' => FALSE, ... 'RegistrationInfo' => [ 'authority' => 'urn:mace:example.federation', 'instant' => '2008-01-17T11:28:03Z', 'policies' => ['en' => 'http://example.org/federation_policy', 'es' => 'https://example.org/politica_federacion'], ], ]; `aggregator2` module: $config = [ 'example.org' => [ 'sources' => [ ... ], 'RegistrationInfo' => [ 'authority' => 'urn:mace:example.federation', 'policies' => ['en' => 'http://example.org/federation_policy', 'es' => 'https://example.org/politica_federacion'], ], ], ]; simplesamlphp-1.19.1/docs/simplesamlphp-translation.md0000644000000000000000000000656414042503475021662 0ustar rootrootSimpleSAMLphp Translation Portal ================================================================ ## How translated terms are referred from a template Here is an example of how two terms are included in a template from dictionary files:

t('{core:frontpage:about_header}'); ?>

t('{core:frontpage:about_text}'); ?>

In this example, two translated terms are included: `about_header` and `about_text`. Both these terms are found in a dictionary file named `frontpage`, inside the module named `core`. **Note:** An important use-case here is that you can create your own module, that includes a new theme that overrides some of the default templates. You may in this template refer to both terms from the existing dictionary files, but you can also add new dictionary files in your new module that may introduce new alternative terms. ## The definition file When the template library is about to lookup the translation of a term, it will lookup * the definition file, for the English translation, and * the translation file, for translation to other languages. SimpleSAMLphp will always fallback to the English translation using the definition file, both: * when the term is not translated into the *current selected language*, and * when the translation file is not available at all. The name of the definition file is `BASENAME.definition.json`, where the term is referred to like this: `{MODULENAME:BASENAME:TERM}`. The file MUST be placed in the followng location: `modules/MODULENAME/dictionaries/BASENAME.definition.json`. The content of the defintion file is a *JSON encoded array* of `term => definition`, where definition is an array with an required `en` index for the english translation, and the value is the English text. Here is an example of a definition file with three terms: { "header": { "en": "Missing cookie" }, "description": { "en": "You appear to have disabled cookies in your browser. Please check the settings in your browser, and try again." }, "retry": { "en": "Retry" } } Note: you may not include other languages in the definition files, the `en` index is used in order to at a later point in time introduce more meta information for each term, like in example: "header": { "en": "Missing cookie", "_note": "This text shows up on the error page when the browser do not support cookies." }, To summarize the pattern of the definition file is as follows: { "TERM1": { "en": "English text 1" }, "TERM2": { "en": "English text 2" } } ## The translation file The translation file is similar to the definition file, but including translation to languages others than English. The structure of the file is identical to the definition files, except from the language index, which now is not `en`, but the actual langauge that is translated: { "TERM1": { "no": "Norsk tekst 1", "da": "Dansk tekst 1" }, "TERM2": { "no": "Norsk tekst 2", "da": "Dansk tekst 2" } } simplesamlphp-1.19.1/docs/index.md0000644000000000000000000000524114042503475015546 0ustar rootrootSimpleSAMLphp Documentation =========================== * Installation and upgrading * [Installing SimpleSAMLphp](simplesamlphp-install) * [Upgrade notes](simplesamlphp-upgrade-notes) * [Installation from the repository](simplesamlphp-install-repo) * [Changelog](simplesamlphp-changelog) * Using SimpleSAMLphp as a SAML Service Provider * [Service Provider Quickstart](simplesamlphp-sp) * [Hosted SP Configuration Reference](./saml:sp) * [IdP remote reference](simplesamlphp-reference-idp-remote) * [Configuring HTTP-Artifact](./simplesamlphp-artifact-sp) * [Using scoping](./simplesamlphp-scoping) * [Holder-of-Key profile](simplesamlphp-hok-sp) * Using SimpleSAMLphp as a SAML Identity Provider * [Identity Provider QuickStart](simplesamlphp-idp) * [IdP hosted reference](simplesamlphp-reference-idp-hosted) * [SP remote reference](simplesamlphp-reference-sp-remote) * [Use case: Setting up an IdP for Google Workspace (G Suite / Google Apps)](simplesamlphp-googleapps) * [Configuring HTTP-Artifact](./simplesamlphp-artifact-idp) * [Identity Provider Advanced Topics](simplesamlphp-idp-more) * [Holder-of-Key profile](simplesamlphp-hok-idp) * [Automated Metadata Management](https://github.com/simplesamlphp/simplesamlphp-module-metarefresh/blob/master/docs/simplesamlphp-automated_metadata.md) * [Maintenance and configuration](simplesamlphp-maintenance) - covers session handling, php configuration etc. * [Authentication Processing Filters](simplesamlphp-authproc) - attribute filtering, attribute mapping, consent, group generation etc. * [Advanced features](simplesamlphp-advancedfeatures) - covers bridging protocols, attribute filtering, etc. * [State Information Lost](simplesamlphp-nostate) - more about this common error message * [SimpleSAMLphp Dictionaries and Translation](simplesamlphp-translation) * [Theming SimpleSAMLphp](simplesamlphp-theming) * [SimpleSAMLphp Modules](simplesamlphp-modules) - how to create own customized modules * [Key rollover](./saml:keyrollover) * [Creating authentication sources](./simplesamlphp-authsource) * [Implementing custom username/password authentication](./simplesamlphp-customauth) * [Storing sessions in Riak](./riak:simplesamlphp-riak) Documentation on specific SimpleSAMLphp modules: * [Consent module](./consent:consent) * [Installing and configuring the consentAdmin module](./consentAdmin:consentAdmin) * [Authorization](./authorize:authorize) * [autotest Module](https://github.com/simplesamlphp/simplesamlphp-module-autotest/blob/v1.0/README.md) * [Statistics](./statistics:statistics) Documentation for SimpleSAMLphp developers: * [Error handling in SimpleSAMLphp](simplesamlphp-errorhandling) simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.18.md0000644000000000000000000000273714042503475022464 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.18 ==================================== The minimum PHP version required is now PHP 5.6. ### Deprecations * The use of the PHP `memcache` extension was deprecated in favour of `memcached`. In order to keep using memcache functionality you have to move to the PHP `memcached` extension, which is available from PECL; see https://pecl.php.net/package/memcached. The former is considered abandoned and it's safe use can no longer be guaranteed. There are a few options here: - Depending on your distribution, the package may just be available for you to install - You could use the package from the REMI repository if you're on RHEL; https://rpms.remirepo.net/ - Download the source from https://pecl.php.net/package/memcached and compile the source as a PHP-extension manually; https://www.php.net/manual/en/install.pecl.phpize.php * Support for SAML1.1 / Shibboleth 1.3 will be discontinued in a future release. * The class `SimpleSAML\Auth\TimeLimitedToken` is now deprecated and will be removed in a future release If your custom module relies on this class, be sure to make a copy into your repository and make sure to also copy the unit tests that come along. * Setting `privacypolicy` in metadata files will be removed in a future release. It was only used by the consent module, which supports `UIInfo`'s `PrivacyStatementURL`. See https://simplesamlphp.org/docs/stable/simplesamlphp-metadata-extensions-ui on how to configure this. simplesamlphp-1.19.1/docs/simplesamlphp-metadata-endpoints.md0000644000000000000000000000404314042503475023073 0ustar rootrootMetadata endpoints ================== This document gives a short introduction to the various methods forms metadata endpoints can take in SimpleSAMLphp. The endpoints we have are: Endpoint | Indexed | Default binding -------------------------------|---------|---------------- `ArtifactResolutionService` | Y | SOAP `AssertionConsumerService` | Y | HTTP-POST `SingleLogoutService` | N | HTTP-Redirect `SingleSignOnService` | N | HTTP-Redirect The various endpoints can be specified in three different ways: * A single string. * Array of strings. * Array of arrays. A single string --------------- 'AssertionConsumerService' => 'https://sp.example.org/ACS', This is the simplest endpoint format. It can be used when there is only a single endpoint that uses the default binding. Array of strings ---------------- 'AssertionConsumerService' => [ 'https://site1.example.org/ACS', 'https://site2.example.org/ACS', ], This endpoint format can be used to represent multiple endpoints, all of which use the default binding. Array of arrays --------------- 'AssertionConsumerService' => [ [ 'index' => 1, 'isDefault' => TRUE, 'Location' => 'https://sp.example.org/ACS', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', ], [ 'index' => 2, 'Location' => 'https://sp.example.org/ACS', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact', ], ], This endpoint format allows for specifying multiple endpoints with different bindings. It can also be used to specify the ResponseLocation attribute on endpoints, e.g. on `SingleLogoutService`: 'SingleLogoutService' => [ [ 'Location' => 'https://sp.example.org/LogoutRequest', 'ResponseLocation' => 'https://sp.example.org/LogoutResponse', 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', ], ], simplesamlphp-1.19.1/docs/simplesamlphp-reference-idp-hosted.md0000644000000000000000000004102114042503475023303 0ustar rootrootIdP hosted metadata reference ============================= This is a reference for the metadata files `metadata/saml20-idp-hosted.php` and `metadata/shib13-idp-hosted.php`. Both files have the following format: 'idp.example.org', /* Configuration options for the first IdP. */ ]; $metadata['entity-id-2'] = [ 'host' => '__DEFAULT__', /* Configuration options for the default IdP. */ ]; /* ... */ The entity ID should be an URI. It can, also be on the form `__DYNAMIC:1__`, `__DYNAMIC:2__`, `...`. In that case, the entity ID will be generated automatically. The `host` option is the hostname of the IdP, and will be used to select the correct configuration. One entry in the metadata-list can have the host `__DEFAULT__`. This entry will be used when no other entry matches. Common options -------------- `auth` : Which authentication module should be used to authenticate users on this IdP. `authproc` : Used to manipulate attributes, and limit access for each SP. See the [authentication processing filter manual](simplesamlphp-authproc). `certificate` : Certificate file which should be used by this IdP, in PEM format. The filename is relative to the `cert/`-directory. `contacts` : Specify contacts in addition to the technical contact configured through config/config.php. For example, specifying a support contact: 'contacts' => [ [ 'contactType' => 'support', 'emailAddress' => 'support@example.org', 'givenName' => 'John', 'surName' => 'Doe', 'telephoneNumber' => '+31(0)12345678', 'company' => 'Example Inc.', ], ], : If you have support for a trust framework that requires extra attributes on the contact person element in your IdP metadata (for example, SIRTFI), you can specify an array of attributes on a contact. 'contacts' => [ [ 'contactType' => 'other', 'emailAddress' => 'mailto:abuse@example.org', 'givenName' => 'John', 'surName' => 'Doe', 'telephoneNumber' => '+31(0)12345678', 'company' => 'Example Inc.', 'attributes' => [ 'xmlns:remd' => 'http://refeds.org/metadata', 'remd:contactType' => 'http://refeds.org/metadata/contactType/security', ], ], ], `host` : The hostname for this IdP. One IdP can also have the `host`-option set to `__DEFAULT__`, and that IdP will be used when no other entries in the metadata matches. `logouttype` : The logout handler to use. Either `iframe` or `traditional`. `traditional` is the default. `OrganizationName` : The name of the organization responsible for this IdP. This name does not need to be suitable for display to end users. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated name: 'OrganizationName' => [ 'en' => 'Example organization', 'no' => 'Eksempel organisation', ], : *Note*: If you specify this option, you must also specify the `OrganizationURL` option. `OrganizationDisplayName` : The name of the organization responsible for this IdP. This name must be suitable for display to end users. If this option isn't specified, `OrganizationName` will be used instead. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated name. : *Note*: If you specify this option, you must also specify the `OrganizationName` option. `OrganizationURL` : A URL the end user can access for more information about the organization. : This option can be translated into multiple languages by specifying the value as an array of language-code to translated URL. : *Note*: If you specify this option, you must also specify the `OrganizationName` option. `privacypolicy` : This is an absolute URL for where an user can find a privacypolicy. If set, this will be shown on the consent page. `%SPENTITYID%` in the URL will be replaced with the entity id of the service the user is accessing. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. : *Note*: **deprecated** Will be removed in a future release; use the MDUI-extension instead `privatekey` : Name of private key file for this IdP, in PEM format. The filename is relative to the `cert/`-directory. `privatekey_pass` : Passphrase for the private key. Leave this option out if the private key is unencrypted. `scope` : An array with scopes for this IdP. The scopes will be added to the generated XML metadata. A scope can either be a domain name or a regular expression matching a number of domains. `userid.attribute` : The attribute name of an attribute which uniquely identifies the user. This attribute is used if SimpleSAMLphp needs to generate a persistent unique identifier for the user. This option can be set in both the IdP-hosted and the SP-remote metadata. The value in the SP-remote metadata has the highest priority. The default value is `eduPersonPrincipalName`. SAML 2.0 options ---------------- The following SAML 2.0 options are available: `assertion.encryption` : Whether assertions sent from this IdP should be encrypted. The default value is `FALSE`. : Note that this option can be set for each SP in the SP-remote metadata. `attributeencodings` : What encoding should be used for the different attributes. This is an array which maps attribute names to attribute encodings. There are three different encodings: : - `string`: Will include the attribute as a normal string. This is the default. : - `base64`: Store the attribute as a base64 encoded string. This is the default when the `base64attributes`-option is set to `TRUE`. : - `raw`: Store the attribute without any modifications. This makes it possible to include raw XML in the response. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. `attributes.NameFormat` : What value will be set in the Format field of attribute statements. This parameter can be configured multiple places, and the actual value used is fetched from metadata by the following priority: : 1. SP Remote Metadata 2. IdP Hosted Metadata : The default value is: `urn:oasis:names:tc:SAML:2.0:attrname-format:basic` : Some examples of values specified in the SAML 2.0 Core Specification: : - `urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified` - `urn:oasis:names:tc:SAML:2.0:attrname-format:uri` (The default in Shibboleth 2.0) - `urn:oasis:names:tc:SAML:2.0:attrname-format:basic` (The default in Sun Access Manager) : You can also define your own value. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. : (This option was previously named `AttributeNameFormat`.) `encryption.blacklisted-algorithms` : Blacklisted encryption algorithms. This is an array containing the algorithm identifiers. : Note that this option can be set for each SP in the [SP-remote metadata](./simplesamlphp-reference-sp-remote). : The RSA encryption algorithm with PKCS#1 v1.5 padding is blacklisted by default for security reasons. Any assertions encrypted with this algorithm will therefore fail to decrypt. You can override this limitation by defining an empty array in this option (or blacklisting any other algorithms not including that one). However, it is strongly discouraged to do so. For your own safety, please include the string 'http://www.w3.org/2001/04/xmlenc#rsa-1_5' if you make use of this option. `https.certificate` : The certificate used by the webserver when handling connections. This certificate will be added to the generated metadata of the IdP, which is required by some SPs when using the HTTP-Artifact binding. `nameid.encryption` : Whether NameIDs sent from this IdP should be encrypted. The default value is `FALSE`. : Note that this option can be set for each SP in the [SP-remote metadata](./simplesamlphp-reference-sp-remote). `NameIDFormat` : The format(s) of the NameID supported by this IdP, as either an array or a string. If an array is given, the first value is used as the default if the incoming request does not specify a preference. Defaults to the `transient` format if unspecified. : This parameter can be configured in multiple places, and the actual value used is fetched from metadata with the following priority: : 1. SP Remote Metadata 2. IdP Hosted Metadata : The three most commonly used values are: : 1. `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` 2. `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` 3. `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` : The `transient` format will generate a new unique ID every time the user logs in. : To properly support the `persistent` and `emailAddress` formats, you should configure [NameID generation filters](./saml:nameid) on your IdP. : Note that the value(s) set here will be added to the metadata generated for this IdP, in the `NameIDFormat` element. `RegistrationInfo` : Allows to specify information about the registrar of this SP. Please refer to the [MDRPI extension](./simplesamlphp-metadata-extensions-rpi) document for further information. `saml20.ecp` : Set to `true` to enable the IdP to recieve authnrequests and send responses according the Enhanced Client or Proxy (ECP) Profile. Note: authentication filters that require interaction with the user will not work with ECP. Defaults to `false`. `saml20.hok.assertion` : Set to `TRUE` to enable the IdP to send responses according the [Holder-of-Key Web Browser SSO Profile](./simplesamlphp-hok-idp). Defaults to `FALSE`. `saml20.sendartifact` : Set to `TRUE` to enable the IdP to send responses with the HTTP-Artifact binding. Defaults to `FALSE`. : Note that this requires a configured memcache server. `saml20.sign.assertion` : Whether `` elements should be signed. Defaults to `TRUE`. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. `saml20.sign.response` : Whether `` messages should be signed. Defaults to `TRUE`. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. `signature.algorithm` : The algorithm to use when signing any message generated by this identity provider. Defaults to RSA-SHA256. : Possible values: * `http://www.w3.org/2000/09/xmldsig#rsa-sha1` *Note*: the use of SHA1 is **deprecated** and will be disallowed in the future. * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256` The default. * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha384` * `http://www.w3.org/2001/04/xmldsig-more#rsa-sha512` `sign.logout` : Whether to sign logout messages sent from this IdP. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. `SingleSignOnService` : Override the default URL for the SingleSignOnService for this IdP. This is an absolute URL. The default value is `/saml2/idp/SSOService.php` : Note that this only changes the values in the generated metadata and in the messages sent to others. You must also configure your webserver to deliver this URL to the correct PHP page. `SingleSignOnServiceBinding` : List of SingleSignOnService bindings that the IdP will claim support for. : Possible values: * `urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect` * `urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST` : Defaults to HTTP-Redirect binding. Please note that the order specified will be kept in the metadata, making the first binding the default one. `SingleLogoutService` : Override the default URL for the SingleLogoutService for this IdP. This is an absolute URL. The default value is `/saml2/idp/SingleLogoutService.php` : Note that this only changes the values in the generated metadata and in the messages sent to others. You must also configure your webserver to deliver this URL to the correct PHP page. `SingleLogoutServiceBinding` : List of SingleLogoutService bindings the IdP will claim support for. : Possible values: * `urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect` * `urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST` : Defaults to HTTP-Redirect binding. Please note that the order specified will be kept in the metadata, making the first binding the default one. `validate.authnrequest` : Whether we require signatures on authentication requests sent to this IdP. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. `validate.logout` : Whether we require signatures on logout messages sent to this IdP. : Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. ### Fields for signing and validating messages SimpleSAMLphp only signs authentication responses by default. Signing of logout requests and logout responses can be enabled by setting the `redirect.sign` option. Validation of received messages can be enabled by the `redirect.validate` option. These options set the default for this IdP, but options for each SP can be set in `saml20-sp-remote`. Note that you need to add a certificate for each SP to be able to validate signatures on messages from that SP. `redirect.sign` : Whether logout requests and logout responses sent from this IdP should be signed. The default is `FALSE`. `redirect.validate` : Whether authentication requests, logout requests and logout responses received sent from this IdP should be validated. The default is `FALSE` **Example: Configuration for signed messages** 'redirect.sign' => true, Shibboleth 1.3 options ---------------------- Note that Shibboleth 1.3 support is deprecated and will be removed in the next major release of SimpleSAMLphp. The following options for Shibboleth 1.3 IdP's are avaiblable: `scopedattributes` : Array with names of attributes which should be scoped. Scoped attributes will receive a `Scope`-attribute on the `AttributeValue`-element. The value of the Scope-attribute will be taken from the attribute value: : `someuser@example.org` : will be transformed into : `someuser` : By default, no attributes are scoped. Note that this option also exists in the SP-remote metadata, and any value in the SP-remote metadata overrides the one configured in the IdP metadata. Metadata extensions ------------------- SimpleSAMLphp supports generating metadata with the MDUI, MDRPI and EntityAttributes metadata extensions. See the documentation for those extensions for more details: * [MDUI extension](./simplesamlphp-metadata-extensions-ui) * [MDRPI extension](./simplesamlphp-metadata-extensions-rpi) * [EntityAttributes](./simplesamlphp-metadata-extensions-attributes) Examples -------- These are some examples of IdP metadata ### Minimal SAML 2.0 / Shibboleth 1.3 IdP ### '__DEFAULT__', /* The private key and certificate used by this IdP. */ 'certificate' => 'example.org.crt', 'privatekey' => 'example.org.pem', /* * The authentication source for this IdP. Must be one * from config/authsources.php. */ 'auth' => 'example-userpass', ]; simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.7.md0000644000000000000000000000153014042503475022370 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.7 =================================== * The attribute names generated by the twitter and facebook authentication sources have changed. * Several new options have been added to config.php, and some have been renamed. The old options should still work, but it is suggested that you look at the config.php file in config-templates, and compare it to your own. * There have been several changes to the internal API. Most of the changes will not be noticed by the application using SimpleSAMLphp. See the changelog for more details about the changes. * Relative redirects are no longer supported. If your application passes relative URL's to the `SimpleSAML_Utilities::redirect()`-function, it will no longer work. This also applies if you pass relative URL's to other functions that do redirects. simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes.md0000644000000000000000000000231214042503475022064 0ustar rootrootSimpeSAMLphp Upgrade Notes ========================== See the following pages for important information for users upgrading from older versions of SimpleSAMLphp: * [Upgrade notes for version 1.19](simplesamlphp-upgrade-notes-1.19) * [Upgrade notes for version 1.18](simplesamlphp-upgrade-notes-1.18) * [Upgrade notes for version 1.17](simplesamlphp-upgrade-notes-1.17) * [Upgrade notes for version 1.16](simplesamlphp-upgrade-notes-1.16) * [Upgrade notes for version 1.15](simplesamlphp-upgrade-notes-1.15) * [Upgrade notes for version 1.14](simplesamlphp-upgrade-notes-1.14) * [Upgrade notes for version 1.13](simplesamlphp-upgrade-notes-1.13) * [Upgrade notes for version 1.12](simplesamlphp-upgrade-notes-1.12) * [Upgrade notes for version 1.11](simplesamlphp-upgrade-notes-1.11) * [Upgrade notes for version 1.10](simplesamlphp-upgrade-notes-1.10) * [Upgrade notes for version 1.9](simplesamlphp-upgrade-notes-1.9) * [Upgrade notes for version 1.8](simplesamlphp-upgrade-notes-1.8) * [Upgrade notes for version 1.7](simplesamlphp-upgrade-notes-1.7) * [Upgrade notes for version 1.6](simplesamlphp-upgrade-notes-1.6) A detailed list of changes in each release can be found in the [Changelog](simplesamlphp-changelog). simplesamlphp-1.19.1/docs/simplesamlphp-database.md0000644000000000000000000001007614042503475021061 0ustar rootrootSimpleSAML\Database ============================= Purpose ------- This document covers the SimpleSAML\Database class and is only relevant to anyone writing code for SimpleSAMLphp, including modules, that require a database connection. The Database class provides a single class that can be used to connect to a database which can be shared by anything within SimpleSAMLphp. Getting Started --------------- If you are just using the already configured database, which would normally be the case, all you need to do is get the global instance of the Database class. $db = \SimpleSAML\Database::getInstance(); If there is a requirement to connect to an alternate database server (ex. authenticating users that exist on a different SQL server or database) you can specify an alternate configuration. $config = new \SimpleSAML\Configuration($myconfigarray, "mymodule/lib/Auth/Source/myauth.php"); $db = \SimpleSAML\Database::getInstance($config); That will create a new instance of the database, separate from the global instance, specific to the configuration defined in $myconfigarray. If you are going to specify an alternate config, your configuration array must contain the same keys that exist in the master config (database.dsn, database.username, database.password, database.prefix, etc). Database Prefix --------------- Administrators can add a prefix to all the table names that this database classes accesses and you should take that in account when querying. Assuming that a prefix has been configured as "sp_": $table = $db->applyPrefix("saml20_idp_hosted"); $table would be set to "sp_saml20_idp_hosted" Querying The Database --------------------- You can query the database through two public functions read() and write() which are fairly self-explanitory when it comes to determining which one to use when querying. ### Writing to The Database Since the database class allows administrators to configure master and slave database servers, the write function will always use the master database connection. The write function takes 2 parameters: SQL, params. $table = $db->applyPrefix("test"); $values = [ 'id' => 20, 'data' => 'Some data', ]; $query = $db->write("INSERT INTO $table (id, data) VALUES (:id, :data)", $values); The values specified in the $values array will be bound to the placeholders and will be executed on the master. By default, values are binded as PDO::PARAM_STR. If you need to override this, you can specify it in the values array. $table = $db->applyPrefix("test"); $values = [ 'id' => [20, PDO::PARAM_INT], 'data' => 'Some data', ]; $query = $db->write("INSERT INTO $table (id, data) VALUES (:id, :data)", $values); You can also skip usage of prepared statements. You should **only** use this if you have a statement that has no user input (ex. CREATE TABLE). If the params variable is explicity set to false, it will skip usage of prepared statements. This is only available when writing to the database. $table = $db->applyPrefix("test"); $query = $db->write("CREATE TABLE IF NOT EXISTS $table (id INT(16) NOT NULL, data TEXT NOT NULL)", false); ### Reading The Database Since the database class allows administrators to configure master and slave database servers, the read function will randomly select a slave server to query. If no slaves are configured, it will read from the master. The read function takes 2 parameters: SQL, params. $table = $db->applyPrefix("test"); $values = [ 'id' => 20, ]; $query = $db->read("SELECT * FROM $table WHERE id = :id", $values); The values specified in the $values array will be bound to the placeholders and will be executed on the selected slave. By default, values are binded as PDO::PARAM_STR. If you need to override this, you can specify it in the values array. $table = $db->applyPrefix("test"); $values = [ 'id' => [20, PDO::PARAM_INT], ]; $query = $db->read("SELECT * FROM $table WHERE id = :id", $values); simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.17.md0000644000000000000000000000234414042503475022455 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.17 ==================================== The minimum PHP version required is now PHP 5.5. All (remaining) classes have been changed to namespaces. There are mappings from the legacy names so calling code should remain working. Custom code (e.g. modules) that test for class names, e.g. when catching specific exceptions, may need to be changed. The possibility has been reintroduced to omit the NameIdPolicy from SP AuthnRequests by setting NameIDPolicy to `false`. The prefered way is to configure it as an array `[ 'Format' => format, 'AllowCreate' => true/false ]`, which is now also the format used in the `saml:NameIDPolicy` variable in `$state`. The code, config and documentation have switched to using the modern PHP array syntax. This should not have an impact as both will remain working equally, but the code examples and config templates look slightly different. The following are equivalent: // Old style array syntax $config = array( 'authproc' => array( 60 => 'class:etc' ), 'other example' => 1 ); // Current style array syntax $config = [ 'authproc' => [ 60 => 'class:etc' ], 'other example' => 1 ]; simplesamlphp-1.19.1/docs/simplesamlphp-sp-api.md0000644000000000000000000002051114042503475020501 0ustar rootrootSimpleSAMLphp SP API reference ============================== This document describes the \SimpleSAML\Auth\Simple API. This is the preferred API for integrating SimpleSAMLphp with other applications. ### Note on PHP sessions and SimpleSAMLphp API calls Some SimpleSAMLphp calls replace the current active PHP session. If you previously started a session and wish to write to it, then you must cleanup the SimpleSAMLphp session before you can write to your session. If you do not need to modify your own session, then you can leave the cleanup call out; however, forgetting to call cleanup is a common source of hard to find bugs. session_start(); // ... $auth = new \SimpleSAML\Auth\Simple('default-sp'); $auth->isAuthenticated(); // Replaces our session with the SimpleSAMLphp one // $_SESSION['key'] = 'value'; // This would save to the SimpleSAMLphp session which isn't what we want SimpleSAML_Session::getSessionFromRequest()->cleanup(); // Reverts to our PHP session // Save to our session $_SESSION['key'] = 'value'; Constructor ----------- new \SimpleSAML\Auth\Simple(string $authSource) The constructor initializes a \SimpleSAML\Auth\Simple object. ### Parameters It has a single parameter, which is the ID of the authentication source that should be used. This authentication source must exist in `config/authsources.php`. ### Example $auth = new \SimpleSAML\Auth\Simple('default-sp'); `isAuthenticated` ----------------- bool isAuthenticated() Check whether the user is authenticated with this authentication source. `TRUE` is returned if the user is authenticated, `FALSE` if not. ### Example if (!$auth->isAuthenticated()) { SimpleSAML_Session::getSessionFromRequest()->cleanup(); /* Show login link. */ print('
Login'); } `requireAuth` ------------- void requireAuth(array $params = []) Make sure that the user is authenticated. This function will only return if the user is authenticated. If the user isn't authenticated, this function will start the authentication process. ### Parameters `$params` is an associative array with named parameters for this function. See the documentation for the `login`-function for a description of the parameters. ### Example 1 $auth->requireAuth(); SimpleSAML_Session::getSessionFromRequest()->cleanup(); print("Hello, authenticated user!"); ### Example 2 /* * Return the user to the frontpage after authentication, don't post * the current POST data. */ $auth->requireAuth([ 'ReturnTo' => 'https://sp.example.org/', 'KeepPost' => FALSE, ]); SimpleSAML_Session::getSessionFromRequest()->cleanup(); print("Hello, authenticated user!"); `login` ------------- void login(array $params = []) Start a login operation. This function will always start a new authentication process. ### Parameters The following global parameters are supported: `ErrorURL` (`string`) : A URL to a page which will receive errors that may occur during authentication. `KeepPost` (`bool`) : If set to `TRUE`, the current POST data will be submitted again after authentication. The default is `TRUE`. `ReturnTo` (`string`) : The URL the user should be returned to after authentication. The default is to return the user to the current page. `ReturnCallback` (`array`) : The function we should call when the user finishes authentication. The [`saml:SP`](./saml:sp) authentication source also defines some parameters. ### Example # Send a passive authentication request. $auth->login([ 'isPassive' => TRUE, 'ErrorURL' => 'https://.../error_handler.php', ]); SimpleSAML_Session::getSessionFromRequest()->cleanup(); `logout` -------- void logout(mixed $params = NULL) Log the user out. After logging out, the user will either be redirected to another page, or a function will be called. This function never returns. ### Parameters `$params` : Parameters for the logout operation. This can either be a simple string, in which case it is interpreted as the URL the user should be redirected to after logout, or an associative array with logout parameters. If this parameter isn't specified, we will redirect the user to the current URL after logout. If the parameter is an an array, it can have the following options: - `ReturnTo`: The URL the user should be returned to after logout. - `ReturnCallback`: The function that should be called after logout. - `ReturnStateParam`: The parameter we should return the state in when redirecting. - `ReturnStateStage`: The stage the state array should be saved with. The `ReturnState` parameters allow access to the result of the logout operation after it completes. ### Example 1 Logout, and redirect to the specified URL. $auth->logout('https://sp.example.org/logged_out.php'); SimpleSAML_Session::getSessionFromRequest()->cleanup(); ### Example 2 Same as the previous, but check the result of the logout operation afterwards. $auth->logout([ 'ReturnTo' => 'https://sp.example.org/logged_out.php', 'ReturnStateParam' => 'LogoutState', 'ReturnStateStage' => 'MyLogoutState', ]); SimpleSAML_Session::getSessionFromRequest()->cleanup(); And in logged_out.php: $state = \SimpleSAML\Auth\State::loadState((string)$_REQUEST['LogoutState'], 'MyLogoutState'); $ls = $state['saml:sp:LogoutStatus']; /* Only works for SAML SP */ if ($ls['Code'] === 'urn:oasis:names:tc:SAML:2.0:status:Success' && !isset($ls['SubCode'])) { /* Successful logout. */ echo("You have been logged out."); } else { /* Logout failed. Tell the user to close the browser. */ echo("We were unable to log you out of all your sessions. To be completely sure that you are logged out, you need to close your web browser."); } `getAttributes` --------------- array getAttributes() Retrieve the attributes of the current user. If the user isn't authenticated, an empty array will be returned. The attributes will be returned as an associative array with the name of the attribute as the key and the value as an array of one or more strings: [ 'uid' => ['testuser'], 'eduPersonAffiliation' => ['student', 'member'], ] ### Example $attrs = $auth->getAttributes(); if (!isset($attrs['displayName'][0])) { throw new Exception('displayName attribute missing.'); } $name = $attrs['displayName'][0]; print('Hello, ' . htmlspecialchars($name)); `getAuthData` --------------- mixed getAuthData(string $name) Retrieve the specified authentication data for the current session. NULL is returned if the user isn't authenticated. The available authentication data depends on the module used for authentication. See the [`saml:SP`](./saml:sp) reference for information about available SAML authentication data. ### Example $idp = $auth->getAuthData('saml:sp:IdP'); $nameID = $auth->getAuthData('saml:sp:NameID')->getValue(); printf('You are %s, logged in from %s', htmlspecialchars($nameID), htmlspecialchars($idp)); `getLoginURL` ------------- string getLoginURL(string $returnTo = NULL) Retrieve a URL that can be used to start authentication. ### Parameters `$returnTo` : The URL the user should be returned to after authentication. The default is the current page. ### Example $url = $auth->getLoginURL(); print('Login'); ### Note The URL returned by this function is static, and will not change. You can easily create your own links without using this function. The URL should be: .../simplesaml/module.php/core/as_login.php?AuthId=&ReturnTo= `getLogoutURL` -------------- string getLogoutURL(string $returnTo = NULL) Retrieve a URL that can be used to trigger logout. ### Parameters `$returnTo` : The URL the user should be returned to after logout. The default is the current page. ### Example $url = $auth->getLogoutURL(); print('Logout'); ### Note The URL returned by this function is static, and will not change. You can easily create your own links without using this function. The URL should be: .../simplesaml/module.php/core/as_logout.php?AuthId=&ReturnTo= simplesamlphp-1.19.1/docs/simplesamlphp-upgrade-notes-1.12.md0000644000000000000000000000016014042503475022442 0ustar rootrootUpgrade notes for SimpleSAMLphp 1.12 ==================================== * PHP version 5.3 is now required. simplesamlphp-1.19.1/docs/simplesamlphp-modules.md0000644000000000000000000002126414042503475020766 0ustar rootrootSimpleSAMLphp modules ================================================== This document describes how the module system in SimpleSAMLphp works. It descibes what types of modules there are, how they are configured, and how to write new modules. Overview -------- There are currently three parts of SimpleSAMLphp which can be stored in modules - authentication sources, authentication processing filters and themes. There is also support for defining hooks - functions run at specific times. More than one thing can be stored in a single module. There is also support for storing supporting files, such as templates and dictionaries, in modules. The different functionalities which can be created as modules will be described in more detail in the following sections; what follows is a short introduction to what you can do with them: - Authentication sources implement different methods for authenticating users, for example simple login forms which authenticate against a database backend, or login methods which use client-side certificates. - Authentication processing filters perform various tasks after the user is authenticated and has a set of attributes. They can add, remove and modify attributes, do additional authentication checks, ask questions of the user, +++. - Themes allow you to package custom templates for multiple modules into a single module. ## Module layout Each SimpleSAMLphp module is stored in a directory under the `modules`-directory. The module directory contains the following directories and files: default-disable : The presence of this file indicates that the module is disabled by default. It can be enabled using the `module.enable` option in `config.php`. default-enable : The presence of this file indicates that the module is enabled by default. It can be disabled using the `module.enable` option in `config.php`. dictionaries : This directory contains dictionaries which belong to this module. To use a dictionary stored in a module, the extended tag names can be used: `{::}` For example, `{example:login:hello}` will look up `hello` in `modules/example/dictionaries/login.php`. : It is also possible to specify `:` as the default dictionary when instantiating the `\SimpleSAML\XHTML\Template` class. hooks : This directory contains hook functions for this module. Each file in this directory represents a single function. See the hook-section in the documentation for more information. lib : This directory contains classes which belong to this module. All classes must be named in the following pattern: `\SimpleSAML\Module\\` When looking up the filename of a class, SimpleSAMLphp will search for `` in the `lib` directory. Underscores in the class name will be translated into slashes. : Thus, if SimpleSAMLphp needs to load a class named `\SimpleSAML\Module\example\Auth\Source\Example`, it will load the file named `modules/example/lib/Auth/Source/Example.php`. templates : These are module-specific templates. To use one of these templates, specify `: