remoteAddr = $server['REMOTE_ADDR']; } $this->sslEnabled = $config->get('system', 'ssl_policy') === App\BaseURL::SSL_POLICY_FULL; $this->sitePrivateKey = $config->get('system', 'site_prvkey'); $authCookieDays = $config->get('system', 'auth_cookie_lifetime', self::DEFAULT_EXPIRE); $this->lifetime = $authCookieDays * 24 * 60 * 60; $this->cookie = $cookie; } /** * Checks if the Friendica cookie is set for a user * * @param string $hash The cookie hash * @param string $password The user password * @param string $privateKey The private Key of the user * * @return boolean True, if the cookie is set * */ public function check(string $hash, string $password, string $privateKey) { return hash_equals( $this->getHash($password, $privateKey), $hash ); } /** * Set the Friendica cookie for a user * * @param int $uid The user id * @param string $password The user password * @param string $privateKey The user private key * @param int|null $seconds optional the seconds * * @return bool */ public function set(int $uid, string $password, string $privateKey, int $seconds = null) { if (!isset($seconds)) { $seconds = $this->lifetime; } elseif (isset($seconds) && $seconds != 0) { $seconds = $seconds + time(); } $value = json_encode([ 'uid' => $uid, 'hash' => $this->getHash($password, $privateKey), 'ip' => $this->remoteAddr, ]); return $this->setCookie(self::NAME, $value, $seconds, '/', '', $this->sslEnabled, true); } /** * Returns the data of the Friendicas user cookie * * @return mixed|null The JSON data, null if not set */ public function getData() { // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie. if (isset($this->cookie[self::NAME])) { $data = json_decode($this->cookie[self::NAME]); if (!empty($data)) { return $data; } } return null; } /** * Clears the Friendica cookie of this user after leaving the page */ public function clear() { // make sure cookie is deleted on browser close, as a security measure return $this->setCookie(self::NAME, '', -3600, '/', '', $this->sslEnabled, true); } /** * Calculate the hash that is needed for the Friendica cookie * * @param string $password The user password * @param string $privateKey The private key of the user * * @return string Hashed data */ private function getHash(string $password, string $privateKey) { return hash_hmac( 'sha256', hash_hmac('sha256', $password, $privateKey), $this->sitePrivateKey ); } /** * Send a cookie - protected, internal function for test-mocking possibility * * @link https://php.net/manual/en/function.setcookie.php * * @param string $name * @param string $value [optional] * @param int $expire [optional] * @param string $path [optional] * @param string $domain [optional] * @param bool $secure [optional] * @param bool $httponly [optional] * * @return bool If output exists prior to calling this function, * */ protected function setCookie(string $name, string $value = null, int $expire = null, string $path = null, string $domain = null, bool $secure = null, bool $httponly = null) { return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); } }