Example #1
0
 /**
  * Handle a request for a file
  *
  * @param Request $request HTTP request
  * @return Response
  */
 public function getResponse(Request $request)
 {
     $response = new Response();
     $response->prepare($request);
     $path = implode('/', $request->getUrlSegments());
     if (!preg_match('~serve-file/e(\\d+)/l(\\d+)/d([ia])/c([01])/([a-zA-Z0-9\\-_]+)/(.*)$~', $path, $m)) {
         return $response->setStatusCode(400)->setContent('Malformatted request URL');
     }
     list(, $expires, $last_updated, $disposition, $use_cookie, $mac, $path_from_dataroot) = $m;
     if ($expires && $expires < time()) {
         return $response->setStatusCode(403)->setContent('URL has expired');
     }
     $hmac_data = array('expires' => (int) $expires, 'last_updated' => (int) $last_updated, 'disposition' => $disposition, 'path' => $path_from_dataroot, 'use_cookie' => (int) $use_cookie);
     if ((bool) $use_cookie) {
         $hmac_data['cookie'] = $this->getCookieValue($request);
     }
     ksort($hmac_data);
     $hmac = $this->crypto->getHmac($hmac_data);
     if (!$hmac->matchesToken($mac)) {
         return $response->setStatusCode(403)->setContent('HMAC mistmatch');
     }
     $dataroot = $this->config->getDataPath();
     $filenameonfilestore = "{$dataroot}{$path_from_dataroot}";
     if (!is_readable($filenameonfilestore)) {
         return $response->setStatusCode(404)->setContent('File not found');
     }
     $actual_last_updated = filemtime($filenameonfilestore);
     if ($actual_last_updated != $last_updated) {
         return $response->setStatusCode(403)->setContent('URL has expired');
     }
     $if_none_match = $request->headers->get('if_none_match');
     if (!empty($if_none_match)) {
         // strip mod_deflate suffixes
         $request->headers->set('if_none_match', str_replace('-gzip', '', $if_none_match));
     }
     $etag = '"' . $actual_last_updated . '"';
     $response->setPublic()->setEtag($etag);
     if ($response->isNotModified($request)) {
         return $response;
     }
     $public = $use_cookie ? false : true;
     $content_disposition = $disposition == 'i' ? 'inline' : 'attachment';
     $headers = ['Content-Type' => (new MimeTypeDetector())->getType($filenameonfilestore)];
     $response = new BinaryFileResponse($filenameonfilestore, 200, $headers, $public, $content_disposition);
     $sendfile_type = $this->config->getVolatile('X-Sendfile-Type');
     if ($sendfile_type) {
         $request->headers->set('X-Sendfile-Type', $sendfile_type);
         $mapping = (string) $this->config->getVolatile('X-Accel-Mapping');
         $request->headers->set('X-Accel-Mapping', $mapping);
         $response->trustXSendfileTypeHeader();
     }
     $response->prepare($request);
     if (empty($expires)) {
         $expires = strtotime('+1 year');
     }
     $expires_dt = (new DateTime())->setTimestamp($expires);
     $response->setExpires($expires_dt);
     $response->setEtag($etag);
     return $response;
 }
Example #2
0
 function testMacAlteredByArrayTypeModification()
 {
     $crypto = new ElggCrypto();
     $key = 'a very bad key';
     $t1 = $crypto->getHmac([12, 34], 'sha256', $key)->getToken();
     $t2 = $crypto->getHmac([12, '34'], 'sha256', $key)->getToken();
     $this->assertNotEquals($t1, $t2);
 }
Example #3
0
/**
 * Initialise the site secret (32 bytes: "z" to indicate format + 186-bit key in Base64 URL).
 *
 * Used during installation and saves as a datalist.
 *
 * Note: Old secrets were hex encoded.
 *
 * @return mixed The site secret hash or false
 * @access private
 * @todo Move to better file.
 */
