'POST', 'HTTPS' => 'on', 'SERVER_PORT' => 443, 'HTTP_HOST' => 'cacti.fixture', 'SERVER_NAME' => 'cacti.fixture', 'SCRIPT_NAME' => '/login_sso.php', 'REQUEST_URI' => '/login_sso.php?action=acs&realm=1001']);
$key = openssl_pkey_new(['private_key_bits' => 2048]);
$csr = openssl_csr_new(['commonName' => 'fixture'], $key, ['digest_alg' => 'sha256']);
$cert = openssl_csr_sign($csr, null, $key, 1, ['digest_alg' => 'sha256']);
openssl_pkey_export($key, $privateKey);
openssl_x509_export($cert, $certificate);
$providerRow = ['id' => 1, 'type' => $mode === 'openid' ? 4 : 3, 'name' => 'Fixture', 'enabled' => 'on', 'parameters' => json_encode(['idp_entity_id' => 'https://idp.fixture', 'idp_sso_url' => 'https://idp.fixture/sso', 'idp_slo_url' => 'https://idp.fixture/slo', 'idp_x509cert' => $certificate, 'want_assertions_signed' => true])];
$now = gmdate('Y-m-d\TH:i:s\Z');
$before = gmdate('Y-m-d\TH:i:s\Z', time() - 60);
$after = gmdate('Y-m-d\TH:i:s\Z', time() + 300);
$acs = 'https://cacti.fixture/login_sso.php?action=acs&realm=1001';
$audience = 'https://cacti.fixture/login_sso.php?action=metadata&realm=1001';
$assertion = 'https://idp.fixturealice@example.test' . $audience . 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport';
if ($mode !== 'unsigned') {
$assertion = OneLogin\Saml2\Utils::addSign($assertion, $privateKey, $certificate);
// addSign() targets protocol messages; assertions put Issuer before Signature.
$document = new DOMDocument();
$document->loadXML($assertion);
$issuer = $document->getElementsByTagNameNS('urn:oasis:names:tc:SAML:2.0:assertion', 'Issuer')->item(0);
$document->documentElement->insertBefore($issuer, $document->documentElement->firstChild);
$assertion = $document->saveXML();
}
$assertion = preg_replace('/^<\?xml[^>]*>\s*/', '', $assertion);
if ($mode === 'tampered') {
$assertion = str_replace('alice@example.test', 'mallory@example.test', $assertion);
}
$response = 'https://idp.fixture' . $assertion . '';
$_POST = ['SAMLResponse' => base64_encode($response)];
if ($mode !== 'missing') {
$_SESSION['sess_saml_request_1'] = ['request_id' => $mode === 'mismatch' ? '_other_request' : '_fixture_request', 'remember' => false];
}
require $root . '/include/csrf.php';
$exempt = csrf_is_saml_callback();
$csrf = csrf_check(false);
$login = false;
$username = '';
$replay = false;
if ($exempt && !in_array($mode, ['openid', 'disabled', 'inactive', 'other-page'], true)) {
$provider = new Cacti\Auth\SamlLoginProvider($providerRow);
$result = $provider->complete();
$login = $result->success;
$username = $result->username;
$replay = $provider->complete()->success;
}
print json_encode(['exempt' => $exempt, 'csrf' => $csrf, 'login' => $login, 'username' => $username, 'replay' => $replay]);