From 9e9b09464fc737c12ce3c84201a11343f4cd8a3e Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 8 Feb 2016 21:26:43 +0900 Subject: [PATCH] Clean up admin IP whitelist and block at login time --- classes/module/ModuleHandler.class.php | 12 --------- modules/admin/admin.admin.controller.php | 16 ++++++++++++ modules/admin/lang/en.php | 7 ++++-- modules/admin/lang/ja.php | 7 ++++-- modules/admin/lang/ko.php | 7 ++++-- modules/admin/lang/tr.php | 2 +- modules/admin/lang/zh-CN.php | 2 +- modules/admin/tpl/config_security.html | 11 +++++++-- modules/member/lang/en.php | 1 + modules/member/lang/es.php | 1 + modules/member/lang/fr.php | 1 + modules/member/lang/ja.php | 1 + modules/member/lang/ko.php | 1 + modules/member/lang/zh-CN.php | 1 + modules/member/lang/zh-TW.php | 1 + modules/member/member.admin.model.php | 31 ++++++++++++++++++++---- modules/member/member.controller.php | 28 ++++++++++++--------- 17 files changed, 92 insertions(+), 38 deletions(-) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index afe01ad47..b996f5de0 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -436,18 +436,6 @@ class ModuleHandler extends Handler $logged_info = Context::get('logged_info'); - // Admin ip - if($kind == 'admin' && $_SESSION['denied_admin'] == 'Y') - { - self::_setInputErrorToContext(); - $this->error = "msg_not_permitted_act"; - $oMessageObject = self::getModuleInstance('message', $display_mode); - $oMessageObject->setError(-1); - $oMessageObject->setMessage($this->error); - $oMessageObject->dispMessage(); - return $oMessageObject; - } - // if(type == view, and case for using mobilephone) if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled()) { diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index b33672fd1..00d8ca392 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -584,7 +584,23 @@ class adminAdminController extends admin if (!IpFilter::validate($whitelist)) { return new Object(-1, 'msg_invalid_ip'); } + + $denied_ip = array_map('trim', preg_split('/[\r\n]/', $vars->admin_denied_ip)); + $denied_ip = array_unique(array_filter($denied_ip, function($item) { + return $item !== ''; + })); + if (!IpFilter::validate($whitelist)) { + return new Object(-1, 'msg_invalid_ip'); + } + + $oMemberAdminModel = getAdminModel('member'); + if (!$oMemberAdminModel->getMemberAdminIPCheck($allowed_ip, $denied_ip)) + { + return new Object(-1, 'msg_current_ip_will_be_denied'); + } + Rhymix\Framework\Config::set('admin.allow', array_values($allowed_ip)); + Rhymix\Framework\Config::set('admin.deny', array_values($denied_ip)); // Save Rhymix\Framework\Config::save(); diff --git a/modules/admin/lang/en.php b/modules/admin/lang/en.php index 9257346c0..36038933b 100644 --- a/modules/admin/lang/en.php +++ b/modules/admin/lang/en.php @@ -115,9 +115,12 @@ $lang->input_footer_script = 'Footer script'; $lang->detail_input_footer_script = 'The script is inserted into the bottom of body. It does not work at admin page.'; $lang->corp = 'Crop(Cut)'; $lang->ratio = 'Ratio(Keep Aspect)'; -$lang->admin_ip_limit = 'Sepcify IP address band that can access the admin page.'; +$lang->admin_ip_allow = 'IP addresses allowed to log in as administrator'; +$lang->admin_ip_deny = 'IP addresses forbidden to log in as administrator'; $lang->local_ip_address = 'Local IP address'; -$lang->about_admin_ip_limit = 'Specify IP address which can access to admin page. Please note that only the specified IP addresses can access the admin page.'; +$lang->about_admin_ip_allow = 'If this list is not empty, the administrator will only be able to log in from one of the listed IP addresses.'; +$lang->about_admin_ip_deny = 'This list can be used to designate IP addresses that are not allowed to log in as administrator.'; +$lang->msg_current_ip_will_be_denied = 'The given IP list cannot be applied, as they would block your own IP address.'; $lang->detail_about_ftp_info = 'FTP information is needed for easyinstall when save_mode = on.'; $lang->allow_use_favicon = 'Do you want to use favicon?'; $lang->about_use_favicon = 'You can upload 16x16 size*.ico file only.'; diff --git a/modules/admin/lang/ja.php b/modules/admin/lang/ja.php index ed614ef45..c9cbd1902 100644 --- a/modules/admin/lang/ja.php +++ b/modules/admin/lang/ja.php @@ -110,9 +110,12 @@ $lang->input_footer_script = '下段(footer)スクリプト'; $lang->detail_input_footer_script = '最下段にコードを追加します。管理者ページでは遂行できません。'; $lang->corp = '切り取り'; $lang->ratio = 'Ratio(縦横の比率をキープ)'; -$lang->admin_ip_limit = '管理者のIPアドレス帯域'; +$lang->admin_ip_allow = '管理者ログイン許容IP'; +$lang->admin_ip_deny = '管理者ログイン禁止IP'; $lang->local_ip_address = 'ローカルIPアドレス'; -$lang->about_admin_ip_limit = '該当IPについてのみ管理者ページへアクセスできるため、注意してください。IP帯域情報は、/files/config/db.config.php ファイルに保存されます。Change the line to multiple IP.'; +$lang->about_admin_ip_allow = 'ここでIPアドレスの一覧を表示すると、そのIPのみ、管理者のログインが可能になります。すべてのIPからのログインを許可するには、リストを空白のままに。'; +$lang->about_admin_ip_deny = 'ここに記載され、IPアドレスは、管理者のログインが禁止されます。'; +$lang->msg_current_ip_will_be_denied = '入力された設定によると、現在ログインして、管理者のIPアドレスもブロックされます。再度確認してください。'; $lang->detail_about_ftp_info = 'FTP情報を入力すれば簡単設置を可能にします。FTP情報は files/config/ftp.config.php ファイルに保存されます。簡単設置ができない場合、PHPのsafe_modeをOnへ変更が必要です。'; $lang->allow_use_favicon = 'ファビコン設定'; $lang->about_use_favicon = '16 x 16 サイズの*.ico ファイルのみ登録できます。'; diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php index 53fc51655..3561c11bc 100644 --- a/modules/admin/lang/ko.php +++ b/modules/admin/lang/ko.php @@ -112,9 +112,12 @@ $lang->input_footer_script = '하단(footer) 스크립트'; $lang->detail_input_footer_script = '최하단에 코드를 삽입합니다. 관리자 페이지에서는 수행되지 않습니다.'; $lang->corp = 'Crop(잘라내기)'; $lang->ratio = 'Ratio(비율 맞추기)'; -$lang->admin_ip_limit = '관리자 IP대역'; +$lang->admin_ip_allow = '관리자 로그인 허용 IP'; +$lang->admin_ip_deny = '관리자 로그인 금지 IP'; $lang->local_ip_address = '로컬 IP 주소'; -$lang->about_admin_ip_limit = '관리자 페이지로 접근가능한 IP대역을 지정합니다. 해당 IP에 대해서만 관리자 페이지로 접근이 가능하므로 주의 바랍니다.'; +$lang->about_admin_ip_allow = '여기에 IP 주소를 나열하면 해당 IP에서만 관리자 로그인이 가능하게 됩니다. 모든 IP에서 로그인을 허용하려면 목록을 비워 두십시오.'; +$lang->about_admin_ip_deny = '여기에 나열된 IP 주소에서는 관리자 로그인이 금지됩니다.'; +$lang->msg_current_ip_will_be_denied = '주어진 설정에 따르면 현재 로그인하신 관리자의 IP 주소도 차단됩니다. 다시 확인해 주십시오.'; $lang->detail_about_ftp_info = 'safe_mode = on 상태에서 쉬운설치를 사용하려면 FTP 정보를 입력해야 합니다.'; $lang->allow_use_favicon = '파비콘 지정'; $lang->about_use_favicon = '16 x 16 크기의*.ico 파일 업로드 권장.'; diff --git a/modules/admin/lang/tr.php b/modules/admin/lang/tr.php index 85071bb20..77bd8f4ec 100644 --- a/modules/admin/lang/tr.php +++ b/modules/admin/lang/tr.php @@ -93,7 +93,7 @@ $lang->input_footer_script = 'Alt (footer) Script Eklemek'; $lang->detail_input_footer_script = 'Script alt tarafa eklenmiştir. Yönetici sayfası çalışmıyor.'; $lang->corp = 'Crop (Kesme)'; $lang->ratio = 'Ratio(Yüzde Ayarı)'; -$lang->admin_ip_limit = 'Yönetici sayfasına ulaşabileceğiniz IP aralığını belirleyiniz.'; +$lang->admin_ip_allow = 'Yönetici sayfasına ulaşabileceğiniz IP aralığını belirleyiniz.'; $lang->local_ip_address = 'Yerel IP adresi'; $lang->about_admin_ip_limit = 'Sadece bu IP adresi üzerinden yönetici sayfasına erişim mümkündür.IP-bant bilgileri /files/config/db.config.php dosyasında saklanır. Satıra birden fazla öğe girin.'; $lang->detail_about_ftp_info = 'Kolay kurulum sağlayan FTP bilgilerini girdiğinizde. FTP bilgi, dosya / config / ftp.config.php dosyasında saklanır. Kolay yükleme sizin için mümkün değilse, PHP\'nin safe_mode ayarını On şeklinde değiştiriniz.'; diff --git a/modules/admin/lang/zh-CN.php b/modules/admin/lang/zh-CN.php index f5fa5a0e7..b7ea84e8a 100644 --- a/modules/admin/lang/zh-CN.php +++ b/modules/admin/lang/zh-CN.php @@ -92,7 +92,7 @@ $lang->input_footer_script = '输入页脚脚本'; $lang->detail_input_footer_script = '该脚本将被插入到页面的底部. 页面管理将无效.'; $lang->corp = '裁剪'; $lang->ratio = '缩放'; -$lang->admin_ip_limit = '后台IP绑定'; +$lang->admin_ip_allow = '后台IP绑定'; $lang->local_ip_address = '本地IP地址'; $lang->about_admin_ip_limit = '请注意,只有绑定的IP才能访问后台。IP信息将保存在 /files/config/db.config.php. 每行一个IP。'; $lang->detail_about_ftp_info = '当设定FTP信息来启用快捷安装。FTP的信息保存在 /files/config/ftp.config.php. 如果不启用快捷安装,请务必将开启PHP安全模式'; diff --git a/modules/admin/tpl/config_security.html b/modules/admin/tpl/config_security.html index d5309fa96..ff81ba143 100644 --- a/modules/admin/tpl/config_security.html +++ b/modules/admin/tpl/config_security.html @@ -20,10 +20,17 @@
- +
-

