0

Hi I have this session class. The session seems to work but then after a minute or a few page clicks later the session totally dies. I have taken this code from: http://www.wikihow.com/Create-a-Secure-Session-Managment-System-in-PHP-and-MySQL and made it into my class. I was wondering if anyone could tell me why its dying? I have a database connection established with the var $sql

Its strange that it works for a little while then it dies.

EDIT: I put none in the return of the read function, I then echoed this and its the read function that is turning no data.

On the site I got this code from it has if statements like if(!isset($this->gc_stmt)) { if(!isset($this->key_stmt)) { if(!isset($this->delete_stmt)) { if(!isset($this->w_stmt)) { inside the functions, I have dropped these in my code because I don't understand how its setting them. Could this be why?

function __construct(){
    global $system;

    // set our custom session functions.
    session_set_save_handler(array($this, 'open'), 
                            array($this, 'close'), 
                            array($this, 'read'), 
                            array($this, 'write'), 
                            array($this, 'destroy'), 
                            array($this, 'gc'));

    // This line prevents unexpected effects when using objects as save handlers.
    register_shutdown_function('session_write_close');

    $this->start_session();
}

function start_session(){
    global $system;

    // Hash algorithm to use for the sessionid. (use hash_algos() to get a list of available hashes.)
    $session_hash = 'sha512';

    // Check if hash is available
    if (in_array($session_hash, hash_algos())) {

        // Set the has function.
        ini_set('session.hash_function', $session_hash);
    }
    // How many bits per character of the hash.
    // The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").
    ini_set('session.hash_bits_per_character', 5);

    // Force the session to only use cookies, not URL variables.
    ini_set('session.use_only_cookies', 1);

    // Set the parameters
    $time = 86400 * $system->system_settings('cookie_days');
    $cookieParams = session_get_cookie_params(); 
    // Set the parameters
    session_set_cookie_params($time, $cookieParams["path"], $cookieParams["domain"], false, true); 
    // Change the session name 
    session_name(SESSION_ID_NAME);
    // Now we cat start the session
    session_start();
    // This line regenerates the session and delete the old one. 
    // It also generates a new encryption key in the database. 
    session_regenerate_id(true);    
}


function open(){

    return true;
}

function close() {

    return true;
}

function read($id) {
    global $sql;

    $result = $sql->sql_query("SELECT data FROM `".TABLE_SESSIONS."` WHERE id = '".$id."' LIMIT 1");

    if($sql->sql_num($result) == 1){

        $row = $sql->sql_fetch($result);
        $data = $row['data'];

        $key = $this->getkey($id);
        $data = $this->decrypt($data, $key);

        return $data;
    }else{

        return '';
    }       
}

function write($id, $data){
    global $sql;

    // Get unique key
    $key = $this->getkey($id);
    // Encrypt the data
    $data = $this->encrypt($data, $key);

    $time = time();
    $sql->sql_query("REPLACE INTO `".TABLE_SESSIONS."` (id, set_time, data, session_key) VALUES ('".$id."', '".$time."', '".$data."', '".$key."')");

    return true;
}

function destroy($id){
    global $sql;

    $sql->sql_delete(TABLE_SESSIONS, " id='".$id."'");
    return true;
}

function gc($max){
    global $sql;

    $old = time() - $max;
    $sql->sql_delete(TABLE_SESSIONS, " set_time < '".$old."'");
    return true;
}

private function getkey($id){
    global $sql;

    $result = $sql->sql_query("SELECT session_key FROM `".TABLE_SESSIONS."` WHERE id = '".$id."' LIMIT 1");

    if($sql->sql_num($result) == 1){ 

        $row = $sql->sql_fetch($result);
        return $row['session_key'];
    }else{

        $random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
        return $random_key;
    }
}


private function encrypt($data, $key) {

    $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH';
    $key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv));

    return $encrypted;
}

private function decrypt($data, $key) {

    $salt = 'cH!swe!retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39=E@rAsp7c-Ph@pH';
    $key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv);

    return $decrypted;
}
Jay
  • 68
  • 1
  • 10
  • One thing I spotted which am not 100% certain will fix your problem is this `".TABLE_SESSIONS."` which should probably read as `'".TABLE_SESSIONS."'` – Funk Forty Niner Oct 15 '13 at 14:52
  • 1
    "totally dies" is totally useless for debugging purposes. HOW does it die? – Marc B Oct 15 '13 at 14:52
  • 1
    @Fred-ii-: wrong. using `'` will turn the table name into a simple string and CAUSE a syntax error. `INSERT INTO 'foo'` is never going to work. – Marc B Oct 15 '13 at 14:53
  • The `read` function returns blank. The `".TABLE_SESSIONS."` is fine mate – Jay Oct 15 '13 at 14:54
  • @MarcB Thanks Marc. As I said, I wasn't 100% sure about that. – Funk Forty Niner Oct 15 '13 at 14:54
  • 4
    Respectfully, you need to try to narrow down your problem. Posting a bunch of code that we can't run is going to make it hard for us to solve. – user1477388 Oct 15 '13 at 14:55
  • Where is it "dying"? What happens when it "dies"? – gen_Eric Oct 15 '13 at 14:55
  • Would it be the `gc` function deleting the session for some reason? – Jay Oct 15 '13 at 15:02
  • @Jay I noticed you're declaring `$data` as a variable but not `$id` – Funk Forty Niner Oct 15 '13 at 15:04
  • THe `$id` comes from the functions param? – Jay Oct 15 '13 at 15:11
  • 1
    Just as an advice: the code is **really bad designed**! It uses global variables and it does not use prepared statements. – ComFreek Oct 15 '13 at 15:29
  • @ComFreek Whats wrong with using `global $system;` ? Prepared statements are being introduced soon. – Jay Oct 15 '13 at 15:37
  • @Jay Global variables are in most cases a code smell. You can read about here for example: http://stackoverflow.com/questions/176118/when-is-it-ok-to-use-a-global-variable-in-c I'd create a class and put the functions into it. – ComFreek Oct 15 '13 at 15:40
  • @ComFreek so how would I get the $sql variable inside the function without using the `global` its not possible? – Jay Oct 15 '13 at 15:41
  • @Jay One could pass it to the constructor when creating the object ("Dependency Injection"). – ComFreek Oct 15 '13 at 15:43
  • @comFreek `global $sql;` is the only way to get the SQL into this class. What other ways are there? It needs to be this? – Jay Oct 15 '13 at 15:45
  • @Jay Sorry, but explaining those principles would be too much for one comment (simply speaking, always have the SQL variable stored in an object or class; not globally). I'd advise you to take a look at simple PHP framework tutorials or read StackOverflow questions and answers. You might also ask a question here (or preferably at Programmers SE), please note though that you should word it well and give specific questions or problems (and share your research results or links). – ComFreek Oct 15 '13 at 16:26
  • @ComFreek `$sql` is an object `$sql = new sql;` So its fine? – Jay Oct 15 '13 at 18:04

0 Answers0