diff --git a/addons/spamfilter/spamfilter.addon.php b/addons/spamfilter/spamfilter.addon.php
index 9c52ebfe3..73ab00fb3 100644
--- a/addons/spamfilter/spamfilter.addon.php
+++ b/addons/spamfilter/spamfilter.addon.php
@@ -1,133 +1,6 @@
act, $effecived_target_act)) return;
-
- // 각 모듈별 act에 대해서도 피해갈 부분이 있으면 피해감
- switch($this->act) {
-
- // 게시물 작성시 신규 등록이 아니면 패스~
- case 'procBoardInsertDocument' :
- // document module의 model 객체 생성
- $oDocumentModel = &getModel('document');
-
- // 이미 존재하는 글인지 체크
- $document_srl = Context::get('document_srl');
- $oDocument = $oDocumentModel->getDocument($document_srl);
-
- // 이미 존재하는 글이라면 return
- if($oDocument->isExists()) return;
- break;
-
- // 댓글 작성시 신규 등록이 아니면 패스~
- case 'procBoardInsertComment' :
- case 'procBlogInsertComment' :
- $comment_srl = Context::get('comment_srl');
- $oCommentModel = &getModel('comment');
-
- // 이미 존재하는 댓글인지 체크
- $comment = $oCommentModel->getComment($comment_srl);
- if($comment->comment_srl == $comment_srl) return;
- break;
- }
-
- // 현재 모듈의 관리자이거나 그에 준하는 manager권한이면 그냥 패스
- if($this->grant->is_admin || $this->grant->manager) return;
-
- // 현 접속자의 ip address를 구함
- $ipaddress = $_SERVER['REMOTE_ADDR'];
-
- // spamfilter 모듈 객체 생성
- $oSpamFilterController = &getController('spamfilter');
- $oSpamFilterModel = &getModel('spamfilter');
-
- // 스팸필터 기본 설정 출력
- $config = $oSpamFilterModel->getConfig();
-
- // 스팸 간격을 체크하는 변수
- $interval = $config->interval?$config->interval:60;
-
- // 스팸 간격내에 limit_count이상 작성을 시도하면 해당 ip를 금지 시킴
- $limit_count = $config->limit_count?$config->limit_count:5;
-
- // 트랙백의 경우 한 글에 하나의 ip에서만 트랙백을 허용함
- $check_trackback = $config->check_trackback=='Y'?true:false;
-
- // 스팸 IP에 등록되어 있는지 체크하여 등록되어 있으면 return
- $is_denied = $oSpamFilterModel->isDeniedIP($ipaddress);
- if($is_denied) {
- $output = new Object(-1, 'msg_alert_registered_denied_ip');
- $this->stop_proc = true;
- return;
- }
-
- // act==procReceiveTrackback (트랙백)일때 check_trackback==true이면 검사
- if($this->act=='trackback' && $check_trackback){
- $oTrackbackModel = &getModel('trackback');
- $document_srl = Context::get('document_srl');
- $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, $ipaddress);
- if($count>0) {
- $output = Object(-1, 'msg_alert_trackback_denied');
- $this->stop_proc = true;
- return;
- }
- }
-
- // 정해진 시간내에 글 작성 시도를 하였는지 체크
- $count = $oSpamFilterModel->getLogCount($interval, $ipaddress);
-
- // 정해진 시간내에 정해진 글의 수를 초과시 스팸 IP로 등록시킴
- if($count>=$limit_count) {
- $oSpamFilterController->insertIP($ipaddress);
- $output = new Object(-1, 'msg_alert_registered_denied_ip');
- $this->stop_proc = true;
- return;
-
- // 제한 글수까지는 아니지만 정해진 시간내에 글 작성을 계속 할때
- } elseif($count) {
- $message = sprintf(Context::getLang('msg_alert_limited_by_config'), $interval);
- $output = new Object(-1, $message);
- $this->stop_proc = true;
- }
-
- // 금지 단어 체크를 위해서 몇가지 지정된 변수들을 한데 묶음
- $check_vars = implode("\n",get_object_vars(Context::getRequestVars()));
-
- // 금지 단어를 이용하여 본문 내용을 체크
- $denied_word_list = $oSpamFilterModel->getDeniedWordList();
- $denied_word_count = count($denied_word_list);
- if($denied_word_count>0) {
- for($i=0;$i<$denied_word_count;$i++) {
- $word = preg_quote($denied_word_list[$i]->word,'/');
- if(preg_match('/'.$word.'/i', $check_vars)) {
- $message = sprintf(Context::getLang('msg_alert_denied_word'), $word);
- $output = new Object(-1, $message);
- $this->stop_proc = true;
- return;
- }
- }
- }
-
- // 로그를 남김
- $oSpamFilterController->insertLog();
+ return;
?>
diff --git a/modules/spamfilter/queries/isDeniedIP.xml b/modules/spamfilter/queries/isDeniedIP.xml
index 6bfd31adf..53b497cc8 100644
--- a/modules/spamfilter/queries/isDeniedIP.xml
+++ b/modules/spamfilter/queries/isDeniedIP.xml
@@ -6,6 +6,6 @@
-
+
diff --git a/modules/spamfilter/spamfilter.class.php b/modules/spamfilter/spamfilter.class.php
index b1375b138..831fd989e 100644
--- a/modules/spamfilter/spamfilter.class.php
+++ b/modules/spamfilter/spamfilter.class.php
@@ -17,6 +17,11 @@
$oModuleController->insertActionForward('spamfilter', 'view', 'dispSpamfilterAdminDeniedIPList');
$oModuleController->insertActionForward('spamfilter', 'view', 'dispSpamfilterAdminDeniedWordList');
+ // 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
+ $oModuleController->insertTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before');
+ $oModuleController->insertTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before');
+ $oModuleController->insertTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before');
+
return new Object();
}
@@ -24,6 +29,13 @@
* @brief 설치가 이상이 없는지 체크하는 method
**/
function checkUpdate() {
+ $oModuleModel = &getModel('module');
+
+ // 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
+ if(!$oModuleModel->getTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before')) return true;
+ if(!$oModuleModel->getTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before')) return true;
+ if(!$oModuleModel->getTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before')) return true;
+
return false;
}
@@ -31,7 +43,18 @@
* @brief 업데이트 실행
**/
function moduleUpdate() {
- return new Object();
+ $oModuleModel = &getModel('module');
+ $oModuleController = &getController('module');
+
+ // 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
+ if(!$oModuleModel->getTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before'))
+ $oModuleController->insertTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before');
+ if(!$oModuleModel->getTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before'))
+ $oModuleController->insertTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before');
+ if(!$oModuleModel->getTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before'))
+ $oModuleController->insertTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before');
+
+ return new Object(0,'success_updated');
}
/**
diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php
index 0028d25e0..3f733d6c4 100644
--- a/modules/spamfilter/spamfilter.controller.php
+++ b/modules/spamfilter/spamfilter.controller.php
@@ -13,6 +13,112 @@
function init() {
}
+ /**
+ * @brief 글 작성시 글 작성 시간 체크 및 금지 ip/단어 처리 루틴
+ **/
+ function triggerinsertDocument(&$obj) {
+ // 로그인 여부, 로그인 정보, 권한 유무 체크
+ $is_logged = Context::get('is_logged');
+ $logged_info = Context::get('logged_info');
+ $grant = Context::get('grant');
+
+ // 로그인 되어 있을 경우 관리자 여부를 체크
+ if($is_logged) {
+ if($logged_info->is_admin == 'Y') return new Object();
+ if($grant->manager) return new Object();
+ }
+
+ $oFilterModel = &getModel('spamfilter');
+
+ // ip가 금지되어 있는 경우를 체크
+ $output = $oFilterModel->isDeniedIP();
+ if(!$output->toBool()) return $output;
+
+ // 금지 단어에 있을 경우 체크
+ $text = $obj->title.$obj->content;
+ $output = $oFilterModel->isDeniedWord($text);
+ if(!$output->toBool()) return $output;
+
+ // 지정된 시간 체크
+ $output = $oFilterModel->checkLimited();
+ if(!$output->toBool()) return $output;
+
+ // 로그 남김
+ $this->insertLog();
+
+ return new Object();
+ }
+
+ /**
+ * @brief 댓글 작성 시간 및 금지 ip/ 단어 처리 루틴
+ **/
+ function triggerInsertComment(&$obj) {
+ // 로그인 여부, 로그인 정보, 권한 유무 체크
+ $is_logged = Context::get('is_logged');
+ $logged_info = Context::get('logged_info');
+ $grant = Context::get('grant');
+
+ // 로그인 되어 있을 경우 관리자 여부를 체크
+ if($is_logged) {
+ if($logged_info->is_admin == 'Y') return new Object();
+ if($grant->manager) return new Object();
+ }
+
+ $oFilterModel = &getModel('spamfilter');
+
+ // ip가 금지되어 있는 경우를 체크
+ $output = $oFilterModel->isDeniedIP();
+ if(!$output->toBool()) return $output;
+
+ // 금지 단어에 있을 경우 체크
+ $text = $obj->content;
+ $output = $oFilterModel->isDeniedWord($text);
+ if(!$output->toBool()) return $output;
+
+ // 지정된 시간 체크
+ $output = $oFilterModel->checkLimited();
+ if(!$output->toBool()) return $output;
+
+ // 로그 남김
+ $this->insertLog();
+
+ return new Object();
+ }
+
+ /**
+ * @brief 엮인글 작성시 시간 및 ip 검사
+ **/
+ function triggerInsertTrackback(&$obj) {
+ $oFilterModel = &getModel('spamfilter');
+
+ // 해당 글에 엮인글을 한번 이상 추가하였는지를 확인
+ $output = $oFilterModel->isInsertedTrackback($obj->document_srl);
+ if(!$output->toBool()) return $output;
+
+ // ip가 금지되어 있는 경우를 체크
+ $output = $oFilterModel->isDeniedIP();
+ if(!$output->toBool()) return $output;
+
+ // 금지 단어에 있을 경우 체크
+ $text = $obj->blog_name.$obj->title.$obj->excerpt.$obj->url;
+ $output = $oFilterModel->isDeniedWord($text);
+ if(!$output->toBool()) return $output;
+
+ // 12시간 이내에 3개 이상 한 C클래스의 ip에서 엮인글 등록 시도시 금지 아이피로 지정하고 해당 ip의 글을 모두 삭제
+ $oTrackbackModel = &getModel('trackback');
+ list($ipA,$ipB,$ipC,$ipD) = explode('.',$_SERVER['REMOTE_ADDR']);
+ $ipaddress = $ipA.'.'.$ipB.'.'.$ipC;
+ $count = $oTrackbackModel->getRegistedTrackback(24*60*60, $ipaddress);
+ if($count > 2) {
+ $oTrackbackController = &getController('trackback');
+ $oTrackbackController->deleteTrackbackSender(24*60*60, $ipaddress);
+ $this->insertIP($_SERVER['REMOTE_ADDR']);
+ return new Object(-1,'msg_alert_trackback_denied');
+ }
+
+ return new Object();
+ }
+
/**
* @brief IP 등록
* 등록된 IP는 스패머로 간주
diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php
index 97dd2a65f..54b64136b 100644
--- a/modules/spamfilter/spamfilter.model.php
+++ b/modules/spamfilter/spamfilter.model.php
@@ -37,11 +37,24 @@
/**
* @brief 인자로 넘겨진 ipaddress가 금지 ip인지 체크하여 return
**/
- function isDeniedIP($ipaddress) {
- $args->ipaddress = $ipaddress;
- $output = executeQuery('spamfilter.isDeniedIP', $args);
- if($output->data->count>0) return true;
- return false;
+ function isDeniedIP() {
+ $ipaddress = $_SERVER['REMOTE_ADDR'];
+
+ $ip_list = $this->getDeniedIPList();
+ if(!count($ip_list)) return false;
+
+ $count = count($ip_list);
+ $patterns = array();
+ for($i=0;$i<$count;$i++) {
+ $ip = str_replace('*','',$ip_list[$i]->ipaddress);
+ $patterns[] = $ip;
+ }
+
+ $pattern = '/^('.implode($patterns,'|').')/';
+
+ if(preg_match($pattern, $ipaddress, $matches)) return new Object(-1,'msg_alert_registered_denied_ip');
+
+ return new Object();
}
/**
@@ -55,6 +68,69 @@
return $output->data;
}
+ /**
+ * @brief 넘어온 text에 금지 단어가 있는지 확인
+ **/
+ function isDeniedWord($text) {
+ $word_list = $this->getDeniedWordList();
+ if(!count($word_list)) return false;
+
+ $count = count($word_list);
+ for($i=0;$i<$count;$i++) {
+ $word = $word_list[$i]->word;
+ if(strpos($text, $word)!==false) return new Object(-1,sprintf(Context::getLang('msg_alert_denied_word'), $word));
+ }
+
+ return new Object();
+ }
+
+ /**
+ * @brief 지정된 시간을 체크
+ **/
+ function checkLimited() {
+ $config = $this->getConfig();
+ $limit_count = $config->limit_count?$config->limit_count:5;
+ $interval = $config->interval?$config->interval:60;
+
+ $count = $this->getLogCount($interval);
+
+ $ipaddress = $_SERVER['REMOTE_ADDR'];
+
+ // 정해진 시간보다 클 경우 금지 ip로 등록
+ if($count>=$limit_count) {
+ $oSpamFilterController = &getController('spamfilter');
+ $oSpamFilterController->insertIP($ipaddress);
+ return new Object(-1, 'msg_alert_registered_denied_ip');
+ }
+
+ // 제한 글수까지는 아니지만 정해진 시간내에 글 작성을 계속 할때
+ if($count) {
+ $message = sprintf(Context::getLang('msg_alert_limited_by_config'), $interval);
+
+ $oSpamFilterController = &getController('spamfilter');
+ $oSpamFilterController->insertLog();
+
+ return new Object(-1, $message);
+ }
+
+ return new Object();
+ }
+
+ /**
+ * @brief 특정 글에 이미 엮인글이 등록되어 있는지 확인
+ **/
+ function isInsertedTrackback($document_srl) {
+ $config = $this->getConfig();
+ $check_trackback = $config->check_trackback=='Y'?true:false;
+ if(!$check_trackback) return new Object();
+
+ $oTrackbackModel = &getModel('trackback');
+ $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, $_SERVER['REMOTE_ADDR']);
+ if($count>0) return Object(-1, 'msg_alert_trackback_denied');
+
+ return new Object();
+ }
+
/**
* @brief 지정된 IPaddress의 특정 시간대 내의 로그 수를 return
**/
diff --git a/modules/trackback/queries/getRegistedTrackback.xml b/modules/trackback/queries/getRegistedTrackback.xml
new file mode 100644
index 000000000..f3bff75e3
--- /dev/null
+++ b/modules/trackback/queries/getRegistedTrackback.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/trackback/queries/getRegistedTrackbacks.xml b/modules/trackback/queries/getRegistedTrackbacks.xml
new file mode 100644
index 000000000..603a6cdb3
--- /dev/null
+++ b/modules/trackback/queries/getRegistedTrackbacks.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/trackback/trackback.controller.php b/modules/trackback/trackback.controller.php
index af959f07a..64f5c31d2 100644
--- a/modules/trackback/trackback.controller.php
+++ b/modules/trackback/trackback.controller.php
@@ -114,6 +114,15 @@
}
function insertTrackback($obj, $manual_inserted = false) {
+ // 엮인글 정리
+ $obj = Context::convertEncoding($obj);
+ if(!$obj->blog_name) $obj->blog_name = $obj->title;
+ $obj->excerpt = strip_tags($obj->excerpt);
+
+ // trigger 호출 (before)
+ $output = ModuleHandler::triggerCall('trackback.insertTrackback', 'before', $obj);
+ if(!$output->toBool()) return $output;
+
// GET으로 넘어온 document_srl을 참조, 없으면 오류~
$document_srl = $obj->document_srl;
@@ -129,10 +138,6 @@
$obj->module_srl = $oDocument->get('module_srl');
}
- // 엮인글 정리
- $obj = Context::convertEncoding($obj);
- if(!$obj->blog_name) $obj->blog_name = $obj->title;
- $obj->excerpt = strip_tags($obj->excerpt);
// 엮인글를 입력
$obj->trackback_srl = getNextSequence();
@@ -283,5 +288,20 @@
return new Object(0, 'msg_trackback_send_success');
}
+
+ /**
+ * @brief 특정 ipaddress의 특정 시간대 내의 엮인글을 모두 삭제
+ **/
+ function deleteTrackbackSender($time, $ipaddress) {
+ $obj->regdate = date("YmdHis",time()-$time);
+ $obj->ipaddress = $ipaddress;
+ $output = executeQueryArray('trackback.getRegistedTrackbacks', $obj);
+ if(!$output->data || !count($output->data)) return;
+
+ foreach($output->data as $trackback) {
+ $trackback_srl = $trackback->trackback_srl;
+ $this->deleteTrackback($trackback_srl, true);
+ }
+ }
}
?>
diff --git a/modules/trackback/trackback.model.php b/modules/trackback/trackback.model.php
index 6021f67aa..5fbba54eb 100644
--- a/modules/trackback/trackback.model.php
+++ b/modules/trackback/trackback.model.php
@@ -97,5 +97,15 @@
}
return $module_trackback_config;
}
+
+ /**
+ * @brief 정해진 시간내에 전체 엮인글 등록수를 구함
+ **/
+ function getRegistedTrackback($time, $ipaddress) {
+ $obj->regdate = date("YmdHis",time()-$time);
+ $obj->ipaddress = $ipaddress;
+ $output = executeQuery('trackback.getRegistedTrackback', $obj);
+ return $output->data->count;
+ }
}
?>