function init_site_secret()
{
    $secret = 'z' . ElggCrypto::getRandomString(31);
    if (datalist_set('__site_secret__', $secret)) {
        return $secret;
    }
    return FALSE;
}
Example #4
0
/**
 * Generate an 8 character Base64 URL salt for the password
 *
 * @return string
 * @access private
 */
function _elgg_generate_password_salt()
{
    return ElggCrypto::getRandomString(8);
}
Example #5
0
/**
 * Initialises the system session and potentially logs the user in
 *
 * This function looks for:
 *
 * 1. $_SESSION['id'] - if not present, we're logged out, and this is set to 0
 * 2. The cookie 'elggperm' - if present, checks it for an authentication
 * token, validates it, and potentially logs the user in
 *
 * @uses $_SESSION
 *
 * @return bool
 * @access private
 */
function _elgg_session_boot()
{
    global $DB_PREFIX, $CONFIG;
    // Use database for sessions
    // HACK to allow access to prefix after object destruction
    $DB_PREFIX = $CONFIG->dbprefix;
    if (!isset($CONFIG->use_file_sessions)) {
        session_set_save_handler("_elgg_session_open", "_elgg_session_close", "_elgg_session_read", "_elgg_session_write", "_elgg_session_destroy", "_elgg_session_gc");
    }
    session_name('Elgg');
    session_start();
    // Generate a simple token (private from potentially public session id)
    if (!isset($_SESSION['__elgg_session'])) {
        $_SESSION['__elgg_session'] = ElggCrypto::getRandomString(32, ElggCrypto::CHARS_HEX);
    }
    // test whether we have a user session
    if (empty($_SESSION['guid'])) {
        // clear session variables before checking cookie
        unset($_SESSION['user']);
        unset($_SESSION['id']);
        unset($_SESSION['guid']);
        unset($_SESSION['code']);
        // is there a remember me cookie
        if (!empty($_COOKIE['elggperm'])) {
            // we have a cookie, so try to log the user in
            $code = $_COOKIE['elggperm'];
            $code = md5($code);
            if ($user = get_user_by_code($code)) {
                // we have a user, log him in
                $_SESSION['user'] = $user;
                $_SESSION['id'] = $user->getGUID();
                $_SESSION['guid'] = $_SESSION['id'];
                $_SESSION['code'] = $_COOKIE['elggperm'];
            } else {
                if (_elgg_is_legacy_remember_me_token($_COOKIE['elggperm'])) {
                    // may be attempt to brute force legacy low-entropy codes
                    sleep(1);
                }
                setcookie("elggperm", "", time() - 86400 * 30, "/");
            }
        }
    } else {
        // we have a session and we have already checked the fingerprint
        // reload the user object from database in case it has changed during the session
        if ($user = get_user($_SESSION['guid'])) {
            $_SESSION['user'] = $user;
            $_SESSION['id'] = $user->getGUID();
            $_SESSION['guid'] = $_SESSION['id'];
        } else {
            // user must have been deleted with a session active
            unset($_SESSION['user']);
            unset($_SESSION['id']);
            unset($_SESSION['guid']);
            unset($_SESSION['code']);
            if (!empty($_COOKIE['elggperm']) && _elgg_is_legacy_remember_me_token($_COOKIE['elggperm'])) {
                // replace user's old weaker-entropy code with new one
                $code = _elgg_generate_remember_me_token();
                $_SESSION['code'] = $code;
                $user->code = md5($code);
                $user->save();
                setcookie("elggperm", $code, time() + 86400 * 30, "/");
            }
        }
    }
    if (isset($_SESSION['guid'])) {
        set_last_action($_SESSION['guid']);
    }
    elgg_register_action('login', '', 'public');
    elgg_register_action('logout');
    // Register a default PAM handler
    register_pam_handler('pam_auth_userpass');
    // Initialise the magic session
    global $SESSION;
    $SESSION = new ElggSession();
    // Finally we ensure that a user who has been banned with an open session is kicked.
    if (isset($_SESSION['user']) && $_SESSION['user']->isBanned()) {
        session_destroy();
        return false;
    }
    return true;
}