{$lang->about_ipaddress_input}

+

{$lang->about_admin_ip_allow}

+
+
+
+ +
+ +

{$lang->about_admin_ip_deny}

diff --git a/modules/member/lang/en.php b/modules/member/lang/en.php index f2f15ce1b..f4c4940cd 100644 --- a/modules/member/lang/en.php +++ b/modules/member/lang/en.php @@ -152,6 +152,7 @@ $lang->msg_accept_agreement = 'You have to accept the agreement.'; $lang->msg_user_denied = 'You have entered a prohibited ID.'; $lang->msg_user_not_confirmed = 'Your account is not activated yet. Please check your email.'; $lang->msg_user_limited = 'You have entered an ID that cannot be used before %s'; +$lang->msg_admin_ip_not_allowed = 'Your IP address is not allowed to log in as an administrator.'; $lang->about_rechecked_password = 'Confirm your password before editing account information.'; $lang->about_user_id = 'User ID should be 3~20 characters long, consist of alphanumeric and start with a letter.'; $lang->about_password = 'Password should be 6~20 characters long.'; diff --git a/modules/member/lang/es.php b/modules/member/lang/es.php index 76420c629..45557fec6 100644 --- a/modules/member/lang/es.php +++ b/modules/member/lang/es.php @@ -107,6 +107,7 @@ $lang->msg_accept_agreement = 'Usted primero debe aceptar el acuerdo'; $lang->msg_user_denied = 'ID ingresado ha sido prohibido para su uso'; $lang->msg_user_not_confirmed = '아직 메일 인증이 이루어지지 않았습니다. 메일을 확인해 주세요'; $lang->msg_user_limited = 'ID ingresado puede ser usado luego de %s'; +$lang->msg_admin_ip_not_allowed = 'Su dirección IP no se puede iniciar la sesión como administrador.'; $lang->about_user_id = 'ID del usuario debe ser entre 3-20 letras que consiste en alfabetos+número con alfabeto como primera letra.'; $lang->about_password = 'Contraseña debe ser entre 6-20 letras'; $lang->about_user_name = 'Nombre debe ser entre 2-20 letras'; diff --git a/modules/member/lang/fr.php b/modules/member/lang/fr.php index 6abe33787..d3674d841 100644 --- a/modules/member/lang/fr.php +++ b/modules/member/lang/fr.php @@ -120,6 +120,7 @@ $lang->msg_accept_agreement = 'Vous devez agréer l\'accord'; $lang->msg_user_denied = 'Le compte que vous avez entré est suspendu'; $lang->msg_user_not_confirmed = 'Vous n\'avez pas encore authentifié. Verifiez votre mél, S.V.P.'; $lang->msg_user_limited = 'Vous avez entré un compte qui peut être utilisé depuis %s'; +$lang->msg_admin_ip_not_allowed = 'Votre adresse IP ne soit pas autorisé à se connecter en tant qu\'administrateur.'; $lang->about_user_id = 'Le compte d\'utilisateur doit être long de 3~20 lettres et se composer des alphabets et des chiffres avec un alphabet au premier.'; $lang->about_password = 'Le Mot de Passe doit être long de 6~20 lettres.'; $lang->about_user_name = 'Le Nom doit être long de 2~20 lettres.'; diff --git a/modules/member/lang/ja.php b/modules/member/lang/ja.php index 097d72ba0..2338a3d7f 100644 --- a/modules/member/lang/ja.php +++ b/modules/member/lang/ja.php @@ -156,6 +156,7 @@ $lang->msg_accept_agreement = '利用規約に同意しなければなりませ $lang->msg_user_denied = '利用が中止されているユーザIDです。'; $lang->msg_user_not_confirmed = 'メールでの認証が行われていません。メールを確認してください。'; $lang->msg_user_limited = '入力したユーザIDは%s以前まで使用できません。'; +$lang->msg_admin_ip_not_allowed = '接続したIPアドレスでは、管理者のログインが許容されないです。'; $lang->about_rechecked_password = '会員の情報を安全に保護するため、パスワードを再度確認します。'; $lang->about_user_id = 'ユーザーIDは、3~20文字までの英数文字にしてください。先頭文字は英字でなければなりません。'; $lang->about_password = 'パスワードは6~20文字にしてください。'; diff --git a/modules/member/lang/ko.php b/modules/member/lang/ko.php index 4da8f0cee..6de7477fc 100644 --- a/modules/member/lang/ko.php +++ b/modules/member/lang/ko.php @@ -158,6 +158,7 @@ $lang->msg_accept_agreement = '약관에 동의해야 합니다.'; $lang->msg_user_denied = '입력한 아이디의 사용이 중지 되었습니다.'; $lang->msg_user_not_confirmed = '아직 메일 인증이 이루어지지 않았습니다. 메일을 확인해 주세요.'; $lang->msg_user_limited = '입력한 아이디는 %s 까지 사용하실 수 없습니다.'; +$lang->msg_admin_ip_not_allowed = '접속하신 IP 주소에서는 관리자 로그인이 허용되지 않습니다.'; $lang->about_rechecked_password = '회원의 정보를 안전하게 보호하기 위해 비밀번호를 다시 한번 확인 합니다.'; $lang->about_user_id = '회원 ID는 3~20자 사이의 영문+숫자로 이루어져야 하며 영문으로 시작해야 합니다.'; $lang->about_password = '비밀번호는 6~20자로 되어야 합니다.'; diff --git a/modules/member/lang/zh-CN.php b/modules/member/lang/zh-CN.php index 3fbd9346f..cdc5fefd5 100644 --- a/modules/member/lang/zh-CN.php +++ b/modules/member/lang/zh-CN.php @@ -154,6 +154,7 @@ $lang->msg_accept_agreement = '您必须同意条款。'; $lang->msg_user_denied = '您输入的用户名已禁止使用!'; $lang->msg_user_not_confirmed = '您的注册信息还没有被激活,请确认您的电子邮箱。'; $lang->msg_user_limited = '您输入的用户名%s以后才可以开始使用。'; +$lang->msg_admin_ip_not_allowed = '连接的IP地址中,管理者的登录在不允许的。'; $lang->about_rechecked_password = '为了会员资料的安全保护,再次确认密码。'; $lang->about_user_id = '用户名长度必须由 3 ~20 字以内的英文+数字组成,且首个字母必须是英文字母。'; $lang->about_password = '密码长度必须在6~20字以内。'; diff --git a/modules/member/lang/zh-TW.php b/modules/member/lang/zh-TW.php index 42db8dc17..8b168786e 100644 --- a/modules/member/lang/zh-TW.php +++ b/modules/member/lang/zh-TW.php @@ -142,6 +142,7 @@ $lang->msg_accept_agreement = '您必須同意條款。'; $lang->msg_user_denied = '您輸入的帳號已禁止使用!'; $lang->msg_user_not_confirmed = '您的註冊資料尚未啟用,請確認您的電子郵箱。'; $lang->msg_user_limited = '您輸入的帳號 %s 以後才可以開始使用。'; +$lang->msg_admin_ip_not_allowed = '連接的IP地址中,管理者的登錄在不允許的。'; $lang->about_user_id = '帳號必須由 3~20 字以內的英文+數字組成,開頭必須是英文。'; $lang->about_password = '密碼必須在 6~20 字以內。'; $lang->about_user_name = '姓名必須是 2~20 字以內。'; diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 4c9f6db87..9bca07a60 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -294,12 +294,33 @@ class memberAdminModel extends member * * @return boolean (true : allowed, false : refuse) */ - function getMemberAdminIPCheck() + function getMemberAdminIPCheck($allow_list = null, $deny_list = null) { - $admin_ip_list = config('admin.allow'); - if(!$admin_ip_list) return true; - if(!count($admin_ip_list) || IpFilter::filter($admin_ip_list)) return true; - else return false; + if ($allow_list = ($allow_list === null) ? config('admin.allow') : $allow_list) + { + foreach ($allow_list as $range) + { + if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) + { + return true; + } + } + return false; + } + + if ($deny_list = ($deny_list === null) ? config('admin.deny') : $deny_list) + { + foreach ($deny_list as $range) + { + if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) + { + return false; + } + } + return true; + } + + return true; } } /* End of file member.admin.model.php */ diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index 559f4ec5d..a8dfbebdd 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -1753,8 +1753,23 @@ class memberController extends member } return new Object(-1, ($this->memberInfo->refused_reason)? Context::getLang('msg_user_denied') . "\n" . $this->memberInfo->refused_reason : 'msg_user_denied'); } - // Notify if denied_date is less than the current time - if($this->memberInfo->limit_date && substr($this->memberInfo->limit_date,0,8) >= date("Ymd")) return new Object(-9,sprintf(Context::getLang('msg_user_limited'),zdate($this->memberInfo->limit_date,"Y-m-d"))); + + // Notify if user is limited + if($this->memberInfo->limit_date && substr($this->memberInfo->limit_date,0,8) >= date("Ymd")) + { + return new Object(-9,sprintf(Context::getLang('msg_user_limited'),zdate($this->memberInfo->limit_date,"Y-m-d"))); + } + + // Do not allow login as admin if not in allowed IP list + if($this->memberInfo->is_admin === 'Y' && $this->act === 'procMemberLogin') + { + $oMemberAdminModel = getAdminModel('member'); + if(!$oMemberAdminModel->getMemberAdminIPCheck()) + { + return new Object(-1, 'msg_admin_ip_not_allowed'); + } + } + // Update the latest login time $args->member_srl = $this->memberInfo->member_srl; $output = executeQuery('member.updateLastLogin', $args); @@ -1819,17 +1834,8 @@ class memberController extends member $autologin_output = executeQuery('member.insertAutologin', $autologin_args); if($autologin_output->toBool()) setCookie('xeak',$autologin_args->autologin_key, $_SERVER['REQUEST_TIME']+31536000, '/'); } - if($this->memberInfo->is_admin == 'Y') - { - $oMemberAdminModel = getAdminModel('member'); - if(!$oMemberAdminModel->getMemberAdminIPCheck()) - { - $_SESSION['denied_admin'] = 'Y'; - } - } $this->setSessionInfo(); - return $output; }