diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index f2f06bfd4..2cc4f4fac 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -215,10 +215,9 @@ class Context $this->loadDBInfo(); if($this->db_info->use_sitelock == 'Y') { - $whitelist = array('127.0.0.1', '::1', 'fe80::1'); - if(is_array($this->db_info->sitelock_whitelist)) $whitelist = array_merge($whitelist, $this->db_info->sitelock_whitelist); - - if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)) + if(is_array($this->db_info->sitelock_whitelist)) $whitelist = $this->db_info->sitelock_whitelist; + + if(!IpFilter::filter($whitelist)) { $title = ($this->db_info->sitelock_title) ? $this->db_info->sitelock_title : 'Maintenance in progress...'; $message = $this->db_info->sitelock_message; @@ -479,7 +478,7 @@ class Context $self->set('_https_port', $db_info->https_port); if(!$db_info->sitelock_whitelist) { - $db_info->sitelock_whitelist = '127.0.0.1,::1,fe80::1'; + $db_info->sitelock_whitelist = '127.0.0.1'; } if(is_string($db_info->sitelock_whitelist)) { diff --git a/classes/security/IpFilter.class.php b/classes/security/IpFilter.class.php new file mode 100644 index 000000000..d03a5d30b --- /dev/null +++ b/classes/security/IpFilter.class.php @@ -0,0 +1,92 @@ + */ + +class IpFilter +{ + public function filter($ip_list, $ip = NULL) + { + if(!$ip) $ip = $_SERVER['REMOTE_ADDR']; + $long_ip = ip2long($ip); + foreach($ip_list as $filter_ip) + { + $range = explode('-', $filter_ip); + if(!$range[1]) // single address type + { + $star_pos = strpos($filter_ip, '*'); + if($star_pos !== FALSE ) // wild card exist + { + if(strncmp($filter_ip, $ip, $star_pos)===0) return true; + } + else if(strcmp($filter_ip, $ip)===0) + { + return true; + } + } + else if(ip2long($range[0]) <= $long_ip && ip2long($range[1]) >= $long_ip) + { + return true; + } + } + return false; + } + + /* public function filter2($ip_list, $ip) + { + $long_ip = ip2long($ip); + foreach($ip_list as $filter_ip) + { + $range = explode('-', $filter_ip); + if(!$range[1]) // single address type + { + $range[1] = str_replace('*', '255', $range[0]); + $range[0] = str_replace('*', '0', $range[0]); + } + + if(ip2long($range[0]) <= $long_ip && ip2long($range[1]) >= $long_ip) + { + return true; + } + } + + return false; + } */ + + + public function validate($ip_list = array()) + { + /* 사용가능한 표현 + 192.168.2.10 - 4자리의 정확한 ip주소 + 192.168.*.* - 와일드카드(*)가 사용된 4자리의 ip주소, a클래스에는 와일드카드 사용불가, + 와일드카드 이후의 아이피주소 허용(단, filter()를 쓸 경우 와일드카드 이후 주소는 무시됨 + 192.168.1.1-192.168.1.10 - '-'로 구분된 정확한 4자리의 ip주소 2개 + */ + $regex = "/^ + (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) + (?: + (?: + (?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3} + (?:-(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){1} + (?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3} + ) + | + (?: + (?:\.(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|\*)){3} + ) + ) + $/"; + $regex = str_replace(array("\r\n", "\n", "\r","\t"," "), '', $regex); + + foreach($ip_list as $i => $ip) + { + preg_match($regex, $ip, $matches); + if(!count($matches)) return false; + } + + return true; + } + +} + + +/* End of file : IpFilter.class.php */ +/* Location: ./classes/security/IpFilter.class.php */ diff --git a/common/lang/lang.xml b/common/lang/lang.xml index fdad62d8f..fa358f772 100644 --- a/common/lang/lang.xml +++ b/common/lang/lang.xml @@ -2617,6 +2617,14 @@ + + 1. 와일드카드(*) 사용가능(예: 192.168.0.*)
2. 하이픈(-)을 사용하여 대역으로 입력가능
(단, 대역폭으로 입력할 경우 와일드카드 사용불가. 예: 192.168.0.1-192.168.0.254)
3.여러개의 항목은 줄을 바꾸어 입력하세요]]>
+ You can use wildcard(*) (ex: 192.168.0.*)
You can use hyphen(*) for ip range (you can't use wild card with hyphen, ex: 192.168.0.1-192.168.0.254)
]]>
+
+ + + + diff --git a/config/config.inc.php b/config/config.inc.php index 357c4c7cc..dba84366c 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -265,6 +265,7 @@ if(!defined('__XE_LOADED_CLASS__')) require(_XE_PATH_ . 'classes/validator/Validator.class.php'); require(_XE_PATH_ . 'classes/frontendfile/FrontEndFileHandler.class.php'); require(_XE_PATH_ . 'classes/security/Security.class.php'); + require(_XE_PATH_ . 'classes/security/IpFilter.class.php'); if(__DEBUG__) $GLOBALS['__elapsed_class_load__'] = getMicroTime() - __ClassLoadStartTime__; } diff --git a/config/func.inc.php b/config/func.inc.php index 2b2502625..7ad6691f8 100644 --- a/config/func.inc.php +++ b/config/func.inc.php @@ -1318,7 +1318,7 @@ function isCrawler($agent = NULL) $check_agent = array('bot', 'spider', 'google', 'yahoo', 'daum', 'teoma', 'fish', 'hanrss', 'facebook'); $check_ip = array( - '211.245.21.11*' /* mixsh */ + '211.245.21.110-211.245.21.119' /* mixsh */ ); foreach($check_agent as $str) @@ -1329,17 +1329,7 @@ function isCrawler($agent = NULL) } } - $check_ip = '/^(' . implode($check_ip, '|') . ')/'; - $check_ip = str_replace('.', '\.', $check_ip); - $check_ip = str_replace('*', '.+', $check_ip); - $check_ip = str_replace('?', '.?', $check_ip); - - if(preg_match($check_ip, $_SERVER['REMOTE_ADDR'], $matches)) - { - return TRUE; - } - - return FALSE; + return IpFilter::filter($check_ip, '211.245.21.113'); } /** diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index 6e7241220..5d995d28e 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -490,11 +490,31 @@ class adminAdminController extends admin $db_info->use_sitelock = ($vars->use_sitelock) ? $vars->use_sitelock : 'N'; $db_info->sitelock_title = $vars->sitelock_title; $db_info->sitelock_message = $vars->sitelock_message; - $db_info->sitelock_whitelist = $vars->sitelock_whitelist; - if(!$db_info->sitelock_whitelist) $db_info->sitelock_whitelist = '127.0.0.1'; + + $whitelist = $vars->sitelock_whitelist; + $whitelist = preg_replace("/[\r|\n|\r\n]+/",",",$whitelist); + $whitelist = preg_replace("/\s+/","",$whitelist); + if(preg_match('/(<\?|<\?php|\?>)/xsm', $whitelist)) + { + $whitelist = ''; + } + $whitelist .= ',127.0.0.1'; + $whitelist = explode(',',trim($whitelist, ',')); + $whitelist = array_unique($whitelist); - FileHandler::writeFile(Context::getConfigFile(), $oInstallController->_getDBConfigFileContents($db_info)); + if(!IpFilter::validate($whitelist)) { + return new Object(-1, 'msg_invalid_ip'); + } + + $db_info->sitelock_whitelist = $whitelist; + + $oInstallController = &getController('install'); + if(!$oInstallController->makeConfigFile()) + { + return new Object(-1, 'msg_invalid_request'); + } + if(!in_array(Context::getRequestMethod(), array('XMLRPC','JSON'))) { $returnUrl = Context::get('success_return_url'); @@ -502,6 +522,12 @@ class adminAdminController extends admin header('location:' . $returnUrl); return; } + + + + + + } } diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index 55928d8b4..d47621364 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -419,13 +419,15 @@ class adminAdminView extends admin Context::set('use_sitelock', $db_info->use_sitelock); Context::set('sitelock_title', $db_info->sitelock_title); Context::set('sitelock_message', htmlspecialchars($db_info->sitelock_message, ENT_COMPAT | ENT_HTML401, 'UTF-8', false)); - Context::set('sitelock_whitelist', implode(PHP_EOL, $db_info->sitelock_whitelist)); + + $whitelist = implode("\r\n", $db_info->sitelock_whitelist); + Context::set('sitelock_whitelist', $whitelist); + + $admin_ip_list = implode("\r\n", $db_info->admin_ip_list); + Context::set('admin_ip_list', $admin_ip_list); Context::set('lang_selected', Context::loadLangSelected()); - $admin_ip_list = preg_replace("/[,]+/", "\r\n", $db_info->admin_ip_list); - Context::set('admin_ip_list', $admin_ip_list); - $oAdminModel = getAdminModel('admin'); $favicon_url = $oAdminModel->getFaviconUrl(); $mobicon_url = $oAdminModel->getMobileIconUrl(); diff --git a/modules/admin/tpl/config_general.html b/modules/admin/tpl/config_general.html index cef738e5c..bc5c5a68d 100644 --- a/modules/admin/tpl/config_general.html +++ b/modules/admin/tpl/config_general.html @@ -140,7 +140,8 @@
- + +

{$lang->about_ipaddress_input}

@@ -222,6 +223,8 @@ {$lang->sitelock_warning_whitelist} {$lang->your_ip} : {$remote_addr} +
+

{$lang->about_ipaddress_input}

diff --git a/modules/install/install.admin.controller.php b/modules/install/install.admin.controller.php index 8fd274d6a..08c91e39d 100644 --- a/modules/install/install.admin.controller.php +++ b/modules/install/install.admin.controller.php @@ -49,15 +49,25 @@ class installAdminController extends install */ function procInstallAdminSaveTimeZone() { + $db_info = Context::getDBInfo(); + $admin_ip_list = Context::get('admin_ip_list'); - $admin_ip_list = preg_replace("/[\r|\n|\r\n]+/",",",$admin_ip_list); - $admin_ip_list = preg_replace("/\s+/","",$admin_ip_list); - if(preg_match('/(<\?|<\?php|\?>)/xsm', $admin_ip_list)) + if($admin_ip_list) { - $admin_ip_list = ''; + $admin_ip_list = preg_replace("/[\r|\n|\r\n]+/",",",$admin_ip_list); + $admin_ip_list = preg_replace("/\s+/","",$admin_ip_list); + if(preg_match('/(<\?|<\?php|\?>)/xsm', $admin_ip_list)) + { + $admin_ip_list = ''; + } + $admin_ip_list = explode(',',trim($admin_ip_list, ',')); + $admin_ip_list = array_unique($admin_ip_list); + if(!IpFilter::validate($admin_ip_list)) { + return new Object(-1, 'msg_invalid_ip'); + } } - + $default_url = Context::get('default_url'); if($default_url && strncasecmp('http://', $default_url, 7) !== 0 && strncasecmp('https://', $default_url, 8) !== 0) $default_url = 'http://'.$default_url; @@ -82,7 +92,6 @@ class installAdminController extends install $use_html5 = Context::get('use_html5'); if(!$use_html5) $use_html5 = 'N'; - $db_info = Context::getDBInfo(); $db_info->default_url = $default_url; $db_info->qmail_compatibility = $qmail_compatibility; $db_info->use_db_session = $use_db_session; diff --git a/modules/install/install.controller.php b/modules/install/install.controller.php index f727501f5..df9504a33 100644 --- a/modules/install/install.controller.php +++ b/modules/install/install.controller.php @@ -553,10 +553,8 @@ class installController extends install { $tmpValue = $this->_getDbConnText($key, $val, true); } - else if($key == 'sitelock_whitelist') + else if($key == 'sitelock_whitelist' || $key == 'admin_ip_list') { - if(!is_array($val)) $val = preg_split("/[\r\n|\r|\n]+/", $val); - $val = array_unique($val); $tmpValue = sprintf('$db_info->%s = array(\'%s\');' . PHP_EOL, $key, implode('\', \'', $val)); } else @@ -578,7 +576,6 @@ class installController extends install $buff[] = $tmpValue; } - $buff[] = "?>"; return implode(PHP_EOL, $buff); } diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 38d638472..216053935 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -294,24 +294,9 @@ class memberAdminModel extends member { $db_info = Context::getDBInfo(); $admin_ip_list = $db_info->admin_ip_list; - $admin_ip_list = explode(",",$admin_ip_list); - $oMemberModel = &getModel('member'); - $ip = $_SERVER['REMOTE_ADDR']; - $falg = false; - foreach($admin_ip_list as $admin_ip_list_key => $admin_ip_value) - { - if(preg_match('/^\d{1,3}(?:.(\d{1,3}|\*)){3}\s*$/', $admin_ip_value, $matches) && $ip) - { - $admin_ip = $matches[0]; - $admin_ip = str_replace('*','',$admin_ip); - $admin_ip_patterns[] = preg_quote($admin_ip); - $admin_ip_pattern = '/^('.implode($admin_ip_patterns,'|').')/'; - if(preg_match($admin_ip_pattern, $ip, $matches)) return true; - $flag = true; - } - } - if(!$flag) return true; - return false; + if(!is_array($admin_ip_list)) $admin_ip_list = explode(',',$admin_ip_list); + if(!count($admin_ip_list) || IpFilter::filter($admin_ip_list)) return true; + else return false; } } /* End of file member.admin.model.php */