βŒˆβŒ‹ βŽ‡ branch:  freshcode


Artifact Content

Artifact eb96cc7ed58d235aebab3177c6147733aae55bd5:

  • File lib/deferred_openid_session.php — part of check-in [d7ae58c7dd] at 2015-04-14 12:07:33 on branch trunk — For resiliency support `set_password` update in session handler. Prepare login page for complaints about visible text field. (Alternatively just placeholder=notice for login feedback). (user: mario size: 3375)

<?php
/**
 * api: php
 * title: Session startup
 * description: Avoids session startup until actual login occured
 * license: MITL
 * version: 0.3.1
 *
 * Start $_SESSION only if there's already a session cookie present.
 * (Prevent needless cookies and tracking ids for not logged-in users.)
 *
 * The only handler that initiates any login process is `page_login.php`
 *
 */



// Kill off CloudFlare cookie when Do-Not-Track header present
if ($_SERVER->has("HTTP_DNT") and $_SERVER->boolean["HTTP_DNT"]) {
    header("Set-Cookie: __cfduid= ; path=/; domain=.freshcode.club; HttpOnly");
}





// Check for pre-existant cookie before defaulting to initiate session store
if ($_COOKIE->has("USER") or $_REQUEST->has("set_password")) {
    session_fresh();
}
// If there's none, make sure there's an array at least
if (!isset($_SESSION)) {
   $_SESSION = ["fromempty1"=>1];
}
// Populate stub array with empty defaults.
isset($_SESSION["openid"]) or $_SESSION["openid"] = "" and $_SESSION["reset_3"] = "3";
isset($_SESSION["name"]) or $_SESSION["name"] = "";
isset($_SESSION["csrf"]) or $_SESSION["csrf"] = [];
isset($_SESSION["password"]) or $_SESSION["password"] = "";



// verify incoming OpenID request
if ($_GET->has("openid_mode") and empty($_SESSION["openid"])) {

    try {
        $openid = new LightOpenID(HTTP_HOST);
        $openid->verify_peer = false;
        if ($openid->mode) {
            if ($openid->validate()) {
                $_COOKIE->no("USER") and session_fresh();
                $_SESSION["openid"] = $openid->identity;
                $_SESSION["name"] = $openid->getAttributes()["namePerson/friendly"];
            }
        }
    }
    catch (ErrorException $e) {
        die("OpenID verify exception (possibly endpoint / SSL error)");
    }

}
elseif ($_REQUEST->has("set_password")) {
    $_SESSION["password"] = $_REQUEST->ascii->nocontrol->trim["set_password"];
}



#session_write_close();


// Prevent some session tampering
function session_fresh() {

    // Initiate with current session identifier
    if ($_COOKIE->has("USER")) {
        session_id($_COOKIE->id["USER"]);
    }
    session_name("USER");
    session_set_cookie_params(7*24*3600, "/", HTTP_HOST, false, true);
#    session_cache_limiter('private');
    session_cache_expire(7*24*60);
    session_start();

    // Security by obscurity: lock client against User-Agent
    $useragent = $_SERVER->text->length…30["HTTP_USER_AGENT"];
    // Security by obscurity: IP subnet lock (or just major route for IPv6)
    $subnet = $_SERVER->ip->length…6["REMOTE_ADDR"];
    // Server-side timeout (7 days)
    $expire = time() + 7 * 24 * 3600;

    // New ID for mismatches
    if (empty($_SESSION["state/client"]) or $_SESSION["state/client"] != $useragent
    or  empty($_SESSION["state/subnet"]) or $_SESSION["state/subnet"] != $subnet
    or  empty($_SESSION["state/expire"]) or $_SESSION["state/expire"] < time()
    ) {
        $dat = json_encode($_SESSION);
# CloudFlare vs PHP 5.6.4
/*
        #session_destroy();
        #session_regenerate_id(true);
        #session_start();
*/
//        $_SESSION["destroyed2"] = "{$_COOKIE->json_encode['USER']} / $dat / $useragent / $subnet / " . time();
    }
    // and Repopulate status fields
    $_SESSION["state/client"] = $useragent;
    $_SESSION["state/subnet"] = $subnet;
    $_SESSION["state/expire"] = $expire;
}