merged session manager/memcache limiter
cleanup for PR
This commit is contained in:
parent
c373fc7192
commit
6398e5dfec
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
# Local Config
|
||||
/public/include/config/global.inc.php
|
||||
/public/include/config/security.inc.php
|
||||
|
||||
# Templates
|
||||
/public/templates/compile/*.php
|
||||
@ -14,7 +15,6 @@
|
||||
# Test configs
|
||||
public/include/config/global.inc.scrypt.php
|
||||
public/include/config/global.inc.sha.php
|
||||
exploits/*
|
||||
|
||||
# IDE Settings
|
||||
/.idea/*
|
||||
|
||||
@ -18,6 +18,21 @@ limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
define('SECURITY', '*)WT#&YHfd');
|
||||
// Whether or not to check SECHASH for validity, still checks if SECURITY defined as before if disabled
|
||||
define('SECHASH_CHECK', false);
|
||||
|
||||
// Nothing below here to configure, move along...
|
||||
|
||||
// change SECHASH every second, we allow up to 3 sec back for slow servers
|
||||
if (SECHASH_CHECK) {
|
||||
function fip($tr=0) { return md5(SECURITY.(time()-$tr).SECURITY); }
|
||||
define('SECHASH', fip());
|
||||
function cfip() { return (fip()==SECHASH||fip(1)==SECHASH||fip(2)==SECHASH) ? 1 : 0; }
|
||||
} else {
|
||||
function cfip() { return (@defined('SECURITY')) ? 1 : 0; }
|
||||
}
|
||||
|
||||
// MODIFY THIS
|
||||
// We need to find our include files so set this properly
|
||||
define("BASEPATH", "../public/");
|
||||
|
||||
113
public/include/admin_checks.php
Normal file
113
public/include/admin_checks.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA']['id'])) {
|
||||
|
||||
if (!include_once(INCLUDE_DIR . '/lib/jsonRPCClient.php')) die('Unable to load libs');
|
||||
|
||||
$notice = array();
|
||||
$enotice = array();
|
||||
$error = array();
|
||||
|
||||
// setup some basic stuff for checking
|
||||
$apache_user = posix_getuid();
|
||||
$apache_user = (function_exists('posix_getpwuid')) ? posix_getpwuid($apache_user) : $apache_user;
|
||||
|
||||
// setup checks
|
||||
// check if memcache isn't available but enabled in config -> error
|
||||
if (!class_exists('Memcached') && $config['memcache']['enabled']) {
|
||||
$error[] = "You have memcache enabled in your config and it's not available. Install the package on your system.";
|
||||
}
|
||||
// if it's not enabled, test it if it exists, if it works -> error tell them to enable, -> otherwise notice it's disabled
|
||||
if (!$config['memcache']['enabled']) {
|
||||
if (PHP_OS == 'WINNT') {
|
||||
require_once(CLASS_DIR . 'memcached.class.php');
|
||||
}
|
||||
if (class_exists('Memcached')) {
|
||||
$memcache_test = @new Memcached();
|
||||
$memcache_test_add = @$memcache_test->addServer($config['memcache']['host'], $config['memcache']['port']);
|
||||
$randmctv = rand(5,10);
|
||||
$memcache_test_set = @$memcache_test->set('test_mpos_setval', $randmctv);
|
||||
$memcache_test_get = @$memcache_test->get('test_mpos_setval');
|
||||
}
|
||||
if (class_exists('Memcached') && $memcache_test_get == $randmctv) {
|
||||
$error[] = "You have memcache disabled in the config and it's available & works! Enable it.";
|
||||
} else {
|
||||
$notice[] = "Memcache is disabled; Almost every linux distro has packages for it, you should be using it if you can.";
|
||||
}
|
||||
}
|
||||
// check if we can write templates/cache and templates/compile -> error
|
||||
if (!is_writable(THEME_DIR.'/cache')) {
|
||||
$error[] = "templates/cache folder is not writable for uid {$apache_user['name']}";
|
||||
}
|
||||
if (!is_writable(THEME_DIR.'/compile')) {
|
||||
$error[] = "templates/compile folder is not writable for uid {$apache_user['name']}";
|
||||
}
|
||||
// check if daemon can connect -> error
|
||||
try {
|
||||
if ($bitcoin->can_connect() !== true) {
|
||||
$error[] = "Unable to connect to coin daemon using provided credentials";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
// if coldwallet is not empty, check if the address is valid -> error
|
||||
if (!empty($config['coldwallet']['address'])) {
|
||||
try {
|
||||
if ($bitcoin->can_connect() == true) {
|
||||
$validate_cold_address = $bitcoin->validateaddress($config['coldwallet']['address']);
|
||||
if (!$validate_cold_address['isvalid']) {
|
||||
$error[] = "Your cold wallet address is <u>SET and INVALID</u>";
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
// if database connection fails -> error
|
||||
$db_connect = new mysqli($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
|
||||
if (mysqli_connect_errno() || !array_key_exists('client_info', $db_connect)) {
|
||||
$error[] = "Unable to connect to mysql using provided credentials";
|
||||
}
|
||||
if (($config['strict'] || $config['mc_antidos']) && !$config['memcache']['enabled']) {
|
||||
$error[] = "strict or mc_antidos are enabled and memcache is not, <u>memcache is required</u> to use these.";
|
||||
}
|
||||
// poke stratum using gettingstarted details -> enotice
|
||||
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if ($socket !== false) {
|
||||
$address = @gethostbyname($config['gettingstarted']['stratumurl']);
|
||||
$result = @socket_connect($socket, $address, $config['gettingstarted']['stratumport']);
|
||||
if ($result !== 1) {
|
||||
$enotice[] = "We tried to poke your Stratum server using config->gettingstarted details but it didn't respond";
|
||||
}
|
||||
$close = @socket_close($socket);
|
||||
}
|
||||
// security checks
|
||||
// strict not on -> notice
|
||||
if (!$config['strict']) {
|
||||
$notice[] = "strict is <u>disabled</u> - if you have memcache, you should turn this on.";
|
||||
}
|
||||
// salts too short -> notice, salts default -> error
|
||||
if ((strlen(SALT) < 24) || (strlen(SALTY) < 24) || SALT == 'PLEASEMAKEMESOMETHINGRANDOM' || SALTY == 'THISSHOULDALSOBERRAANNDDOOM') {
|
||||
if (SALT == 'PLEASEMAKEMESOMETHINGRANDOM' || SALTY == 'THISSHOULDALSOBERRAANNDDOOM') {
|
||||
$error[] = "You absolutely <u>SHOULD NOT leave your SALT or SALTY default</u>";
|
||||
} else {
|
||||
$notice[] = "SALT or SALTY is too short, they should be more than 24 characters and changing them will require registering again.";
|
||||
}
|
||||
}
|
||||
|
||||
// display the errors
|
||||
foreach ($enotice as $en) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $en, 'TYPE' => 'info');
|
||||
}
|
||||
if (!count($notice) && !count($error)) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'The config options we checked seem OK', 'TYPE' => 'success');
|
||||
} else {
|
||||
foreach ($notice as $n) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $n, 'TYPE' => 'warning');
|
||||
}
|
||||
foreach ($error as $e) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $e, 'TYPE' => 'errormsg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -71,4 +71,8 @@ require_once(INCLUDE_DIR . '/lib/scrypt.php');
|
||||
// Include our versions
|
||||
require_once(INCLUDE_DIR . '/version.inc.php');
|
||||
|
||||
if ($user->isAdmin(@$_SESSION['USERDATA']['id'])) {
|
||||
//include_once(INCLUDE_DIR . '/admin_checks.inc.php');
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -4,66 +4,119 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
class MemcacheAntiDos
|
||||
{
|
||||
public $cache;
|
||||
public static $key = 'mcad_';
|
||||
public static $request_model = array(
|
||||
'ident' => '',
|
||||
'last_hit' => 0,
|
||||
'last_flush' => 0,
|
||||
'hits_since_flush' => 0
|
||||
);
|
||||
public $rate_limit_this_request = false;
|
||||
public function __construct($config, &$memcache, $userORip, $request, $mcSettings) {
|
||||
public $rate_limit_api_request = false;
|
||||
public $rate_limit_site_request = false;
|
||||
public function __construct($config, &$memcache, $userORip, $request='', $mcSettings) {
|
||||
$this->cache = $memcache;
|
||||
// set our config options
|
||||
$per_page = $config['per_page'];
|
||||
$flush_sec = $config['flush_seconds'];
|
||||
$rate_limit = $config['rate_limit'];
|
||||
$per_page = '';
|
||||
$flush_sec_api = $config['flush_seconds_api'];
|
||||
$rate_limit_api = $config['rate_limit_api'];
|
||||
$flush_sec_site = $config['flush_seconds_site'];
|
||||
$rate_limit_site = $config['rate_limit_site'];
|
||||
$ajax_add = $config['ajax_hits_additive'];
|
||||
unset($config);
|
||||
// prep stuff we need to check this request
|
||||
$key_md5 = substr(md5($userORip), 0, 4);
|
||||
$request_md5 = substr(md5($request), 0, 4);
|
||||
$request_key = $mcSettings['keyprefix'].self::$key.$key_md5."_".$request_md5."_".$per_page;
|
||||
$request_data = $this->cache->get($request_key);
|
||||
$key_md5 = md5($mcSettings['keyprefix'].$userORip);
|
||||
$request_data = $this->cache->get($key_md5);
|
||||
$now = time();
|
||||
$max_req_flush = max(array($flush_sec_api,$flush_sec_site));
|
||||
// check the request
|
||||
if (is_array($request_data)) {
|
||||
// this request key already exists, update it
|
||||
$request_data['ident'] = $key_md5;
|
||||
$request_data['last_hit'] = $now;
|
||||
$request_data['hits_since_flush'] += 1;
|
||||
$request_data['la'] = $now;
|
||||
if ($request == 'api') {
|
||||
$request_data['ha'] += 1;
|
||||
if ($ajax_add) {
|
||||
$request_data['hn'] += 1;
|
||||
}
|
||||
} else {
|
||||
$request_data['hn'] += 1;
|
||||
}
|
||||
// not rate limited yet, update the rest of the object
|
||||
if ($request_data['hits_since_flush'] < $rate_limit) {
|
||||
if (($request_data['last_flush'] + $flush_sec) <= $now || ($request_data['last_hit'] + $flush_sec) <= $now) {
|
||||
// needs to be flushed
|
||||
$request_data['hits_since_flush'] = 0;
|
||||
$request_data['last_hit'] = 0;
|
||||
$request_data['last_flush'] = $now;
|
||||
// update the object
|
||||
$this->cache->set($request_key, $request_data, $flush_sec);
|
||||
$this->rate_limit_this_request = false;
|
||||
if (($request_data['hn'] < $rate_limit_site) && ($request_data['ha'] < $rate_limit_api)) {
|
||||
|
||||
if (((($request_data['hnl'] + $flush_sec_site) <= $now) || ($request_data['hal'] + $flush_sec_api) <= $now) || (($request_data['la'] + $max_req_flush) <= $now)) {
|
||||
// needs to be flushed & updated
|
||||
$new = $this->getRequestBase();
|
||||
$new['key'] = $key_md5;
|
||||
$new['sid'] = session_id();
|
||||
$new['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
|
||||
$new['ip'] = $key_md5;
|
||||
$new['la'] = $now;
|
||||
$new['hal'] = ((($request_data['hal'] + $flush_sec_api) <= $now)) ? $now : 1;
|
||||
$new['hnl'] = ((($request_data['hnl'] + $flush_sec_site) <= $now)) ? $now : 1;
|
||||
$this->cache->set($key_md5, $new, $max_req_flush);
|
||||
$this->rate_limit_api_request = ($request_data['ha'] >= $rate_limit_api) ? true : false;
|
||||
$this->rate_limit_site_request = ($request_data['hn'] >= $rate_limit_site) ? true : false;
|
||||
//$this->rate_limit_this_request = false;
|
||||
} else {
|
||||
// no flush, just update
|
||||
$this->cache->set($request_key, $request_data, $flush_sec);
|
||||
$this->rate_limit_this_request = false;
|
||||
$new = $this->getRequestBase();
|
||||
$new['key'] = $key_md5;
|
||||
$new['sid'] = session_id();
|
||||
$new['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
|
||||
$new['ip'] = $key_md5;
|
||||
$new['la'] = time();
|
||||
$new['ha'] = $request_data['ha'];
|
||||
$new['hal'] = $request_data['hal'];
|
||||
$new['hn'] = $request_data['hn'];
|
||||
$new['hnl'] = $request_data['hnl'];
|
||||
$this->cache->set($key_md5, $new, $max_req_flush);
|
||||
//$this->rate_limit_this_request = false;
|
||||
$this->rate_limit_api_request = ($request_data['ha'] >= $rate_limit_api) ? true : false;
|
||||
$this->rate_limit_site_request = ($request_data['hn'] >= $rate_limit_site) ? true : false;
|
||||
}
|
||||
} else {
|
||||
// too many hits, we should rate limit this
|
||||
$this->rate_limit_this_request = true;
|
||||
//$this->rate_limit_this_request = true;
|
||||
$this->rate_limit_api_request = ($request_data['ha'] >= $rate_limit_api) ? true : false;
|
||||
$this->rate_limit_site_request = ($request_data['hn'] >= $rate_limit_site) ? true : false;
|
||||
}
|
||||
} else {
|
||||
// doesn't exist for this request_key, create one
|
||||
$new_data = self::$request_model;
|
||||
$new_data['ident'] = $key_md5;
|
||||
$new_data['last_hit'] = time();
|
||||
$new_data['hits_since_flush'] = 1;
|
||||
$new_data['last_flush'] = $now;
|
||||
$this->cache->set($request_key, $new_data, $flush_sec);
|
||||
$new = $this->getRequestBase();
|
||||
$new['key'] = $key_md5;
|
||||
$new['sid'] = session_id();
|
||||
$new['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
|
||||
$new['ip'] = $key_md5;
|
||||
$new['la'] = time();
|
||||
if ($request == 'api') {
|
||||
$new['ha'] += 1;
|
||||
if ($ajax_add) {
|
||||
$new['hn'] += 1;
|
||||
}
|
||||
} else {
|
||||
$new['hn'] += 1;
|
||||
}
|
||||
$this->cache->set($key_md5, $new, $max_req_flush);
|
||||
$this->rate_limit_this_request = false;
|
||||
}
|
||||
}
|
||||
public function getRequestBase() {
|
||||
$new = array(
|
||||
'key' => '',
|
||||
'sid' => '',
|
||||
'ua' => '',
|
||||
'ip' => '',
|
||||
'la' => 0,
|
||||
'hn' => 0,
|
||||
'hnl' => 0,
|
||||
'ha' => 0,
|
||||
'hal' => 0
|
||||
);
|
||||
return $new;
|
||||
}
|
||||
public function rateLimitRequest() {
|
||||
return $this->rate_limit_this_request;
|
||||
}
|
||||
public function rateLimitSite() {
|
||||
return $this->rate_limit_site_request;
|
||||
}
|
||||
public function rateLimitAPI() {
|
||||
return $this->rate_limit_api_request;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -1,108 +1,140 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
class SessionManager {
|
||||
private $bind_address = '';
|
||||
private $started = false;
|
||||
private $host_verified = false;
|
||||
|
||||
private $config_dura = 0;
|
||||
private $config_path = '';
|
||||
private $config_domain = '';
|
||||
private $config_secure = false;
|
||||
private $config_httponly = false;
|
||||
|
||||
private $server_http_host = null;
|
||||
|
||||
private $current_session_id = '';
|
||||
private $current_session_ip = '';
|
||||
|
||||
public $memcache_handle = null;
|
||||
|
||||
public function set_cookie_params($duration, $path, $domain, $secure, $httponly) {
|
||||
session_set_cookie_params((time()+$duration), $path, $domain, $secure, $httponly);
|
||||
class strict_session {
|
||||
private $memcache = null;
|
||||
private $validate_client = false;
|
||||
private $validate_client_ip = false;
|
||||
private $validate_client_ua = false;
|
||||
private $validate_client_sid = false;
|
||||
private $validate_client_num = 0;
|
||||
private $valid_server = '';
|
||||
private $memcache_key = '';
|
||||
public function valid_session_id($id) {
|
||||
return preg_match('#^[a-zA-Z0-9]{26}$#', $id);
|
||||
}
|
||||
|
||||
public function verify_server() {
|
||||
if ($this->bind_address !== $this->server_http_host) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
public function session_delete_key($key) {
|
||||
$read = $this->memcache->delete($key);
|
||||
}
|
||||
|
||||
public function verify_client($ip) {
|
||||
if ($this->started && $this->memcache_handle !== null && $this->verify_server()) {
|
||||
$read_client = $this->memcache_handle->get(md5((string)$ip));
|
||||
if (is_array($read_client) && $read_client[0] == session_id()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
private $validation_misses = 0;
|
||||
private $initial_ua;
|
||||
public function create_or_update_client($client, $force=false, $login=false) {
|
||||
$read = $this->memcache->get($client['key']);
|
||||
// this needs to be available later
|
||||
$update = array('key' => '','sid' => '','ua' => '','ip' => '','la' => 0,'hn' => 0,'hnl' => 0,'ha' => 0,'hal' => 0);
|
||||
$update['sid'] = $client['sid'];
|
||||
$update['ua'] = md5($this->initial_ua);
|
||||
$update['ip'] = $client['ip'];
|
||||
$update['la'] = time();
|
||||
$update['key'] = md5($this->memcache_key.$client['ip']);
|
||||
$validation_misses = 0;
|
||||
if ($read !== false) {
|
||||
$read_model = array('key' => '','sid' => '','ua' => '','ip' => '','la' => 0,'hn' => 0,'hnl' => 0,'ha' => 0,'hal' => 0);
|
||||
$read_model['sid'] = @$read['sid'];
|
||||
$read_model['ip'] = @$read['ip'];
|
||||
$read_model['ua'] = @$read['ua'];
|
||||
$read_model['la'] = @$read['la'];
|
||||
$read_model['key'] = md5($this->memcache_key.$read['ip']);
|
||||
// key already exists, update
|
||||
if ($this->validate_client) {
|
||||
if ($this->verify_client($read_model, $update, $login)) {
|
||||
$update_client = $this->memcache->set($update['key'], $update);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function update_client($ip) {
|
||||
if ($this->started && $this->memcache_handle !== null && $this->verify_client($ip)) {
|
||||
$this->memcache_handle->set(md5((string)$ip), array($this->current_session_id, time()));
|
||||
}
|
||||
}
|
||||
|
||||
public function set_cookie($ip) {
|
||||
if ($this->started && $this->memcache_handle !== null && $this->verify_server() && $this->verify_client($ip)) {
|
||||
@setcookie(session_name(), session_id(), $this->config_dura, $this->config_path, $this->config_domain, $this->config_secure, $this->config_httponly);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy_session($ip) {
|
||||
if ($this->started && $this->verify_server() && $this->verify_client($ip)) {
|
||||
$this->memcache_handle->delete(md5((string)$ip));
|
||||
if (ini_get('session.use_cookies')) {
|
||||
setcookie(session_name(), '', time() - 42000, $config_path, $config_domain, $config_secure, $config_httponly);
|
||||
}
|
||||
session_destroy();
|
||||
session_regenerate_id(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function create_session($ip) {
|
||||
if (!$this->verify_server()) {
|
||||
return false;
|
||||
} else {
|
||||
$session_start = @session_start();
|
||||
if (!$session_start) {
|
||||
session_destroy();
|
||||
session_regenerate_id(true);
|
||||
session_start();
|
||||
$this->update_client($ip);
|
||||
$this->started = true;
|
||||
$this->current_session_id = session_id();
|
||||
$this->set_cookie($ip);
|
||||
return true;
|
||||
} else {
|
||||
$this->update_client($ip);
|
||||
$this->started = true;
|
||||
$this->current_session_id = session_id();
|
||||
$this->set_cookie($ip);
|
||||
return true;
|
||||
$update_client = $this->memcache->set($client['key'], $client);
|
||||
if ($force && $login) {
|
||||
$update_client = $this->memcache->set($update['key'], $update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct($config, &$memcache, $server_host) {
|
||||
$this->config_dura = $config['cookie']['duration'];
|
||||
$this->config_path = $config['cookie']['path'];
|
||||
$this->config_domain = $config['cookie']['domain'];
|
||||
$this->config_secure = $config['cookie']['secure'];
|
||||
$this->config_httponly = $config['cookie']['httponly'];
|
||||
if ($config['strict__enforce_ssl']) $config['strict__bind_protocol'] = 'https';
|
||||
$this->bind_address = $config['strict__bind_protocol']."://".$config['strict__bind_host'].":".$config['strict__bind_port'];
|
||||
$this->server_http_host = $config['strict__bind_protocol']."://".$_SERVER['HTTP_HOST'].":".$config['strict__bind_port'];
|
||||
$this->memcache_handle = $memcache;
|
||||
unset($config);
|
||||
$this->set_cookie_params((time()+$this->config_dura), $this->config_path, $this->config_domain, $this->config_secure, $this->config_httponly);
|
||||
public function verify_client($client_model, $data, $login=false) {
|
||||
$fails = 0;
|
||||
$fails += ((count($client_model)) !== (count($data))) ? 1 : 0;
|
||||
$fails += ($client_model['ua'] !== $data['ua']) ? 1 : 0;
|
||||
$fails += ($client_model['ip'] !== $data['ip']) ? 1 : 0;
|
||||
$now = time();
|
||||
$this->validation_misses = $fails;
|
||||
if ($fails > $this->validate_client_num && $login == false) {
|
||||
// something changed
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$location = (@$_SERVER['HTTPS'] == "on") ? 'https://' : 'http://';
|
||||
$location .= $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME'];
|
||||
$this->session_delete_key($client_model['key']);
|
||||
$this->session_delete_key($data['key']);
|
||||
@session_start();
|
||||
@session_regenerate_id(true);
|
||||
$_SESSION = null;
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => "Session revoked due to a change in your client. You may have a plugin messing with your useragent, or your IP address may have changed.", 'TYPE' => 'warning');
|
||||
$location.= '?page=login';
|
||||
if (!headers_sent()) exit(header('Location: ' . $location));
|
||||
exit('<meta http-equiv="refresh" content="0; url=' . htmlspecialchars($location) . '"/>');
|
||||
}
|
||||
return ($fails > 0) ? false : true;
|
||||
}
|
||||
public function read_if_client_exists($client_key) {
|
||||
if ($this->memcache !== null) {
|
||||
$exists = $this->memcache->get($client_key);
|
||||
}
|
||||
return ($exists !== null) ? $exists : false;
|
||||
}
|
||||
public function regen_session_id() {
|
||||
$sidbefore = @session_id();
|
||||
@session_regenerate_id(true);
|
||||
$sid = session_id();
|
||||
return $sid;
|
||||
}
|
||||
public function __construct($config, &$memcache) {
|
||||
$this->initial_ua = $_SERVER['HTTP_USER_AGENT'];
|
||||
$this->memcache = $memcache;
|
||||
$this->memcache_key = $config['memcache']['keyprefix'];
|
||||
if ($config['strict__verify_client']) {
|
||||
$this->validate_client = true;
|
||||
$this->validate_client_ip = $config['strict__verify_client_ip'];
|
||||
$this->validate_client_ua = $config['strict__verify_client_useragent'];
|
||||
$this->validate_client_sid = $config['strict__verify_client_sessionid'];
|
||||
$this->validate_client_num = 0;
|
||||
if ($config['strict__verify_server']) {
|
||||
$proto = (@$_SERVER['HTTPS'] == "on") ? 'https' : 'http';
|
||||
$location = $proto."://".$_SERVER['SERVER_NAME'] . $_SERVER['SERVER_PORT'];
|
||||
if ($config['strict__verify_server']) {
|
||||
if ($config['strict__bind_protocol']."://".$config['strict__bind_host'].$config['strict__bind_port'] !== $location) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$client = array('key' => '','sid' => '','ua' => '','ip' => '','la' => 0,'hn' => 0,'hnl' => 0,'ha' => 0,'hal' => 0);
|
||||
$client['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
|
||||
$client['ip'] = md5($_SERVER['REMOTE_ADDR']);
|
||||
$client['la'] = time();
|
||||
$client['key'] = md5($this->memcache_key.$client['ip']);
|
||||
$read = $this->read_if_client_exists($client['key']);
|
||||
}
|
||||
session_set_cookie_params((time()+$config['cookie']['duration']), $config['cookie']['path'], $config['cookie']['domain'], false, true);
|
||||
$session_start = @session_start();
|
||||
$client['sid'] = session_id();
|
||||
$valid_session_id = $this->valid_session_id($client['sid']);
|
||||
if (!$valid_session_id || !$session_start) {
|
||||
@session_destroy();
|
||||
$client['sid'] = $this->regen_session_id();
|
||||
session_start();
|
||||
}
|
||||
if ($read !== null) {
|
||||
// client exists, verify
|
||||
$this->create_or_update_client($client, true, false);
|
||||
|
||||
} else {
|
||||
// doesn't exist
|
||||
$this->create_or_update_client($client, true, true);
|
||||
}
|
||||
@setcookie(session_name(), $client['sid'], (time()+$config['cookie']['duration']), $config['cookie']['path'], $config['cookie']['domain'], false, true);
|
||||
// post changes validate
|
||||
if ($this->validate_client) {
|
||||
$read_post = $this->read_if_client_exists($client['key']);
|
||||
if ($read_post !== null) {
|
||||
$this->verify_client($client, $read_post, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,26 +147,28 @@ class mysqli_strict extends mysqli {
|
||||
$acopy = $args;
|
||||
$nargs = count($args);
|
||||
for($i=1;$i<$nargs;$i++) {
|
||||
$pos = substr($paramTypes, ($i-1), 1);
|
||||
$ipos = ($i-1);
|
||||
$pos = substr($paramTypes, $ipos, 1);
|
||||
switch ($pos) {
|
||||
case 's':
|
||||
$return_str = filter_var($acopy[$i], FILTER_VALIDATE_STRING, FILTER_NULL_ON_FAILURE);
|
||||
return ($return_str !== null) ? (string)$return_str : false;
|
||||
$acopy[$i] = ($return_str !== null) ? (string)$return_str : null;
|
||||
break;
|
||||
case 'i':
|
||||
$return_int = filter_var($acopy[$i], FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
|
||||
return ($return_int !== null) ? (int)$return_int : false;
|
||||
$acopy[$i] = ($return_int !== null) ? (int)$return_int : null;
|
||||
break;
|
||||
case 'd':
|
||||
$return_dbl = filter_var($acopy[$i], FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
|
||||
return ($return_dbl !== null) ? (float)$return_dbl : false;
|
||||
$acopy[$i] = ($return_dbl !== null) ? (float)$return_dbl : null;
|
||||
break;
|
||||
case 'b':
|
||||
$return_bool = filter_var($acopy[$i], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
return ($return_bool !== null) ? (bool)$return_bool : false;
|
||||
$acopy[$i] = ($return_bool !== null) ? (bool)$return_bool : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (in_array(null, $acopy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,13 +494,10 @@ class User extends Base {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$this->debug->append("Log in user to _SESSION", 2);
|
||||
if ($this->config['strict']) {
|
||||
if ($this->session->verify_server()) {
|
||||
if ($this->session->create_session($_SERVER['REMOTE_ADDR'])) {
|
||||
$this->session->update_client($_SERVER['REMOTE_ADDR']);
|
||||
$_SESSION['AUTHENTICATED'] = '1';
|
||||
$_SESSION['USERDATA'] = $this->user;
|
||||
}
|
||||
}
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['AUTHENTICATED'] = '1';
|
||||
// $this->user from checkUserPassword
|
||||
$_SESSION['USERDATA'] = $this->user;
|
||||
} else {
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['AUTHENTICATED'] = '1';
|
||||
@ -537,10 +534,11 @@ class User extends Base {
|
||||
session_destroy();
|
||||
// Enforce generation of a new Session ID and delete the old
|
||||
session_regenerate_id(true);
|
||||
|
||||
// Enforce a page reload and point towards login with referrer included, if supplied
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$pushto = $_SERVER['SCRIPT_NAME'].'?page=login';
|
||||
$location = @$_SERVER['HTTPS'] ? 'https://' . $_SERVER['SERVER_NAME'] . $port . $pushto : 'http://' . $_SERVER['SERVER_NAME'] . $port . $pushto;
|
||||
$location = (@$_SERVER['HTTPS'] == 'on') ? 'https://' . $_SERVER['SERVER_NAME'] . $port . $pushto : 'http://' . $_SERVER['SERVER_NAME'] . $port . $pushto;
|
||||
// if (!headers_sent()) header('Location: ' . $location);
|
||||
exit('<meta http-equiv="refresh" content="0; url=' . $location . '"/>');
|
||||
}
|
||||
@ -804,7 +802,7 @@ class User extends Base {
|
||||
* @param none
|
||||
* @return bool
|
||||
**/
|
||||
public function isAuthenticated($logout=true) {
|
||||
public function isAuthenticated($logout=true) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if (@$_SESSION['AUTHENTICATED'] == true &&
|
||||
!$this->isLocked($_SESSION['USERDATA']['id']) &&
|
||||
|
||||
@ -1,25 +1,6 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
/**
|
||||
* Forces extra security options when enabled
|
||||
*
|
||||
* You must have Memcache enabled and configured & Memcache anti-dos configured to use this.
|
||||
*
|
||||
* Check -> Memcache configuration
|
||||
* Check -> Memcache anti resource-dos
|
||||
*
|
||||
* Runs a FILTER_VALIDATE_*TYPE on every parameter of bind_param
|
||||
* Verifies server vs. bound protocol/host/port set below
|
||||
* Enables memcache rate limiting of requests
|
||||
* Verifies client when creating/resuming from a session
|
||||
*/
|
||||
$config['strict'] = true;
|
||||
$config['strict__enforce_ssl'] = false;
|
||||
$config['strict__bind_protocol'] = 'http';
|
||||
$config['strict__bind_host'] = 'localhost';
|
||||
$config['strict__bind_port'] = 80;
|
||||
|
||||
/**
|
||||
* Do not edit this unless you have confirmed that your config has been updated!
|
||||
* This is used in the version check to ensure you run the latest version of the configuration file.
|
||||
@ -27,6 +8,11 @@ $config['strict__bind_port'] = 80;
|
||||
**/
|
||||
$config['version'] = '0.0.7';
|
||||
|
||||
/**
|
||||
* Unless you disable this, we'll do a quick check on your config first.
|
||||
*/
|
||||
$config['skip_config_tests'] = false;
|
||||
|
||||
// Our include directory for additional features
|
||||
define('INCLUDE_DIR', BASEPATH . 'include');
|
||||
|
||||
@ -119,64 +105,6 @@ $config['coldwallet']['address'] = '';
|
||||
$config['coldwallet']['reserve'] = 50;
|
||||
$config['coldwallet']['threshold'] = 5;
|
||||
|
||||
/**
|
||||
* E-mail confirmations for user actions
|
||||
*
|
||||
* Explanation:
|
||||
* To increase security for users, account detail changes can require
|
||||
* an e-mail confirmation prior to performing certain actions.
|
||||
*
|
||||
* Options:
|
||||
* enabled : Whether or not to require e-mail confirmations
|
||||
* details : Require confirmation to change account details
|
||||
* withdraw : Require confirmation to manually withdraw/payout
|
||||
* changepw : Require confirmation to change password
|
||||
*
|
||||
* Default:
|
||||
* enabled = true
|
||||
* details = true
|
||||
* withdraw = true
|
||||
* changepw = true
|
||||
*/
|
||||
$config['twofactor']['enabled'] = true;
|
||||
$config['twofactor']['options']['details'] = true;
|
||||
$config['twofactor']['options']['withdraw'] = true;
|
||||
$config['twofactor']['options']['changepw'] = true;
|
||||
|
||||
/**
|
||||
* CSRF protection
|
||||
*
|
||||
* Explanation:
|
||||
* To help protect against CSRF, we can generate a hash that changes every minute
|
||||
* and is unique for each user/IP and page or use, and check against that when a
|
||||
* form is submitted.
|
||||
*
|
||||
* Options:
|
||||
* enabled = Whether or not we will generate & check for valid CSRF tokens
|
||||
* Default:
|
||||
* enabled = true
|
||||
*/
|
||||
$config['csrf']['enabled'] = true;
|
||||
|
||||
/**
|
||||
* Lock account after maximum failed logins
|
||||
*
|
||||
* Explanation:
|
||||
* To avoid accounts being hacked by brute force attacks,
|
||||
* set a maximum amount of failed login or pin entry attempts before locking
|
||||
* the account. They will need to contact site support to re-enable the account.
|
||||
*
|
||||
* This also applies for invalid PIN entries, which is covered by the pin option.
|
||||
*
|
||||
* Workers are not affected by this lockout, mining will continue as usual.
|
||||
*
|
||||
* Default:
|
||||
* login = 3
|
||||
* pin = 3
|
||||
**/
|
||||
$config['maxfailed']['login'] = 3;
|
||||
$config['maxfailed']['pin'] = 3;
|
||||
|
||||
/**
|
||||
* Getting Started Config
|
||||
*
|
||||
|
||||
136
public/include/config/security.inc.dist.php
Normal file
136
public/include/config/security.inc.dist.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Strict is a set of extra security options can use that when enabled can help protect against
|
||||
* a few different types of attacks.
|
||||
*
|
||||
* You must have Memcache enabled and configured & Memcache anti-dos configured to use this!
|
||||
*
|
||||
* Check -> Memcache configuration
|
||||
* Check -> Memcache anti resource-dos
|
||||
*
|
||||
* Options Default Explanation
|
||||
* ------- + ------- + -----------
|
||||
* strict : true : Whether or not to use strict mode
|
||||
* __https_only : false : Requires/pushes to https
|
||||
* __mysql_filter : true : Uses a mysqli shim to use php filters on all incoming data
|
||||
* __verify_client : true : Verifies the client using specified settings
|
||||
* __verify_client_ip : true : If the client request suddenly switches IP, trigger a failure
|
||||
* __verify_client_useragent : true : If the client request suddenly switches Useragent, trigger a failure
|
||||
* __verify_client_sessionid : true : If the client request suddenly switches SessionID, trigger a failure
|
||||
* __verify_client_fails : 0 : Maximum number of client-side inconsistencies to accept before revoking sessions
|
||||
* __verify_server : false : Verifies the server is valid for this request
|
||||
* __bind_protocol : https : Server validate protocol; http or https
|
||||
* __bind_host : '' : Server validate host; ie. your domain or subdomain
|
||||
* __bind_port : 443 : Server validate port; 80 / 443 / something else
|
||||
**/
|
||||
$config['strict'] = true;
|
||||
$config['strict__https_only'] = false;
|
||||
$config['strict__mysql_filter'] = true;
|
||||
$config['strict__verify_client'] = true;
|
||||
$config['strict__verify_client_ip'] = true;
|
||||
$config['strict__verify_client_useragent'] = true;
|
||||
$config['strict__verify_client_sessionid'] = true;
|
||||
$config['strict__verify_client_fails'] = 0;
|
||||
$config['strict__verify_server'] = false;
|
||||
$config['strict__bind_protocol'] = 'https';
|
||||
$config['strict__bind_host'] = '';
|
||||
$config['strict__bind_port'] = 443;
|
||||
|
||||
/**
|
||||
* Memcache anti resource-dos protection / request rate limiting
|
||||
*
|
||||
* Explanation:
|
||||
* Because bots/angry users can just fire away at pages or f5 us to death, we can attempt to rate limit requests
|
||||
* using memcache - now shares data with session manager.
|
||||
*
|
||||
* Options:
|
||||
* enabled = Whether or not we will try to rate limit requests
|
||||
* protect_ajax = If enabled, we will also watch the ajax calls for rate limiting and kill bad requests
|
||||
* ajax_hits_additive = If enabled, ajax hits will count towards the site counter as well as the ajax counter
|
||||
* flush_seconds_api = Number of seconds between each flush of user/ajax counter
|
||||
* rate_limit_api = Number of api requests allowed per flush_seconds_api
|
||||
* flush_seconds_site = Number of seconds between each flush of user/site counter
|
||||
* rate_limit_site = Number of site requests allowed per flush_seconds_site
|
||||
* ignore_admins = Ignores the rate limit for admins
|
||||
* error_push_page = Page/action array to push users to a specific page, look in the URL!
|
||||
* Empty = 'You are sending too many requests too fast!' on a blank page
|
||||
* Default:
|
||||
* enabled = true
|
||||
* protect_ajax = true
|
||||
* ajax_hits_additive = false
|
||||
* flush_seconds_api = 60
|
||||
* rate_limit_api = 20
|
||||
* flush_seconds_site = 60
|
||||
* rate_limit_site = 30
|
||||
* ignore_admins = true
|
||||
* error_push_page = array('page' => 'error', 'action' => 'ratelimit');
|
||||
*/
|
||||
$config['mc_antidos']['enabled'] = true;
|
||||
$config['mc_antidos']['protect_ajax'] = true;
|
||||
$config['mc_antidos']['ajax_hits_additive'] = false;
|
||||
$config['mc_antidos']['flush_seconds_api'] = 60;
|
||||
$config['mc_antidos']['rate_limit_api'] = 20;
|
||||
$config['mc_antidos']['flush_seconds_site'] = 60;
|
||||
$config['mc_antidos']['rate_limit_site'] = 30;
|
||||
$config['mc_antidos']['ignore_admins'] = true;
|
||||
$config['mc_antidos']['error_push_page'] = array('page' => 'error', 'action' => 'ratelimit');
|
||||
|
||||
/**
|
||||
* CSRF protection config
|
||||
*
|
||||
* Explanation:
|
||||
* To help protect against CSRF, we can generate a hash that changes every minute
|
||||
* and is unique for each user/IP and page or use, and check against that when a
|
||||
* form is submitted.
|
||||
*
|
||||
* Options:
|
||||
* enabled = Whether or not we will generate/check for valid CSRF tokens
|
||||
* Default:
|
||||
* enabled = true
|
||||
*/
|
||||
$config['csrf']['enabled'] = true;
|
||||
|
||||
/**
|
||||
* E-mail confirmations for user actions
|
||||
*
|
||||
* Explanation:
|
||||
* To increase security for users, account detail changes can require
|
||||
* an e-mail confirmation prior to performing certain actions.
|
||||
*
|
||||
* Options:
|
||||
* enabled : Whether or not to require e-mail confirmations
|
||||
* details : Require confirmation to change account details
|
||||
* withdraw : Require confirmation to manually withdraw/payout
|
||||
* changepw : Require confirmation to change password
|
||||
*
|
||||
* Default:
|
||||
* enabled = true
|
||||
* details = true
|
||||
* withdraw = true
|
||||
* changepw = true
|
||||
*/
|
||||
$config['twofactor']['enabled'] = true;
|
||||
$config['twofactor']['options']['details'] = true;
|
||||
$config['twofactor']['options']['withdraw'] = true;
|
||||
$config['twofactor']['options']['changepw'] = true;
|
||||
|
||||
/**
|
||||
* Lock account after maximum failed logins
|
||||
*
|
||||
* Explanation:
|
||||
* To avoid accounts being hacked by brute force attacks,
|
||||
* set a maximum amount of failed login or pin entry attempts before locking
|
||||
* the account. They will need to contact site support to re-enable the account.
|
||||
*
|
||||
* This also applies for invalid PIN entries, which is covered by the pin option.
|
||||
*
|
||||
* Workers are not affected by this lockout, mining will continue as usual.
|
||||
*
|
||||
* Default:
|
||||
* login = 3
|
||||
* pin = 3
|
||||
**/
|
||||
$config['maxfailed']['login'] = 3;
|
||||
$config['maxfailed']['pin'] = 3;
|
||||
|
||||
?>
|
||||
@ -2,7 +2,7 @@
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
// Instantiate class, we are using mysqlng
|
||||
if ($config['strict']) {
|
||||
if ($config['strict'] && $config['strict__mysql_filter']) {
|
||||
$mysqli = new mysqli_strict($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
|
||||
} else {
|
||||
$mysqli = new mysqli($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
|
||||
|
||||
@ -24,10 +24,22 @@ if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail
|
||||
// Check if recaptcha is enabled, process form data if valid
|
||||
if (!$setting->getValue('recaptcha_enabled') || !$setting->getValue('recaptcha_enabled_logins') || ($setting->getValue('recaptcha_enabled') && $setting->getValue('recaptcha_enabled_logins') && $rsp->is_valid)) {
|
||||
if (!$config['csrf']['enabled'] || $config['csrf']['enabled'] && $csrftoken->valid) {
|
||||
// check if login is correct
|
||||
if ($user->checkLogin(@$_POST['username'], @$_POST['password']) ) {
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" or $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$location = @$_SERVER['HTTPS'] ? 'https://' : 'http://';
|
||||
$location .= $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME'] . '?page=dashboard';
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$location = (@$_SERVER['HTTPS'] == "on") ? 'https://' : 'http://';
|
||||
$location .= $_SERVER['SERVER_NAME'] . $port . $_SERVER['SCRIPT_NAME'];
|
||||
if ($config['strict']) {
|
||||
$update = array('key' => '','sid' => '','ua' => '','ip' => '','la' => 0,'hn' => 0,'hnl' => 0,'ha' => 0,'hal' => 0);
|
||||
$session->regen_session_id();
|
||||
$update['sid'] = session_id();
|
||||
$update['ua'] = md5($_SERVER['HTTP_USER_AGENT']);
|
||||
$update['ip'] = md5($_SERVER['REMOTE_ADDR']);
|
||||
$update['la'] = time();
|
||||
$update['key'] = md5($update['ip']);
|
||||
$session->create_or_update_client($update, true, true);
|
||||
$location.= '?page=dashboard';
|
||||
}
|
||||
if (!headers_sent()) header('Location: ' . $location);
|
||||
exit('<meta http-equiv="refresh" content="0; url=' . htmlspecialchars($location) . '"/>');
|
||||
} else {
|
||||
@ -40,7 +52,7 @@ if ($setting->getValue('maintenance') && !$user->isAdmin($user->getUserIdByEmail
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'Invalid Captcha, please try again.', 'TYPE' => 'errormsg');
|
||||
}
|
||||
}
|
||||
|
||||
// Load login template
|
||||
$smarty->assign('CONTENT', 'default.tpl');
|
||||
|
||||
?>
|
||||
|
||||
@ -1,7 +1,18 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
$user->logoutUser();
|
||||
if ($config['strict']) {
|
||||
$user->logoutUser();
|
||||
$update = $session::$client_model;
|
||||
$update['sid'] = session_id();
|
||||
$update['ua'] = $_SERVER['HTTP_USER_AGENT'];
|
||||
$update['ip'] = $_SERVER['REMOTE_ADDR'];
|
||||
$update['la'] = time();
|
||||
$update['key'] = md5($update['ua'].$update['ip']);
|
||||
$session->create_or_update_client($update, true);
|
||||
} else {
|
||||
$user->logoutUser();
|
||||
}
|
||||
|
||||
$smarty->assign("CONTENT", "default.tpl");
|
||||
?>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
define('MPOS_VERSION', '0.0.2');
|
||||
define('MPOS_VERSION', '0.0.3');
|
||||
define('DB_VERSION', '0.0.4');
|
||||
define('CONFIG_VERSION', '0.0.7');
|
||||
|
||||
|
||||
@ -16,11 +16,10 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
// Set a decently long SECURITY key with special chars etc
|
||||
define('SECURITY', '*)WT#&YHfd');
|
||||
// Whether or not to check SECHASH for validity, still checks if SECURITY defined as before if disabled
|
||||
define('SECHASH_CHECK', true);
|
||||
define('SECHASH_CHECK', false);
|
||||
|
||||
// Nothing below here to configure, move along...
|
||||
|
||||
@ -30,7 +29,7 @@ if (SECHASH_CHECK) {
|
||||
define('SECHASH', fip());
|
||||
function cfip() { return (fip()==SECHASH||fip(1)==SECHASH||fip(2)==SECHASH) ? 1 : 0; }
|
||||
} else {
|
||||
function cfip() { return (defined('SECURITY')) ? 1 : 0; }
|
||||
function cfip() { return (@defined('SECURITY')) ? 1 : 0; }
|
||||
}
|
||||
|
||||
// Used for performance calculations
|
||||
@ -42,6 +41,11 @@ define("BASEPATH", dirname(__FILE__) . "/");
|
||||
|
||||
// Include our configuration (holding defines for the requires)
|
||||
if (!include_once(BASEPATH . 'include/config/global.inc.php')) die('Unable to load site configuration');
|
||||
if (!include_once(BASEPATH . 'include/config/security.inc.php')) die('Unable to load security configuration');
|
||||
|
||||
// switch to https if config option is enabled
|
||||
$hts = ($config['strict__https_only'] && (!empty($_SERVER['QUERY_STRING']))) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME']."?".$_SERVER['QUERY_STRING'] : "https://".$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'];
|
||||
($config['strict__https_only'] && @!$_SERVER['HTTPS']) ? exit(header($hts)):0;
|
||||
|
||||
// Our default template to load, pages can overwrite this later
|
||||
$master_template = 'master.tpl';
|
||||
@ -52,26 +56,26 @@ require_once(INCLUDE_DIR . '/autoloader.inc.php');
|
||||
|
||||
if ($config['memcache']['enabled'] && ($config['mc_antidos']['enabled'] || $config['strict'])) {
|
||||
if (PHP_OS == 'WINNT') {
|
||||
require_once('memcached.class.php');
|
||||
require_once(CLASS_DIR . 'memcached.class.php');
|
||||
}
|
||||
// strict mode and memcache antidos need a memcache handle
|
||||
$memcache = new Memcached();
|
||||
$memcache->addServer($config['memcache']['host'], $config['memcache']['port']);
|
||||
}
|
||||
|
||||
if ($config['strict']) {
|
||||
if ($config['memcache']['enabled'] && $config['strict'] || $config['mc_antidos']['enabled']) {
|
||||
require_once(CLASS_DIR . '/memcache_ad.class.php');
|
||||
$session = new SessionManager($config, $memcache, $_SERVER['HTTP_HOST']);
|
||||
$user->setSessionManager($session);
|
||||
if ($session->verify_server()) {
|
||||
$session->create_session($_SERVER['REMOTE_ADDR']);
|
||||
if ($session->verify_client($_SERVER['REMOTE_ADDR'])) {
|
||||
$session->update_client($_SERVER['REMOTE_ADDR']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($config['memcache']['enabled'] && $config['strict']) {
|
||||
$session = new strict_session($config, $memcache);
|
||||
if ($config['strict__verify_server'] && !$session) {
|
||||
// server not verified, session manager will kill the client verification failures
|
||||
exit(header('HTTP/1.1 401 Unauthorized'));
|
||||
}
|
||||
} else {
|
||||
session_set_cookie_params(time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
|
||||
$session_start = @session_start();
|
||||
session_set_cookie_params(time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
|
||||
if (!$session_start) {
|
||||
session_destroy();
|
||||
session_regenerate_id(true);
|
||||
@ -79,11 +83,12 @@ if ($config['strict']) {
|
||||
}
|
||||
@setcookie(session_name(), session_id(), time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
|
||||
}
|
||||
|
||||
// Rate limiting
|
||||
if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled'] || $config['strict']) {
|
||||
if ($config['memcache']['enabled'] && ($config['mc_antidos']['enabled'] || $config['strict'])) {
|
||||
$skip_check = false;
|
||||
$per_page = ($config['mc_antidos']['per_page']) ? $_SERVER['QUERY_STRING'] : '';
|
||||
// if this is an api call we need to be careful not to time them out for those calls separately
|
||||
$per_page = '';
|
||||
$ajax_calls = array(
|
||||
array('api', 'getuserbalance'),
|
||||
array('api', 'getnavbardata'),
|
||||
@ -96,9 +101,7 @@ if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled'] || $confi
|
||||
}
|
||||
$is_ajax_call = ($iac > 0) ? true : false;
|
||||
if ($is_ajax_call && $config['mc_antidos']['protect_ajax']) {
|
||||
// we set this to navbar on purpose - if they screw with the REQUEST by adding more
|
||||
// params it still gets added under navbar so multiple requests will still get capped
|
||||
$per_page = 'navbar';
|
||||
$per_page = 'api';
|
||||
} else if ($is_ajax_call && !$config['mc_antidos']['protect_ajax']) {
|
||||
// protect isn't on, we'll ignore it
|
||||
$skip_check = true;
|
||||
@ -107,9 +110,13 @@ if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled'] || $confi
|
||||
}
|
||||
if (!$skip_check) {
|
||||
$mcad = new MemcacheAntiDos($config['mc_antidos'], $memcache, $_SERVER['REMOTE_ADDR'], $per_page, $config['memcache']);
|
||||
$rate_limit_reached = $mcad->rateLimitRequest();
|
||||
$rate_limit_reached_site = $mcad->rateLimitSite();
|
||||
$rate_limit_reached_api = $mcad->rateLimitAPI();
|
||||
if ($rate_limit_reached_api && $is_ajax_call && $config['mc_antidos']['protect_ajax']) {
|
||||
exit(header('HTTP/1.1 401 Unauthorized'));
|
||||
}
|
||||
$error_page = $config['mc_antidos']['error_push_page'];
|
||||
if ($rate_limit_reached == true) {
|
||||
if ($rate_limit_reached_site == true) {
|
||||
if (!is_array($error_page) || count($error_page) < 1 || (empty($error_page['page']) && empty($error_page['action']))) {
|
||||
die("You are sending too many requests too fast!");
|
||||
} else {
|
||||
@ -120,6 +127,11 @@ if ($config['memcache']['enabled'] && $config['mc_antidos']['enabled'] || $confi
|
||||
}
|
||||
}
|
||||
|
||||
// Quick config check
|
||||
if (@$_SESSION['USERDATA']['is_admin'] && (!$config['skip_config_tests'])) {
|
||||
require_once(INCLUDE_DIR. '/admin_checks.php');
|
||||
}
|
||||
|
||||
// Create our pages array from existing files
|
||||
if (is_dir(INCLUDE_DIR . '/pages/')) {
|
||||
foreach (glob(INCLUDE_DIR . '/pages/*.inc.php') as $filepath) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<article class="module width_half">
|
||||
<form action="{$smarty.server.SCRIPT_NAME}?page=login" method="post" id="loginForm">
|
||||
<input type="hidden" name="to" value="{($smarty.request.to|default:"{$smarty.server.SCRIPT_NAME}?page=dashboard")|escape}" />
|
||||
<input type="hidden" name="ctoken" value="{$CTOKEN|escape|default:""}" />
|
||||
<header><h3>Login with existing account</h3></header>
|
||||
<div class="module_content">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user