* @brief Security module for VSPF */ if(!function_exists("check_token_abuse")) { function check_token_abuse($_p_token, $_n_token) { $abuse = false; $_c_token = $_p_token . $_n_token; if(empty($_c_token) || $_p_token != $_n_token || strlen($_c_token) != (strlen($_p_token) + strlen($_n_token)) || !ctype_alnum($_c_token)) { $abuse = true; } return $abuse; } } if(!function_exists("make_random_id")) { function make_random_id($length = 10) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } } if(!function_exists("set_session")) { function set_session($session_name, $value) { if(PHP_VERSION < '5.3.0') { session_register($session_name); } $$session_name = $_SESSION["$session_name"] = $value; } } if(!function_exists("get_session")) { function get_session($session_name) { $session_value = ""; if(!array_key_empty($session_name, $_SESSION)) { $session_value = $_SESSION[$session_name]; } return $session_value; } } if(!function_exists("set_session_token")) { function set_session_token() { $_token = make_random_id(10); set_session("_token", $_token); return $_token; } } if(!function_exists("get_session_token")) { function get_session_token() { return get_session("_token"); } } if(!function_exists("check_token_abuse_by_requests")) { function check_token_abuse_by_requests($name, $method="_POST") { global $requests; $flag = false; if(array_key_empty($name, $requests[$method])) { $flag = true; } else { $flag = check_token_abuse($requests[$method][$name], get_session($name)); } return $flag; } } if(!function_exists("check_login_session")) { function check_login_session($ss_key, $config) { $flag = false; $session_name = get_password($ss_key); $session_file = $config['session_dir'] . '/' . protect_dir_path($session_name); $session_stored_key = ""; if(file_exists($session_file)) { $fh = fopen($session_file, 'r'); if($session_stored_key = fread($fh, filesize($session_file))) { if(!check_token_abuse($session_stored_key, $session_name)) { $flag = true; } } } return $flag; } } if(!function_exists("store_login_session")) { function store_login_session($ss_key, $config) { $flag = false; $session_name = get_password($ss_key); $session_file = $config['session_dir'] . '/' . protect_dir_path($session_name); $fh = fopen($session_file, 'w'); if($fh !== false) { if(fwrite($fh, $session_name)) { $flag = check_login_session($ss_key, $config); } @chmod($session_file, 0777); } return $flag; } } if(!function_exists("process_safe_login")) { function process_safe_login($user_name, $user_password, $user_profile=array(), $escape_safe=false) { $config = get_config(); $flag = false; $ss_key = get_session("ss_key"); $user_id = 0; $stored_password = ""; if(!array_key_empty("user_id", $user_profile)) { $user_id = $user_profile['user_id']; } if(!array_key_empty("user_password", $user_profile)) { $stored_password = $user_profile['user_password']; } if(!empty($ss_key) && check_login_session($ss_key, $config)) { $flag = true; } else { $ss_key = make_random_id(10); if(check_match_password($stored_password, $user_password) || $escape_safe == true) { set_session("ss_user_id", $user_id); set_session("ss_user_name", $user_name); set_session("ss_key", $ss_key); $flag = store_login_session($ss_key, $config); } } return $flag; } } if(!function_exists("check_empty_requests")) { function check_empty_requests($no_empty_fields, $method_get=true) { global $requests; $errors = array(); $check_data = $method_get ? $requests['_GET'] : $requests['_POST']; foreach($no_empty_fields as $fieldname) { if(array_key_empty($fieldname, $check_data)) { $errors[] = array( "fieldname" => $fieldname, "message" => "{$fieldname} 항목은 공백일 수 없습니다." ); } } return $errors; } } if(!function_exists("get_hashed_text")) { function get_hashed_text($text, $algo="sha1") { $hashed_text = ""; switch($algo) { case "sha1": $hashed_text = sha1($text); break; case "md5": $hashed_text = md5($text); break; case "crypt": $hashed_text = crypt($text); default: $hashed_text = ""; } return $hashed_text; } } if(!function_exists("get_salt")) { function get_salt() { $config = get_config(); $salt = ""; if(!array_key_empty("salt", $config)) { $salt = $config['salt']; } else { $salt = make_random_id(16); } return $salt; } } if(!function_exists("get_password")) { function get_password($text, $algo="sha1") { $config = get_config(); $salt = get_salt(); $is_not_supported = false; $plain_text = $text; $hashed_text = ""; if(!empty($salt)) { $plain_text .= $salt; } $hashed_text = get_hashed_text($plain_text, $algo); if(empty($hashed_text)) { $is_not_supported = true; } if($is_not_supported) { $hashed_text = $plain_text; } return $hashed_text; } } if(!function_exists("check_match_password")) { function check_match_password($p, $n, $algo="sha1") { $flag = false; $salt = get_salt(); $n_plain_text = $n . $salt; $n_hashed_text = ""; switch($algo) { case "sha1": $n_hashed_text = get_hashed_text($n_plain_text, $algo); $flag = ($n_hashed_text == $p); break; case "md5": $n_hashed_text = get_hashed_text($n_plain_text, $algo); $flag = ($n_hashed_text == $p); break; case "crypt": $flag = (crypt($n_plain_text, $p) == $p); break; default: $flag = false; } return $flag; } } if(!function_exists("protect_dir_path")) { function protect_dir_path($path) { $path = str_replace('/', '_', $path); return $path; } } if(!function_exists("session_logout")) { function session_logout() { $config = get_config(); $flag = false; $ss_user_name = get_session("ss_user_name"); $ss_key = get_session("ss_key"); if(!empty($ss_key)) { set_session("ss_user_name", ""); set_session("ss_key", ""); } // delete session file @unlink($config['session_dir'] . '/' . protect_dir_path($ss_key)); // permanently destory session_unset(); session_destroy(); // check ereased token $abuse = check_token_abuse($ss_user_name, get_session("ss_user_name")); $abuse = ($abuse && check_token_abuse($ss_key, get_session("ss_key"))); // apply result $flag = $abuse; return $flag; } } if(!function_exists("get_current_user_id")) { function get_current_user_id() { return get_current_session_data("ss_user_id"); } } if(!function_exists("get_current_user_name")) { function get_current_user_name() { return get_current_session_data("ss_user_name"); } } if(!function_exists("get_current_session_data")) { function get_current_session_data($name) { $current_data = ""; $ss_data = get_session($name); $ss_key = get_session("ss_key"); $abuse = check_token_abuse($ss_data, $ss_data); // self check $abuse = ($abuse && check_token_abuse($ss_key, $ss_key)); // self check if(!$abuse) { $current_data = $ss_data; } return $current_data; } } if(!function_exists("get_user_profile")) { function get_user_profile() { $user_profile = array( "user_id" => get_current_user_id(), "user_name" => get_current_user_name() ); return $user_profile; } } if(!function_exists("get_fixed_id")) { function get_fixed_id($str, $len=0, $salt="") { $config = get_config(); $init_salt = empty($salt) ? $config['salt'] : $salt; $init_len = ($len < 1) ? $config['autolen'] : $len; return substr(get_hashed_text(get_hashed_text($str, "sha1") . $init_salt, "sha1"), 0, $init_len); } } // https://stackoverflow.com/questions/1996122/how-to-prevent-xss-with-html-php if(!function_exists("get_clean_xss")) { function get_clean_xss($data, $notags=0) { if(is_string($data)) { // if no tags (equals to strip_tags) if($notags > 0) { return strip_tags($data); } // Fix &entity\n; $data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data); $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); // Remove any attribute starting with "on" or xmlns $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); // Remove javascript: and vbscript: protocols $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); // Only works in IE: $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); // Remove namespaced elements (we do not need them) $data = preg_replace('#]*+>#i', '', $data); do { // Remove really unwanted tags $old_data = $data; $data = preg_replace('#]*+>#i', '', $data); } while ($old_data !== $data); } // we are done... return $data; } } if(!function_exists("get_clean_newlines")) { function get_clean_newlines($data) { return is_string($data) ? trim(preg_replace('~[\r\n]+~', ' ', $data)) : $data; } } if(!function_exists("get_clean_text")) { function get_clean_text($data) { return is_string($data) ? get_clean_newlines(get_clean_xss($data, 1)) : $data; } } // support curl or jsonp(callback) if(!function_exists("get_callable_token")) { function get_callable_token($token, $callback="", $charset="utf-8") { $callback = get_clean_xss($callback); $retdata = ""; if(empty($callback)) { $retdata = $token; } else { $retdata = "function $callback() { return '$token'; }"; } return $retdata; } } if(!function_exists("encapsulate_text")) { function encapsulate_text($text, $algo="aes-128-cbc", $key="", $iv="", $hash="", $hash_algo="sha1") { $config = get_config(); $encapsulated_text = ""; $encrypted_text = ""; // when fail hash test if(!empty($hash)) { if($hash != get_hashed_text($text, $hash_algo)) { return $encapsulated_text; } } // initialize text $init_text = base64_encode($text); if($algo == "base64") { $encapsulated_text = $init_text; } else { $init_key = empty($key) ? $config['masterkey'] : $key; $init_iv = empty($iv) ? $config['masteriv'] : $iv; if(function_exists("openssl_encrypt")) { $encrypted_text = @openssl_encrypt($init_text, $algo, $init_key, true, $init_iv); if(!empty($encrypted_text)) { $encapsulated_text = base64_encode($encrypted_text); } } } return $encapsulated_text; } } if(!function_exists("decapsulate_text")) { function decapsulate_text($text, $algo="aes-128-cbc", $key="", $iv="", $hash="", $hash_algo="sha1") { $config = get_config(); $decapsulate_text = ""; $decrypted_text = ""; // initialize text $init_text = base64_decode($text); if($algo = "base64") { $decapsulate_text = $init_text; } else { $init_key = empty($key) ? $config['masterkey'] : $key; $init_iv = empty($iv) ? $config['masteriv'] : $iv; if(function_exists("openssl_decrypt")) { $encrypted_text = @openssl_decrypt($init_text, $algo, $init_key, true, $init_iv); if(!empty($encrypted_text)) { $decapsulate_text = base64_encode($decrypted_text); } } } // when fail hash test if(!empty($hash)) { if($hash != get_hashed_text($decapsulate_text, $hash_algo)) { $decapsulate_text = ""; } } return $decapsulate_text; } } // https://wiki.ubuntu.com/DevelopmentCodeNames if(!function_exists("get_generated_name")) { function get_generated_name() { $config = get_config(); $generated_name = ""; $adjectives = explode(',', $config['adjectives']); $animals = explode(',', $config['animals']); $c_adjective = ucfirst($adjectives[rand(0, count($adjectives) - 1)]); $c_animal = ucfirst($animals[rand(0, count($animals) - 1)]); $generated_name = $c_adjective . " " . $c_animal; return $generated_name; } } // start session (enable $_SESSION) session_start();