From 3e02d5aff85babc3ffbfcf52313f2108e313aa23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:46:43 +0200 Subject: Adding upstream version 2.12.1. Signed-off-by: Daniel Baumann --- library/Icinga/Authentication/AuthChain.php | 269 ++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 library/Icinga/Authentication/AuthChain.php (limited to 'library/Icinga/Authentication/AuthChain.php') diff --git a/library/Icinga/Authentication/AuthChain.php b/library/Icinga/Authentication/AuthChain.php new file mode 100644 index 0000000..39468e3 --- /dev/null +++ b/library/Icinga/Authentication/AuthChain.php @@ -0,0 +1,269 @@ +config = Config::app(static::AUTHENTICATION_CONFIG); + } catch (NotReadableError $e) { + $this->config = new Config(); + $this->error = static::EPERM; + } + } else { + $this->config = $config; + } + } + + /** + * {@inheritdoc} + */ + public function authenticate(User $user, $password) + { + $this->error = null; + $backendsTried = 0; + $backendsWithError = 0; + foreach ($this as $backend) { + ++$backendsTried; + try { + $authenticated = $backend->authenticate($user, $password); + } catch (AuthenticationException $e) { + Logger::error($e); + ++$backendsWithError; + continue; + } + if ($authenticated) { + $user->setAdditional('backend_name', $backend->getName()); + $user->setAdditional('backend_type', $this->config->current()->get('backend')); + return true; + } + } + + if ($backendsTried === 0) { + $this->error = static::EEMPTY; + } elseif ($backendsTried === $backendsWithError) { + $this->error = static::EFAIL; + } elseif ($backendsWithError) { + $this->error = static::ENOTALL; + } else { + AuditHook::logActivity('login-failed', 'User failed to authenticate', null, $user->getUsername()); + } + + return false; + } + + /** + * Get the last error code + * + * @return int|null + */ + public function getError() + { + return $this->error; + } + + /** + * Whether authentication had errors + * + * @return bool + */ + public function hasError() + { + return $this->error !== null; + } + + /** + * Get whether to skip external user backends on iteration + * + * @return bool + */ + public function getSkipExternalBackends() + { + return $this->skipExternalBackends; + } + + /** + * Set whether to skip external user backends on iteration + * + * @param bool $skipExternalBackends + * + * @return $this + */ + public function setSkipExternalBackends($skipExternalBackends = true) + { + $this->skipExternalBackends = (bool) $skipExternalBackends; + return $this; + } + + /** + * Rewind the chain + * + * @return void + */ + public function rewind(): void + { + $this->currentBackend = null; + $this->config->rewind(); + } + + /** + * Get the current user backend + * + * @return UserBackendInterface + */ + public function current(): UserBackendInterface + { + return $this->currentBackend; + } + + /** + * Get the key of the current user backend config + * + * @return string + */ + public function key(): string + { + return $this->config->key(); + } + + /** + * Move forward to the next user backend config + * + * @return void + */ + public function next(): void + { + $this->config->next(); + } + + /** + * Check whether the current user backend is valid, i.e. it's enabled, not an external user backend and whether its + * config is valid + * + * @return bool + */ + public function valid(): bool + { + if (! $this->config->valid()) { + // Stop when there are no more backends to check + return false; + } + + $backendConfig = $this->config->current(); + if ((bool) $backendConfig->get('disabled', false)) { + $this->next(); + return $this->valid(); + } + + $name = $this->key(); + try { + $backend = UserBackend::create($name, $backendConfig); + } catch (ConfigurationError $e) { + Logger::error( + new ConfigurationError( + 'Can\'t create authentication backend "%s". An exception was thrown:', + $name, + $e + ) + ); + $this->next(); + return $this->valid(); + } + + if ($this->getSkipExternalBackends() + && $backend instanceof ExternalBackend + ) { + $this->next(); + return $this->valid(); + } + + $this->currentBackend = $backend; + return true; + } +} -- cgit v1.2.3