container = $container; } /** * Set the enabled authentication methods * * @param array $authenticationMethods * * @codeCoverageIgnore */ public function setAuthenticationMethods($authenticationMethods) { $this->authenticationMethods = $authenticationMethods; } /** * Get the enabled authentication methods * * @return array * * @codeCoverageIgnore */ public function getAuthenticationMethods() { return $this->authenticationMethods; } /** * Enable an authentication method * * @param integer $method */ public function addAuthenticationMethod($method) { if (!in_array($method, $this->authenticationMethods)) { $this->authenticationMethods[] = $method; } } /** * Disable an authentication method * * @param integer $method */ public function removeAuthenticationMethod($method) { if (in_array($method, $this->authenticationMethods)) { $key = array_search($method, $this->authenticationMethods); unset($this->authenticationMethods[$key]); } } /** * Set the required username for the HTTP Basic Authentication with TOTP method * * @param string $basicAuthUsername * * @codeCoverageIgnore */ public function setBasicAuthUsername($basicAuthUsername) { $this->basicAuthUsername = $basicAuthUsername; } /** * Get the required username for the HTTP Basic Authentication with TOTP method * * @return string * * @codeCoverageIgnore */ public function getBasicAuthUsername() { return $this->basicAuthUsername; } /** * Set the query parameter for the Auth_QueryString_TOTP method * * @param string $queryParam * * @codeCoverageIgnore */ public function setQueryParam($queryParam) { $this->queryParam = $queryParam; } /** * Get the query parameter for the Auth_QueryString_TOTP method * * @return string * * @codeCoverageIgnore */ public function getQueryParam() { return $this->queryParam; } /** * Set the query string for the password in the Auth_SplitQueryString_Plaintext method * * @param string $queryParamPassword * * @codeCoverageIgnore */ public function setQueryParamPassword($queryParamPassword) { $this->queryParamPassword = $queryParamPassword; } /** * Get the query string for the password in the Auth_SplitQueryString_Plaintext method * * @return string * * @codeCoverageIgnore */ public function getQueryParamPassword() { return $this->queryParamPassword; } /** * Set the query string for the username in the Auth_SplitQueryString_Plaintext method * * @param string $queryParamUsername * * @codeCoverageIgnore */ public function setQueryParamUsername($queryParamUsername) { $this->queryParamUsername = $queryParamUsername; } /** * Get the query string for the username in the Auth_SplitQueryString_Plaintext method * * @return string * * @codeCoverageIgnore */ public function getQueryParamUsername() { return $this->queryParamUsername; } /** * Set the time step in seconds for the TOTP in the Auth_HTTPBasicAuth_TOTP method * * @param int $timeStep * * @codeCoverageIgnore */ public function setTimeStep($timeStep) { $this->timeStep = (int)$timeStep; } /** * Get the time step in seconds for the TOTP in the Auth_HTTPBasicAuth_TOTP method * * @return int * * @codeCoverageIgnore */ public function getTimeStep() { return $this->timeStep; } /** * Set the secret key for the TOTP in the Auth_HTTPBasicAuth_TOTP method * * @param string $totpKey * * @codeCoverageIgnore */ public function setTotpKey($totpKey) { $this->totpKey = $totpKey; } /** * Get the secret key for the TOTP in the Auth_HTTPBasicAuth_TOTP method * * @return string * * @codeCoverageIgnore */ public function getTotpKey() { return $this->totpKey; } /** * Tries to get the transparent authentication credentials from the request * * @return array|null */ public function getTransparentAuthenticationCredentials() { $return = null; // Make sure there are enabled transparent authentication methods if (empty($this->authenticationMethods)) { return $return; } $input = $this->container->input; foreach ($this->authenticationMethods as $method) { switch ($method) { case self::Auth_HTTPBasicAuth_TOTP: if (empty($this->totpKey)) { continue 2; } if (empty($this->basicAuthUsername)) { continue 2; } if (!isset($_SERVER['PHP_AUTH_USER'])) { continue 2; } if (!isset($_SERVER['PHP_AUTH_PW'])) { continue 2; } if ($_SERVER['PHP_AUTH_USER'] != $this->basicAuthUsername) { continue 2; } $encryptedData = $_SERVER['PHP_AUTH_PW']; return $this->decryptWithTOTP($encryptedData); break; case self::Auth_QueryString_TOTP: if (empty($this->queryParam)) { continue 2; } $encryptedData = $input->get($this->queryParam, '', 'raw'); if (empty($encryptedData)) { continue 2; } $return = $this->decryptWithTOTP($encryptedData); if (!is_null($return)) { return $return; } break; case self::Auth_HTTPBasicAuth_Plaintext: if (!isset($_SERVER['PHP_AUTH_USER'])) { continue 2; } if (!isset($_SERVER['PHP_AUTH_PW'])) { continue 2; } return array( 'username' => $_SERVER['PHP_AUTH_USER'], 'password' => $_SERVER['PHP_AUTH_PW'] ); break; case self::Auth_QueryString_Plaintext: if (empty($this->queryParam)) { continue 2; } $jsonEncoded = $input->get($this->queryParam, '', 'raw'); if (empty($jsonEncoded)) { continue 2; } $authInfo = json_decode($jsonEncoded, true); if (!is_array($authInfo)) { continue 2; } if (!array_key_exists('username', $authInfo) || !array_key_exists('password', $authInfo)) { continue 2; } return $authInfo; break; case self::Auth_SplitQueryString_Plaintext: if (empty($this->queryParamUsername)) { continue 2; } if (empty($this->queryParamPassword)) { continue 2; } $username = $input->get($this->queryParamUsername, '', 'raw'); $password = $input->get($this->queryParamPassword, '', 'raw'); if (empty($username)) { continue 2; } if (empty($password)) { continue 2; } return array( 'username' => $username, 'password' => $password ); break; } } return $return; } /** * Decrypts a transparent authentication message using a TOTP * * @param string $encryptedData The encrypted data * * @return array The decrypted data */ private function decryptWithTOTP($encryptedData) { if (empty($this->totpKey)) { $this->cryptoKey = null; return null; } $totp = new Totp($this->timeStep); $period = $totp->getPeriod(); $period--; for ($i = 0; $i <= 2; $i++) { $time = ($period + $i) * $this->timeStep; $otp = $totp->getCode($this->totpKey, $time); $this->cryptoKey = hash('sha256', $this->totpKey . $otp); $aes = new Aes($this->cryptoKey); try { $ret = $aes->decryptString($encryptedData); } catch (\Exception $e) { continue; } $ret = rtrim($ret, "\000"); $ret = json_decode($ret, true); if (!is_array($ret)) { continue; } if (!array_key_exists('username', $ret)) { continue; } if (!array_key_exists('password', $ret)) { continue; } // Successful decryption! return $ret; } // Obviously if we're here we could not decrypt anything. Bail out. $this->cryptoKey = null; return null; } }