From 645b22007bd71bccc00dfa08c103aa232c28e871 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:00:29 +0300 Subject: [PATCH 01/16] update package versions --- ansible/runonce/db.yml | 4 ++-- ansible/runonce/includes/chroot_env.yml | 2 +- ansible/runonce/mui.yml | 6 +++--- ansible/runonce/pui.yml | 9 +++++---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ansible/runonce/db.yml b/ansible/runonce/db.yml index 5793c38c7..f20dc5e0f 100644 --- a/ansible/runonce/db.yml +++ b/ansible/runonce/db.yml @@ -91,8 +91,8 @@ - libmemcached - py3-mysqlclient - libtool - - autoconf-2.69p3 - - automake-1.16.3 + - autoconf%2.69 + - automake%1.16 my_cnf: - { init_file: "/etc/mysql-init.sql"} - { bind-address: "{{db_ip}}" } diff --git a/ansible/runonce/includes/chroot_env.yml b/ansible/runonce/includes/chroot_env.yml index 6b66a520d..67d5b443d 100644 --- a/ansible/runonce/includes/chroot_env.yml +++ b/ansible/runonce/includes/chroot_env.yml @@ -24,7 +24,7 @@ CHROOT_ENV: - "/usr/lib/libc++abi.so.*" - "/usr/lib/libm.so.*" - "/usr/lib/libssl.so.*" -- "/usr/local/share/icu/70.1/icudt*l.dat" +- "/usr/local/share/icu/72.1/icudt*l.dat" - "/usr/local/lib/libmemcached.so.*" - "/usr/local/lib/libintl.so.*" - "/usr/local/lib/libonig.so.*" diff --git a/ansible/runonce/mui.yml b/ansible/runonce/mui.yml index 81017bc93..1d1d6905e 100644 --- a/ansible/runonce/mui.yml +++ b/ansible/runonce/mui.yml @@ -95,8 +95,8 @@ - libmemcached - py3-mysqlclient - libtool - - autoconf-2.69p3 - - automake-1.16.3 + - autoconf%2.69 + - automake%1.16 - pecl74-memcached - nginx - php-gd%7.4 @@ -234,7 +234,7 @@ - usr/bin - usr/libexec - usr/local/lib - - usr/local/share/icu/69.1 + - usr/local/share/icu/72.1 - usr/lib - name: "Copy pf conf files" diff --git a/ansible/runonce/pui.yml b/ansible/runonce/pui.yml index d4b29f8ae..baa6e68a0 100644 --- a/ansible/runonce/pui.yml +++ b/ansible/runonce/pui.yml @@ -90,8 +90,8 @@ - { name: mysqld, state: "disable" } - { name: memcached, state: "disable" } packages: - - autoconf-2.69p3 - - automake-1.16.3 + - autoconf%2.69 + - automake%1.16 - curl - git - libmemcached @@ -105,6 +105,7 @@ - php-pdo_mysql%7.4 - php-zip%7.4 - certbot + - py3-pip - py3-requests - py3-mysqlclient tasks: @@ -185,7 +186,7 @@ name: "{{packages}}" - name: Install lexicon (raw) - raw: pip install lexicon + raw: pip3 install lexicon - name: Install composer get_url: @@ -253,7 +254,7 @@ - usr/bin - usr/libexec - usr/local/lib - - usr/local/share/icu/69.1 + - usr/local/share/icu/72.1 - usr/lib - name: "Copy pf conf files" From 82e9cbc66557903eda03236e267b2980fe96d0ce Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:00:48 +0300 Subject: [PATCH 02/16] fix the paths relative to the inventory --- ansible/runonce/docker-servers.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ansible/runonce/docker-servers.yml b/ansible/runonce/docker-servers.yml index 749e6e535..d580f6e73 100644 --- a/ansible/runonce/docker-servers.yml +++ b/ansible/runonce/docker-servers.yml @@ -151,10 +151,10 @@ - name: Force /etc/network/interfaces ignore_errors: true - when: lookup('ansible.builtin.fileglob', inventory_dir+'/../files/etc_network_interfaces.j2') != [] + when: lookup('ansible.builtin.fileglob', inventory_dir+'/../../files/etc_network_interfaces.j2') != [] ansible.builtin.template: - src: "{{inventory_dir}}/../files/etc_network_interfaces.j2" - dest: /etc/network/interfaces + src: "{{inventory_dir}}/../../files/etc_network_interfaces.j2" + dest: "/etc/network/interfaces.d/{{network.driver_options.parent}}.conf" owner: root group: root mode: '0644' @@ -204,9 +204,9 @@ } - name: Configure new systemd docker overrides - when: lookup('ansible.builtin.fileglob', inventory_dir+'/../files/dockerd-service-override.conf') != [] + when: lookup('ansible.builtin.fileglob', inventory_dir+'/../../files/dockerd-service-override.conf') != [] copy: - src: "{{inventory_dir}}/../files/dockerd-service-override.conf" + src: "{{inventory_dir}}/../../files/dockerd-service-override.conf" dest: /etc/systemd/system/docker.service.d/ - name: Reload systemd @@ -274,9 +274,9 @@ with_dict: "{{ containers }}" - name: Create iptables rules - when: lookup('ansible.builtin.fileglob', inventory_dir+'/../files/iptables_rules.v4') != [] + when: lookup('ansible.builtin.fileglob', inventory_dir+'/../../files/iptables_rules.v4') != [] template: - src: "{{inventory_dir}}/../files/iptables_rules.v4" + src: "{{inventory_dir}}/../../files/iptables_rules.v4" dest: /etc/iptables/rules.v4 - name: Disable IPv6 (needs restart) @@ -364,9 +364,9 @@ - pm2 - name: Copy local ctables - when: lookup('ansible.builtin.fileglob', inventory_dir+'/../files/ctables') != [] + when: lookup('ansible.builtin.fileglob', inventory_dir+'/../../files/ctables') != [] copy: - src: "{{inventory_dir}}/../files/ctables" + src: "{{inventory_dir}}/../../files/ctables" dest: /usr/local/bin/ctables owner: root group: root From 6be13287b91ba54e3f0d97aaf9ab92b88aff2740 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:01:25 +0300 Subject: [PATCH 03/16] force symlink --- ansible/runonce/mui.yml | 2 +- ansible/runonce/pui.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/runonce/mui.yml b/ansible/runonce/mui.yml index 1d1d6905e..ee32a3370 100644 --- a/ansible/runonce/mui.yml +++ b/ansible/runonce/mui.yml @@ -398,7 +398,7 @@ - "mkdir -p /home/moderatorUI/{{domain_name}}/backend/web/assets" - "chown -R moderatorUI /home/moderatorUI/{{domain_name}}/backend/web/assets" - "mkdir -p /var/log/cron" - - "ln -s /home/moderatorUI/{{domain_name}}/backend/yii /usr/local/bin/backend" + - "ln -sf /home/moderatorUI/{{domain_name}}/backend/yii /usr/local/bin/backend" - name: configure moderator rc.d command: rcctl {{item}} diff --git a/ansible/runonce/pui.yml b/ansible/runonce/pui.yml index baa6e68a0..adbc867c9 100644 --- a/ansible/runonce/pui.yml +++ b/ansible/runonce/pui.yml @@ -430,7 +430,7 @@ - mkdir -p /var/log/cron - chown -R participantUI /home/participantUI/{{domain_name}}/frontend/web/assets - chown -R participantUI /home/participantUI/{{domain_name}}/frontend/web/images/avatars/ - - ln -s /home/participantUI/{{domain_name}}/frontend/yii /usr/local/bin/frontend + - ln -sf /home/participantUI/{{domain_name}}/frontend/yii /usr/local/bin/frontend - name: configure participant rc.d command: rcctl {{item}} From 80f25bb1b12e5c818c814a193924f88fbc637ff1 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:02:14 +0300 Subject: [PATCH 04/16] update composer params make sure letsencrypt is populated properly --- ansible/runonce/pui.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ansible/runonce/pui.yml b/ansible/runonce/pui.yml index adbc867c9..c2f72fa76 100644 --- a/ansible/runonce/pui.yml +++ b/ansible/runonce/pui.yml @@ -467,7 +467,7 @@ when: GITHUB_OAUTH_TOKEN is defined and GITHUB_OAUTH_TOKEN!="" - name: run composer - command: chdir=/home/participantUI/{{domain_name}}/frontend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress --no-suggest + command: chdir=/home/participantUI/{{domain_name}}/frontend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress - name: Fix home folder permissions for nginx command: chown root.daemon /home/participantUI @@ -529,14 +529,14 @@ - name: Install renewal policy for letsencrypt ini_file: - path: "/etc/letsencrypt/renewal/{{domain_name}}.conf" - section: renewalparams - option: "{{item.key}}" - value: "{{item.value}}" + path: "/etc/letsencrypt/renewal/{{domain_name}}.conf" + section: renewalparams + option: "{{item.key}}" + value: "{{item.value}}" with_items: - manual_auth_hook: /etc/letsencrypt/lexicon-vultr.sh create - manual_cleanup_hook: /etc/letsencrypt/lexicon-vultr.sh delete - post_hook: /etc/nginx/install_renewed_cert.sh + - { key: manual_auth_hook, value: "/etc/letsencrypt/lexicon-vultr.sh create" } + - { key: manual_cleanup_hook, value: "/etc/letsencrypt/lexicon-vultr.sh delete" } + - { key: post_hook, value: "/etc/nginx/install_renewed_cert.sh" } - name: Execute fw_update command: fw_update -a From 0b63727676fb6c7fde913db72d362d9c58c0c0c6 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:03:12 +0300 Subject: [PATCH 05/16] update player command for spam checking --- backend/commands/PlayerController.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/commands/PlayerController.php b/backend/commands/PlayerController.php index 2d1a0d127..74e067ce3 100644 --- a/backend/commands/PlayerController.php +++ b/backend/commands/PlayerController.php @@ -292,7 +292,7 @@ public function actionPendingAvatars($full=false) /** * Check mails for known spammers. */ - public function actionCheckStopforumspam($interval=null) + public function actionCheckStopforumspam($interval=null,$confidence=90) { $players=Player::find(); if($interval!==null) @@ -307,7 +307,7 @@ public function actionCheckStopforumspam($interval=null) $SFS->email=$p->email; $result=$SFS->check(); $retData=json_decode($result)->email; - if(property_exists($retData,'confidence') && $retData->confidence>0) + if(property_exists($retData,'confidence') && $retData->confidence>=intval($confidence)) { printf("Banning %d: %s %d %d => %s\n",$p->id,$p->email,$p->active,$p->status,floatval($retData->confidence)); $p->ban(); @@ -322,25 +322,30 @@ public function actionCheckStopforumspam($interval=null) public function actionCheckSpammy($domains=false) { $skip_domains=[]; - $players=Player::find()->select(["right(email, length(email)-INSTR(email, '@')) as email"])->distinct(); + $players=Player::find()->select(["SUBSTRING_INDEX(email,'@',-1) as email"])->distinct(); foreach($skip_domains as $d) $players->andWhere(['not like','email', $d]); echo "Found ",$players->count()," distinct domains.\n"; foreach($players->all() as $p) { try{ - $DNS_NS=dns_get_record($p->email, DNS_NS); - $DNS_MX=dns_get_record($p->email, DNS_MX); - $DNS_A=dns_get_record($p->email, DNS_A); + $DNS_NS=dns_get_record($p->email, DNS_NS); + $DNS_MX=dns_get_record($p->email, DNS_MX); + $DNS_A=dns_get_record($p->email, DNS_A); } catch(\Exception $e) { - echo "Failed to resolve [",$p->email,"]",$e->getMessage(),"\n"; + echo "Error: Failed to resolve [",$p->email,"]",$e->getMessage(),"\n"; } if($DNS_NS===[] && $DNS_MX===[]) { echo "Domain[",$p->email,"] has empty MX & NS records\n"; } + $validator = new \app\components\validators\MXServersValidator(); + $validator->mxonly=true; + if (!$validator->validate($p->email, $error)) { + echo "Domain[",$p->email,"] MX Validator error\n"; + } } } @@ -372,7 +377,7 @@ public function actionCheckDupips($skip_uids=false) public function actionFailValidation($delete=false) { - $allRecords=Player::find()->all(); + $allRecords=Player::find()->active()->all(); foreach($allRecords as $p) { $p->scenario='validator'; From 16365d6aa562cc2dd7944d6d3d4a2472b8c2aad5 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:03:37 +0300 Subject: [PATCH 06/16] fix finding form #954 --- backend/modules/gameplay/views/finding/_form.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/modules/gameplay/views/finding/_form.php b/backend/modules/gameplay/views/finding/_form.php index e027832b8..1e9da7890 100644 --- a/backend/modules/gameplay/views/finding/_form.php +++ b/backend/modules/gameplay/views/finding/_form.php @@ -28,8 +28,8 @@ field($model, 'protocol')->dropDownList(['icmp' => 'ICMP', 'tcp' => 'TCP', 'udp' => 'UDP', ], ['prompt' => 'Choose the protocol of the finding']) ?> - field($model, 'target_id')->dropDownList(ArrayHelper::map(Target::find()->all(), 'id', function($model) { - return sprintf("(id:%d) %s/%s", $model['id'], $model['fqdn'], $model['ipoctet']);}), ['prompt'=>'Select the target'])->Label('Target') ?> + field($model, 'target_id')->dropDownList(ArrayHelper::map(Target::find()->orderBy(['fqdn'=>SORT_ASC])->all(), 'id', function($model) { + return sprintf("%s/%s", $model['fqdn'], $model['ipoctet']);}), ['prompt'=>'Select the target'])->Label('Target') ?> field($model, 'port')->textInput()->hint('The port where the service listens to (use 0 for icmp)') ?> From c508f899131aadca723d25516803edf42637aac1 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:04:27 +0300 Subject: [PATCH 07/16] fix typo on MailAction was `exceptions` instead of `exception` --- backend/modules/frontend/actions/player/MailAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/modules/frontend/actions/player/MailAction.php b/backend/modules/frontend/actions/player/MailAction.php index 11a2e5a82..5974134e6 100644 --- a/backend/modules/frontend/actions/player/MailAction.php +++ b/backend/modules/frontend/actions/player/MailAction.php @@ -46,7 +46,7 @@ public function run(int $id, $baseURL="https://echoctf.red/activate/") } catch(\Exception $e) { - \Yii::$app->getSession()->setFlash('error', Yii::t('app','Failed to mail player. {exception}',['exceptions'=>Html::encode($e->getMessage())])); + \Yii::$app->getSession()->setFlash('error', Yii::t('app','Failed to mail player. {exception}',['exception'=>Html::encode($e->getMessage())])); } } elseif($player->status==0) From a316b0ecd60a15d05032214e9c5f400e3a074292 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:05:33 +0300 Subject: [PATCH 08/16] add dns checking on settings form update MX validator to check MX records only --- frontend/models/forms/SettingsForm.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/models/forms/SettingsForm.php b/frontend/models/forms/SettingsForm.php index f10b69847..70796b511 100644 --- a/frontend/models/forms/SettingsForm.php +++ b/frontend/models/forms/SettingsForm.php @@ -66,6 +66,7 @@ public function rules() /* email field rules */ [['email'], 'trim'], + ['email', 'email','checkDNS'=>true], [['email'], 'string', 'max'=>255], [['email'], 'email'], ['email', 'unique', 'targetClass' => '\app\models\Player', 'message' => \Yii::t('app','This email has already been taken.'), 'when' => function($model, $attribute) { @@ -83,7 +84,7 @@ public function rules() $this->addError($attribute, \Yii::t('app','This email is banned.')); }], ['email', '\app\components\validators\StopForumSpamValidator', 'max'=>intval(Yii::$app->sys->signup_StopForumSpamValidator),'when' => function($model) { return Yii::$app->sys->signup_StopForumSpamValidator!==false;}], - ['email', '\app\components\validators\MXServersValidator', 'when' => function($model) { return Yii::$app->sys->signup_MXServersValidator!==false;}], + ['email', '\app\components\validators\MXServersValidator', 'mxonly'=>true, 'when' => function($model) { return Yii::$app->sys->signup_MXServersValidator!==false;}], /* username field rules */ From 9f5d326d062426e46afa6ea5c9ef10d974277000 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:06:34 +0300 Subject: [PATCH 09/16] ensure MX validator returns on error --- frontend/components/validators/MXServersValidator.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/components/validators/MXServersValidator.php b/frontend/components/validators/MXServersValidator.php index 426ae3bbd..e876f53fb 100644 --- a/frontend/components/validators/MXServersValidator.php +++ b/frontend/components/validators/MXServersValidator.php @@ -12,7 +12,7 @@ class MXServersValidator extends Validator public $range; public $banned_message="Sorry but you are using an email server that is banned!"; public $nxmessage="Sorry but you are using a domain that does not exist!"; - + public $mxonly=false; public function init() { parent::init(); @@ -30,7 +30,7 @@ public function validateValue($value) $value=$matches['domain']; } - if(getmxrr($value, $hosts)===false) + if(getmxrr($value, $hosts)===false && $this->mxonly===false) { return [$this->nxmessage, [ 'domain' => $value, @@ -49,21 +49,26 @@ public function validateValue($value) public function validateAttribute($model, $attribute) { $value = $model->$attribute; + $hosts=[]; // if not email assume value is a domain if (preg_match('/^(?P(?:"?([^"]*)"?\s)?)(?:\s+)?(?:(?P.+)@(?P[^>]+))(?P>?))$/i', $value, $matches)) { $value=$matches['domain']; } - if(!getmxrr($value, $hosts)) + if(getmxrr($value, $hosts)===false && $this->mxonly===false) { $model->addError($attribute, $this->nxmessage); + return; } foreach($this->range as $key) { if(array_search($key, $hosts)!==false) + { $model->addError($attribute, $this->banned_message); + return; + } } } } From 5e0dadf3de4753744044561f56f5d068f35455b7 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:07:32 +0300 Subject: [PATCH 10/16] improve checking of stopforumspamvalidator --- .../components/validators/StopForumSpamValidator.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/components/validators/StopForumSpamValidator.php b/frontend/components/validators/StopForumSpamValidator.php index d137abc16..6de6e0430 100644 --- a/frontend/components/validators/StopForumSpamValidator.php +++ b/frontend/components/validators/StopForumSpamValidator.php @@ -35,6 +35,7 @@ public function validateValue($value) curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 40); try { @@ -46,9 +47,10 @@ public function validateValue($value) } catch(\Exception $e) { - return [$this->message, [ - 'email' => $value, - ]]; + if(curl_errno($ch)===0) + return [$this->message, [ + 'email' => $value, + ]]; } } public function validateAttribute($model, $attribute) @@ -70,6 +72,7 @@ public function validateAttribute($model, $attribute) curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 40); try { @@ -81,6 +84,7 @@ public function validateAttribute($model, $attribute) } catch(\Exception $e) { + if(curl_errno($ch)===0) $model->addError($attribute, $this->message); } } From 62ed07cefa539d9bc6be35f6ad2791cadafad29d Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:07:59 +0300 Subject: [PATCH 11/16] MXonly on signup form for email validator --- frontend/models/forms/SignupForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/models/forms/SignupForm.php b/frontend/models/forms/SignupForm.php index e82955a52..e83023a5a 100644 --- a/frontend/models/forms/SignupForm.php +++ b/frontend/models/forms/SignupForm.php @@ -55,7 +55,7 @@ public function rules() ['username', '\app\components\validators\HourRegistrationValidator', 'client_ip'=>\Yii::$app->request->userIp, 'max'=>Yii::$app->sys->signup_HourRegistrationValidator,'when' => function($model) { return Yii::$app->sys->signup_HourRegistrationValidator!==false;}], ['username', '\app\components\validators\TotalRegistrationsValidator', 'client_ip'=>\Yii::$app->request->userIp, 'max'=>Yii::$app->sys->signup_TotalRegistrationsValidator,'when' => function($model) { return Yii::$app->sys->signup_TotalRegistrationsValidator!==false;}], ['email', '\app\components\validators\StopForumSpamValidator', 'max'=>Yii::$app->sys->signup_StopForumSpamValidator,'when' => function($model) { return Yii::$app->sys->signup_StopForumSpamValidator!==false;}], - ['email', '\app\components\validators\MXServersValidator', 'when' => function($model) { return Yii::$app->sys->signup_MXServersValidator!==false;}], + ['email', '\app\components\validators\MXServersValidator', 'mxonly'=>true, 'when' => function($model) { return Yii::$app->sys->signup_MXServersValidator!==false;}], //['email', '\app\components\validators\WhoisValidator', ], ['captcha', 'captcha'], From fd620e5af17f945d9c0ad18c9b0e434fb6a7841b Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:08:50 +0300 Subject: [PATCH 12/16] include all_vip on active sub check --- frontend/modules/subscription/Module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/modules/subscription/Module.php b/frontend/modules/subscription/Module.php index 0a2133025..8a07d0a2d 100644 --- a/frontend/modules/subscription/Module.php +++ b/frontend/modules/subscription/Module.php @@ -66,7 +66,7 @@ public function getExpires() public function getIsActive() { - if(intval(\app\modules\subscription\models\PlayerSubscription::find()->me()->active()->notExpired()->count())>0) + if(intval(\app\modules\subscription\models\PlayerSubscription::find()->me()->active()->notExpired()->count())>0 || \Yii::$app->sys->all_players_vip===true) { return true; } From c50f2c9f95c53520bedad8f0456f6d02486a10b4 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:09:15 +0300 Subject: [PATCH 13/16] group the last part of the check --- frontend/models/Player.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/models/Player.php b/frontend/models/Player.php index d13542188..84d3a6522 100644 --- a/frontend/models/Player.php +++ b/frontend/models/Player.php @@ -250,7 +250,7 @@ public function getIsAdmin():bool */ public function getIsVip():bool { - if($this->isAdmin || Yii::$app->sys->all_players_vip===true || $this->subscription!==null && $this->subscription->active>0) + if($this->isAdmin || Yii::$app->sys->all_players_vip===true || ($this->subscription!==null && $this->subscription->active>0)) return true; return false; } From 676acadcc8ac1b90d4c7fdd3b423da256e532cf2 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:10:08 +0300 Subject: [PATCH 14/16] cast int or else mailer complains --- backend/components/Mailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/components/Mailer.php b/backend/components/Mailer.php index dd76e2978..592da4970 100644 --- a/backend/components/Mailer.php +++ b/backend/components/Mailer.php @@ -19,7 +19,7 @@ public function init() if(Yii::$app->sys->mail_port !== false) { - $config['port']=Yii::$app->sys->mail_port; + $config['port']=intval(Yii::$app->sys->mail_port); } if(Yii::$app->sys->mail_username !== false) From 1ff9fdf7f0e9ecd3c94c0d28d6bce257d09097a7 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:10:28 +0300 Subject: [PATCH 15/16] hook the mx validator on backend also --- backend/modules/frontend/models/PlayerAR.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/modules/frontend/models/PlayerAR.php b/backend/modules/frontend/models/PlayerAR.php index ff55dcffe..be1a71e60 100644 --- a/backend/modules/frontend/models/PlayerAR.php +++ b/backend/modules/frontend/models/PlayerAR.php @@ -131,6 +131,9 @@ public function rules() if($this->{$attribute}!==null && $this->active===1 && $this->status=10) $this->addError($attribute, '{attribute} must be empty when player active.'); },'on'=>'validator'], + //['email', 'email','checkDNS'=>true,'on'=>'validator','message'=>'This domain does not resolve.'], + //['email', '\app\components\validators\StopForumSpamValidator', 'max'=>Yii::$app->sys->signup_StopForumSpamValidator,'when' => function($model) { return Yii::$app->sys->signup_StopForumSpamValidator!==false;},'on'=>'validator'], + ['email', '\app\components\validators\MXServersValidator', 'mxonly'=>true, 'when' => function($model) { return Yii::$app->sys->signup_MXServersValidator!==false;},'on'=>'validator'], ]; } From e563ec0206c32989a7b12812f8894ba30adcac56 Mon Sep 17 00:00:00 2001 From: Pantelis Roditis Date: Tue, 15 Aug 2023 20:10:43 +0300 Subject: [PATCH 16/16] bring the frontend validators to backend also --- .../validators/HourRegistrationValidator.php | 56 ++++++++++++ .../validators/LowerRangeValidator copy.php | 70 ++++++++++++++ .../validators/MXServersValidator.php | 74 +++++++++++++++ .../validators/StopForumSpamValidator.php | 91 +++++++++++++++++++ .../TotalRegistrationsValidator.php | 56 ++++++++++++ .../components/validators/WhoisValidator.php | 47 ++++++++++ 6 files changed, 394 insertions(+) create mode 100644 backend/components/validators/HourRegistrationValidator.php create mode 100644 backend/components/validators/LowerRangeValidator copy.php create mode 100644 backend/components/validators/MXServersValidator.php create mode 100644 backend/components/validators/StopForumSpamValidator.php create mode 100644 backend/components/validators/TotalRegistrationsValidator.php create mode 100644 backend/components/validators/WhoisValidator.php diff --git a/backend/components/validators/HourRegistrationValidator.php b/backend/components/validators/HourRegistrationValidator.php new file mode 100644 index 000000000..052381ca0 --- /dev/null +++ b/backend/components/validators/HourRegistrationValidator.php @@ -0,0 +1,56 @@ +message=\Yii::t('app',"You reached your maximum registrations for this hour!"); + if(!$this->counter) + $this->counter=intval(\Yii::$app->cache->memcache->get('registeredip:'.$this->client_ip)); + parent::init(); + } + public function validateValue($value) + { + if (\Yii::$app->sys->signup_HourRegistrationValidator!==false && intval($this->counter)>=$this->max) + { + return [$this->message, [ + 'signup_ip' => $value, + ]]; + } + + } + public function validateAttribute($model, $attribute) + { + $value = $model->$attribute; + if(\Yii::$app->sys->signup_HourRegistrationValidator!==false && intval($this->counter)>=$this->max) + { + $model->addError($attribute, $this->message); + } + } + + public function clientValidateAttribute($model, $attribute, $view) + { + if(\Yii::$app->sys->signup_HourRegistrationValidator!==false) + { + $message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + return <<counter}>={$this->max}) { + messages.push($message); + return false; +} +JS; + + } + } +} diff --git a/backend/components/validators/LowerRangeValidator copy.php b/backend/components/validators/LowerRangeValidator copy.php new file mode 100644 index 000000000..6d4ea6f82 --- /dev/null +++ b/backend/components/validators/LowerRangeValidator copy.php @@ -0,0 +1,70 @@ + + * @since 2.0 + */ +class LowerRangeValidator extends \yii\validators\RangeValidator +{ + /** + * @var array|\Traversable|\Closure $range + */ + public $range; + /** + * @var bool whether the comparison is strict (both type and value must be the same) + */ + public $strict=false; + /** + * @var bool whether to invert the validation logic. Defaults to false. If set to true, + * the attribute value should NOT be among the list of values defined via [[range]]. + */ + public $not=false; + /** + * @var bool whether to allow array type attribute. + */ + public $allowArray=false; + + + /** + * {@inheritdoc} + */ + public function init() + { + parent::init(); + if($this->message === null) + { + $this->message=Yii::t('yii', '{attribute} is invalid.'); + } + } + + /** + * {@inheritdoc} + */ + protected function validateValue($value) + { + $in=false; + + if(ArrayHelper::isIn(mb_strtolower($value), (array) $this->range, $this->strict)) + { + $in=true; + } + return $this->not !== $in ? null : [$this->message, []]; + } +} diff --git a/backend/components/validators/MXServersValidator.php b/backend/components/validators/MXServersValidator.php new file mode 100644 index 000000000..e876f53fb --- /dev/null +++ b/backend/components/validators/MXServersValidator.php @@ -0,0 +1,74 @@ +range) + { + $this->range=ArrayHelper::getColumn(\app\modelscli\BannedMxServer::find()->select('name')->asArray()->all(),'name'); + } + } + + public function validateValue($value) + { + // if not email assume value is a domain + if (preg_match('/^(?P(?:"?([^"]*)"?\s)?)(?:\s+)?(?:(?P.+)@(?P[^>]+))(?P>?))$/i', $value, $matches)) + { + $value=$matches['domain']; + } + + if(getmxrr($value, $hosts)===false && $this->mxonly===false) + { + return [$this->nxmessage, [ + 'domain' => $value, + ]]; + } + + foreach($this->range as $key) + { + if(array_search($key, $hosts)!==false) + return [$this->banned_message, [ + 'domain' => $value, + ]]; + } + } + + public function validateAttribute($model, $attribute) + { + $value = $model->$attribute; + $hosts=[]; + // if not email assume value is a domain + if (preg_match('/^(?P(?:"?([^"]*)"?\s)?)(?:\s+)?(?:(?P.+)@(?P[^>]+))(?P>?))$/i', $value, $matches)) + { + $value=$matches['domain']; + } + + if(getmxrr($value, $hosts)===false && $this->mxonly===false) + { + $model->addError($attribute, $this->nxmessage); + return; + } + + foreach($this->range as $key) + { + if(array_search($key, $hosts)!==false) + { + $model->addError($attribute, $this->banned_message); + return; + } + } + } +} diff --git a/backend/components/validators/StopForumSpamValidator.php b/backend/components/validators/StopForumSpamValidator.php new file mode 100644 index 000000000..6de6e0430 --- /dev/null +++ b/backend/components/validators/StopForumSpamValidator.php @@ -0,0 +1,91 @@ +sys->signup_StopForumSpamValidator===false) + return; + $data = array( + 'email' => $value, + 'json'=>'', + 'confidence'=>'80', + ); + + $data = http_build_query($data); + + // init the request, set some info, send it and finally close it + $ch = curl_init($this->url); + + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 40); + + try + { + $result = curl_exec($ch); + curl_close($ch); + $retData=json_decode($result)->email; + if(property_exists($retData,'confidence') && $retData->confidence>$this->max) + throw new \yii\base\UserException('StopForumSpamValidator null'); + } + catch(\Exception $e) + { + if(curl_errno($ch)===0) + return [$this->message, [ + 'email' => $value, + ]]; + } + } + public function validateAttribute($model, $attribute) + { + if(\Yii::$app->sys->signup_StopForumSpamValidator===false) + return; + $value = $model->$attribute; + $data = array( + 'email' => $value, + 'json'=>'', + 'confidence'=>'', + ); + + $data = http_build_query($data); + + // init the request, set some info, send it and finally close it + $ch = curl_init($this->url); + + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 40); + + try + { + $result = curl_exec($ch); + curl_close($ch); + $retData=json_decode($result)->email; + if(property_exists($retData,'confidence') && $retData->confidence>$this->max) + throw new \yii\base\UserException('StopForumSpamValidator null'); + } + catch(\Exception $e) + { + if(curl_errno($ch)===0) + $model->addError($attribute, $this->message); + } + } +} diff --git a/backend/components/validators/TotalRegistrationsValidator.php b/backend/components/validators/TotalRegistrationsValidator.php new file mode 100644 index 000000000..58c8e5de3 --- /dev/null +++ b/backend/components/validators/TotalRegistrationsValidator.php @@ -0,0 +1,56 @@ +counter) + $this->counter=\Yii::$app->db + ->createCommand('SELECT count(*) FROM player_last WHERE signup_ip=:player_ip') + ->bindValue(':player_ip',ip2long($this->client_ip)) + ->queryScalar(); + parent::init(); + } + public function validateValue($value) + { + if (\Yii::$app->sys->signup_TotalRegistrationsValidator!==false && intval($this->counter)>=$this->max) + { + return [$this->message, [ + 'username' => $value, + ]]; + } + } + public function validateAttribute($model, $attribute) + { + $value = $model->$attribute; + if (\Yii::$app->sys->signup_TotalRegistrationsValidator!==false && intval($this->counter)>=$this->max) + { + $model->addError($attribute, $this->message); + } + } + + public function clientValidateAttribute($model, $attribute, $view) + { + if(\Yii::$app->sys->signup_TotalRegistrationsValidator!==false) + { + $message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + return <<counter}>={$this->max}) { + messages.push($message); + return false; +} +JS; + } + } +} diff --git a/backend/components/validators/WhoisValidator.php b/backend/components/validators/WhoisValidator.php new file mode 100644 index 000000000..2cbe0ff58 --- /dev/null +++ b/backend/components/validators/WhoisValidator.php @@ -0,0 +1,47 @@ +(?:"?([^"]*)"?\s)?)(?:\s+)?(?:(?P.+)@(?P[^>]+))(?P>?))$/i', $value, $matches)) + { + $value=$matches['domain']; + } + $domain = new \overals\whois\Whois($value); + if ($domain->isAvailable()) + { + return [$this->message, [ + 'username' => $value, + ]]; + } + } + public function validateAttribute($model, $attribute) + { + $value = $model->$attribute; + if (preg_match('/^(?P(?:"?([^"]*)"?\s)?)(?:\s+)?(?:(?P.+)@(?P[^>]+))(?P>?))$/i', $value, $matches)) + { + $value=$matches['domain']; + } + $domain = new \overals\whois\Whois($matches['domain']); + if ($domain->isAvailable()) + { + $model->addError($attribute, $this->message); + } + } + +}