1<?php 2 3DEFINE("SESSION_FILE_PREFIX" ,"session_test_"); 4 5/* 6 * == General Return Value Rule == 7 * 8 * Returning FALSE indicates FATAL error. 9 * Exceptions are: gc(), validate_sid() 10 * 11 * == Session Data Lock == 12 * 13 * Session data lock is mandatory. Lock must be exclusive. i.e. Block read also. 14 * 15 * == Collision Detection == 16 * 17 * Collision detection is mandatory to reject attacker initialized session ID. 18 * Coolision detection is absolute requirement for secure session. 19 */ 20 21 22/* Open session data database */ 23function open($save_path, $session_name) { 24 // string $save_path - Directory path, connection strings, etc. Default: session.save_path 25 // string $session_name - Session ID cookie name. Default: session.name 26 27 global $session_save_path, $name; 28 $session_save_path = $save_path; 29 $name = $session_name; 30 echo "Open [${session_save_path},${session_name}]\n"; 31 32 // MUST return bool. Return TRUE for success. 33 return true; 34} 35 36/* Close session data database */ 37function close() { 38 // void parameter 39 // NOTE: This function should unlock session data, if write() does not unlock it. 40 41 global $session_save_path, $name; 42 echo "Close [${session_save_path},${name}]\n"; 43 44 // MUST return bool. Return TRUE for success. 45 return true; 46} 47 48/* Read session data */ 49function read($id) { 50 // string $id - Session ID string 51 // NOTE: All production session save handler MUST implement "exclusive" lock. 52 // e.g. Use "serializable transaction isolation level" with RDBMS. 53 // read() would be the best place for locking for most save handlers. 54 55 global $session_save_path, $name, $session_id; 56 $session_id = $id; 57 echo "Read [${session_save_path},${id}]\n"; 58 $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; 59 // read MUST create file. Otherwise, strict mode will not work 60 touch($session_file); 61 62 // MUST return STRING for successful read(). 63 // Return FALSE only when there is error. i.e. Do not return FALSE 64 // for non-existing session data for the $id. 65 return (string) @file_get_contents($session_file); 66} 67 68/* Write session data */ 69function write($id, $session_data) { 70 // string $id - Session ID string 71 // string $session_data - Session data string serialized by session serializer. 72 // NOTE: This function may unlock session data locked by read(). If write() is 73 // is not suitable place your handler to unlock. Unlock data at close(). 74 75 global $session_save_path, $name, $session_id; 76 $session_id = $id; 77 echo "Write [${session_save_path},${id},${session_data}]\n"; 78 $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; 79 if ($fp = fopen($session_file, "w")) { 80 $return = fwrite($fp, $session_data); 81 fclose($fp); 82 return $return === FALSE ? FALSE : TRUE; 83 } 84 85 // MUST return bool. Return TRUE for success. 86 return false; 87} 88 89/* Remove specified session */ 90function destroy($id) { 91 // string $id - Session ID string 92 93 global $session_save_path, $name; 94 echo "Destroy [${session_save_path},${id}]\n"; 95 $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; 96 unlink($session_file); 97 98 // MUST return bool. Return TRUE for success. 99 // Return FALSE only when there is error. i.e. Do not return FALSE 100 // for non-existing session data for the $id. 101 return true; 102} 103 104/* Perform garbage collection */ 105function gc($maxlifetime) { 106 // long $maxlifetime - GC TTL in seconds. Default: session.gc_maxlifetime 107 108 global $session_save_path, $name; 109 $gc_cnt = 0; 110 $directory = opendir($session_save_path."/"); 111 $length = strlen(SESSION_FILE_PREFIX); 112 while (($file = readdir($directory)) !== FALSE) { 113 $qualified = ($session_save_path."/".$file); 114 if (is_file($qualified) === TRUE) { 115 if (substr($file, 0, $length) === SESSION_FILE_PREFIX && (filemtime($qualified) + $maxlifetime <= time() )) { 116 unlink($qualified); 117 $gc_cnt++; 118 } 119 } 120 } 121 closedir($directory); 122 123 // SHOULD return long (number of deleted sessions). 124 // Returning TRUE works also, but it will not report correct number of deleted sessions. 125 // Return negative value for error. FALSE does not work because it's the same as 0. 126 return $gc_cnt; 127} 128 129/* Create new secure session ID */ 130function create_sid() { 131 // void parameter 132 // NOTE: Defining create_sid() is mandatory because validate_sid() is mandatory for 133 // security reasons for production save handler. 134 // PHP 7.1 has session_create_id() for secure session ID generation. Older PHPs 135 // must generate secure session ID by yourself. 136 // e.g. hash('sha2', random_bytes(64)) or use /dev/urandom 137 138 $id = ('PHPT-'.time()); 139 echo "CreateID [${id}]\n"; 140 141 // MUST return session ID string. 142 // Return FALSE for error. 143 return $id; 144} 145 146/* Check session ID collision */ 147function validate_sid($id) { 148 // string $id - Session ID string 149 150 global $session_save_path, $name; 151 echo "ValidateID [${session_save_path},${id}]\n"; 152 $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; 153 $ret = file_exists($session_file); 154 155 // MUST return bool. Return TRUE for collision. 156 // NOTE: This handler is mandatory for session security. 157 // All save handlers MUST implement this handler. 158 // Check session ID collision, return TRUE when it collides. 159 // Otherwise, return FALSE. 160 return $ret; 161} 162 163/* Update session data access time stamp WITHOUT writing $session_data */ 164function update($id, $session_data) { 165 // string $id - Session ID string 166 // string $session_data - Session data serialized by session serializer 167 // NOTE: This handler is optional. If your session database cannot 168 // support time stamp updating, you must not define this. 169 170 global $session_save_path, $name; 171 echo "Update [${session_save_path},${id}]\n"; 172 $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; 173 $ret = touch($session_file); 174 175 // MUST return bool. Return TRUE for success. 176 return $ret; 177} 178 179 180function feature() { 181 /* NOT IMPLEMENTED YET */ 182 /* TYPES: gc, create_sid, use_strict_mode, minimzie_lock, lazy_write 183 /* VALUES: 0=unknown, 1=supported, 2=partially supported, 3=unsupported */ 184 return array('gc'=>0, 185 'create_sid'=>1, 186 'use_strict_mode'=>2, 187 'minimize_lock'=>3, 188 'lazy_write'=>4, 189 'invalid'=>5, 190 'another invalid'=>6 191 ); 192} 193 194?> 195