diff --git a/ansible/playbooks/feed-targets.yml b/ansible/playbooks/feed-targets.yml index 728497b36..ac5d75949 100644 --- a/ansible/playbooks/feed-targets.yml +++ b/ansible/playbooks/feed-targets.yml @@ -70,6 +70,7 @@ scheduled_at: "{{ scheduled_at|default(omit) }}" # scheduled_at: "{{scheduled_at| default('%Y-%m-%d 00:00:00' | strftime( ( ansible_date_time.epoch | int ) ) ) }}" image: '{{DOCKER_REGISTRY}}/{{DOCKER_REPOSITORY}}/{{container.image | lower}}:{{container.tag|default("latest")}}' + weight: '{{weight|default(0)}}' status_code: 201 # Add network if defined diff --git a/ansible/runonce/docker-registry.yml b/ansible/runonce/docker-registry.yml index 14c97f738..bd5a6e7f0 100755 --- a/ansible/runonce/docker-registry.yml +++ b/ansible/runonce/docker-registry.yml @@ -60,13 +60,20 @@ tags: create_users - name: Clean registry distribution - command: rm -rf distribution + command: rm -rf /root/distribution - name: Get registry distribution command: git clone https://github.com/distribution/distribution.git environment: GOPATH: "{{registry.home}}/go" + - name: Checkout working hash for distribution + command: git checkout 90939f1173f65356e724f398793b4d7239a49595 + args: + chdir: /root/distribution + environment: + GOPATH: "{{registry.home}}/go" + - name: Build registry command: go build main.go args: diff --git a/ansible/runonce/docker-servers.yml b/ansible/runonce/docker-servers.yml index cd1d2fa96..76868fc3b 100644 --- a/ansible/runonce/docker-servers.yml +++ b/ansible/runonce/docker-servers.yml @@ -35,6 +35,12 @@ hostname: name: "{{fqdn}}" + - name: Configure hosts + copy: + content: "{{etchosts}}\n" + dest: /etc/hosts + when: etchosts is defined + - name: Configure resolv.conf copy: content: "{{resolvconf}}\n" @@ -164,6 +170,14 @@ tags: - interfaces + - name: Remove DHCP from interfaces + ansible.builtin.lineinfile: + path: /etc/network/interfaces + state: absent + regexp: '^iface {{network.driver_options.parent}} inet dhcp' + tags: + - interfaces + - name: Copy Dockerfiles data folder structure when: SYNC_DOCKERFILES is defined and SYNC_DOCKERFILES synchronize: @@ -221,11 +235,14 @@ daemon_reload: true name: docker - - name: Check if docker network exists - command: docker network ls -qf name={{network.name}} - register: netresult - changed_when: false - when: network is defined + - name: Remove docker network if exists + command: docker network rm -f {{network.name}} + +# - name: Check if docker network exists +# command: docker network ls -qf name={{network.name}} +# register: netresult +# changed_when: false +# when: network is defined - name: Create docker network if needed docker_network: @@ -234,7 +251,7 @@ driver: "{{network.driver}}" driver_options: "{{network.driver_options}}" ipam_config: "{{network.ipam_options}}" - when: network is defined and netresult is defined and netresult.stdout == "" + when: network is defined - name: Force removal of existing containers when: containers is defined diff --git a/ansible/runonce/mui.yml b/ansible/runonce/mui.yml index 0d9dd4486..e584fc00e 100644 --- a/ansible/runonce/mui.yml +++ b/ansible/runonce/mui.yml @@ -46,7 +46,7 @@ libc: 96.0 libutil: 15.0 libcrypto: 46.2 - ICU_MAJOR: 73 + ICU_MAJOR: 74 ICU_MINOR: 2 sysctl: kern.bufcachepercent: 30 @@ -454,7 +454,7 @@ when: GITHUB_OAUTH_TOKEN is defined and GITHUB_OAUTH_TOKEN!="" - name: run composer - command: chdir=/home/moderatorUI/{{domain_name}}/backend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress --no-suggest + command: chdir=/home/moderatorUI/{{domain_name}}/backend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress --no-suggest --ignore-platform-reqs - name: Fix home folder permissions for nginx command: chown root.daemon /home/moderatorUI diff --git a/ansible/runonce/pui.yml b/ansible/runonce/pui.yml index bc274101e..65130bc77 100644 --- a/ansible/runonce/pui.yml +++ b/ansible/runonce/pui.yml @@ -474,7 +474,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 + 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 --ignore-platform-reqs - name: Fix home folder permissions for nginx command: chown root.daemon /home/participantUI diff --git a/ansible/runonce/vpngw.yml b/ansible/runonce/vpngw.yml index 2dcab87c2..7843b2826 100644 --- a/ansible/runonce/vpngw.yml +++ b/ansible/runonce/vpngw.yml @@ -8,11 +8,11 @@ vars_prompt: - name: "myname" prompt: "1/16. System hostname?" - default: "vpn.offensivex.net" + default: "vpn.example.com" private: no - name: "vpngw" prompt: "2/16. OpenVPN gateway hostname or IP?" - default: "vpn.offensivex.net" + default: "vpn.example.com" private: no - name: "egress_if" prompt: "3/16. Egress network interface (ifconfig egress)?" @@ -194,7 +194,7 @@ APP_DIR: "{{playbook_dir}}/../../" - name: Install packages - shell: "pkg_add {{packages| join(' ')}}" + shell: "pkg_add -I {{packages| join(' ')}}" - name: Configure PS1 for root and skeleton lineinfile: @@ -304,13 +304,13 @@ force: yes depth: 1 - - name: Clone openvpn-updown repo - git: - repo: 'https://github.com/echoCTF/openvpn-updown.git' - dest: /usr/src/openvpn-updown - clone: yes - force: yes - depth: 1 +# - name: Clone openvpn-updown repo +# git: +# repo: 'https://github.com/echoCTF/openvpn-updown.git' +# dest: /usr/src/openvpn-updown +# clone: yes +# force: yes +# depth: 1 - name: Clone findingsd repo @@ -340,10 +340,10 @@ - "install -c -s -o root -g bin -m 555 heartbeatd /usr/local/sbin/heartbeatd" - "install -c -o root -g wheel -m 555 heartbeatd.rc /etc/rc.d/heartbeatd" - - name: make install openvpn-updown - shell: GOOS=openbsd CGO_ENABLED=0 go build -a -ldflags '-s -w -extldflags "-static"' -o /etc/openvpn/openvpn-updown /usr/src/openvpn-updown - args: - chdir: /usr/src/openvpn-updown +# - name: make install openvpn-updown +# shell: GOOS=openbsd CGO_ENABLED=0 go build -a -ldflags '-s -w -extldflags "-static"' -o /etc/openvpn/openvpn-updown /usr/src/openvpn-updown +# args: +# chdir: /usr/src/openvpn-updown - name: make install memcached udf shell: AUTOCONF_VERSION=2.69 AUTOMAKE_VERSION=1.16 make all install @@ -412,7 +412,7 @@ when: GITHUB_OAUTH_TOKEN is defined and GITHUB_OAUTH_TOKEN != "randomtoken" and GITHUB_OAUTH_TOKEN!="" - name: run composer - command: chdir={{APP_DIR}}/backend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress + command: chdir={{APP_DIR}}/backend php -d allow_url_fopen=on /usr/local/bin/composer install -n --no-dev --prefer-dist --no-progress --ignore-platform-reqs - name: "Prepare empty interfaces (pflog0, pflog1...)" copy: diff --git a/backend/commands/SslController.php b/backend/commands/SslController.php index f10c3636e..1bf96f8ad 100644 --- a/backend/commands/SslController.php +++ b/backend/commands/SslController.php @@ -246,15 +246,21 @@ public function actionCreateCrl() public function actionGenerateCrl($clean=false) { $CERTS=Crl::find()->all(); + $folder=\Yii::getAlias('@appconfig/revoke'); + if(file_exists($folder)!==true) + { + mkdir($folder); + } + foreach($CERTS as $cert) { try { - $tmpcrt=tempnam('/tmp', 'crt'); + $tmpcrt=tempnam($folder, 'crt'); file_put_contents($tmpcrt, $cert->crt); $cmd=sprintf("openssl ca -revoke %s %s ", $tmpcrt, $this->ssl_params); shell_exec($cmd); - unlink($tmpcrt); + //unlink($tmpcrt); if($clean!==false) $cert->delete(); } catch(\Exception $e) diff --git a/backend/modules/content/views/default/menu_items.php b/backend/modules/content/views/default/menu_items.php index ff02926a1..1c5b73339 100644 --- a/backend/modules/content/views/default/menu_items.php +++ b/backend/modules/content/views/default/menu_items.php @@ -28,6 +28,7 @@ val) foreach(json_decode($model->val,true) as $i => $item) { echo '
'; echo '
',Html::label('Link name', "item[$i][name]", ['class' => 'label name']); diff --git a/backend/modules/frontend/controllers/ProfileController.php b/backend/modules/frontend/controllers/ProfileController.php index 65873972d..d1ec48c82 100644 --- a/backend/modules/frontend/controllers/ProfileController.php +++ b/backend/modules/frontend/controllers/ProfileController.php @@ -26,7 +26,18 @@ class ProfileController extends \app\components\BaseController */ public function behaviors() { - return ArrayHelper::merge(parent::behaviors(), [ + return ArrayHelper::merge( + [ + 'access' => [ + 'class' => \yii\filters\AccessControl::class, + 'rules' => [ + '00filtered-actions'=>[ + 'actions' => ['view-full','target-progress','score-monthly','headshots','vpn-history','spin-history','notifications'], + 'allow' => true, + 'roles' => ['@'], + ] + ], + ], 'verbs' => [ 'class' => VerbFilter::class, 'actions' => [ @@ -36,7 +47,7 @@ public function behaviors() 'reset-key' => ['POST'], ], ], - ]); + ],parent::behaviors()); } /** diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php index 2481dd220..cb35b2bf9 100644 --- a/backend/views/layouts/main.php +++ b/backend/views/layouts/main.php @@ -128,7 +128,7 @@ ], [ - 'label' => ' SmartCity', 'url' => ['/smartcity/default/index'], 'visible' => !Yii::$app->user->isGuest, 'active' => Yii::$app->controller->module->id == 'smartcity', + 'label' => ' SmartCity', 'url' => ['/smartcity/default/index'], 'visible' => !Yii::$app->user->isGuest && !Yii::$app->sys->module_smartcity_disabled, 'active' => Yii::$app->controller->module->id == 'smartcity', 'items' => [ ['label' => 'Infrastructure', 'url' => ['/smartcity/infrastructure/index'], 'visible' => !Yii::$app->user->isGuest,], ['label' => 'Infrastructure Targets', 'url' => ['/smartcity/infrastructure-target/index'], 'visible' => !Yii::$app->user->isGuest,], diff --git a/contrib/init.sh b/contrib/init.sh index 70f9b94d3..785a01064 100755 --- a/contrib/init.sh +++ b/contrib/init.sh @@ -24,8 +24,8 @@ function settings() { function services() { sudo service memcached restart sudo service mysql restart + sed -e "s/echoCTF/${DATABASE}/" contrib/mysql-init.sql | mysql ${DATABASE} > /dev/null mysql ${DATABASE} -e "SET GLOBAL EVENT_SCHEDULER=ON" - mysql ${DATABASE} < contrib/mysql-init.sql > /dev/null } function sql() { @@ -108,7 +108,7 @@ function tmuxs() { function eventOrganizers() { - #./backend/yii player/register "organizer" "organizer@example.com" "organizer" "organizer" offense 0 "" "CTF ORGANIZERS" + ./backend/yii player/register "organizer" "organizer@example.com" "organizer" "organizer" offense 0 "" "CTF ORGANIZERS" } function sampleData() diff --git a/docs/Sysconfig-Keys.md b/docs/Sysconfig-Keys.md index f194729e1..54be46e44 100644 --- a/docs/Sysconfig-Keys.md +++ b/docs/Sysconfig-Keys.md @@ -23,7 +23,7 @@ * `require_activation` Whether it is required for users to activate their accounts * `disable_registration` Whether online registrations are allowed * `team_visible_instances` Whether or not player instances are visible to the rest of the team by default otherwise the per-instance field `team_allowed` takes priority -* `guest_visible_leaderboards` Whether or not the leaderboards will be visible to guest users (this still respects the event start/end restrictions) +* `guest_visible_leaderboards` Whether or not the leaderboard will be visible to guest users (this still respects the event start/end restrictions) * `hide_timezone` Whether or not the Timezone information should be visible * `profile_discord`: Whether the field will be visible under the player profile page. This is different than `profile_settings_fields` @@ -34,7 +34,7 @@ * `profile_twitch`: Whether the field will be visible under the player profile page. This is different than `profile_settings_fields` * `profile_youtube`: Whether the field will be visible under the player profile page. This is different than `profile_settings_fields` -* `writeup_rankings`: Whether or not writeup rankings will be visible on leaderboards +* `writeup_rankings`: Whether or not writeup rankings will be visible on leaderboard * `country_rankings`: Whether or not country rankings will be visible on leaderboard * `player_point_rankings`: Whether or not player point rankings will be visible on leaderboard * `player_monthly_rankings`: Whether or not player monthly rankings will be visible on leaderboard diff --git a/docs/console-commands/Vpn.md b/docs/console-commands/Vpn.md index 61732aa2a..baafb622c 100644 --- a/docs/console-commands/Vpn.md +++ b/docs/console-commands/Vpn.md @@ -44,10 +44,10 @@ Logout all players from the database. It **does NOT** issue an OpenVPN kill comm ## save Save an OpenVPN instance configuration file with data from the database -Usage: `./backend/yii vpn/save ` +Usage: `./backend/yii vpn/save [server]` The command looks for a record with the following criteria: -* uses the current system `hostname` as a `server` +* uses the current system `hostname` as a `server` if a server parameter was not provided * uses the filename (basename) from the openvpn configuration file provided as cli argument ## status diff --git a/frontend/models/PlayerAR.php b/frontend/models/PlayerAR.php index 84b8b054b..56d671b5b 100644 --- a/frontend/models/PlayerAR.php +++ b/frontend/models/PlayerAR.php @@ -31,6 +31,7 @@ * @property PlayerSsl $playerSsl * @property TargetInstance $instance * @property Subscription $subscription + * @property Metadata $metadata */ class PlayerAR extends ActiveRecord { @@ -262,4 +263,9 @@ public function getSSL() return $this->hasOne(PlayerSsl::class, ['player_id' => 'id']); } + public function getMetadata() + { + return $this->hasOne(PlayerMetadata::class, ['player_id' => 'id']); + } + } diff --git a/frontend/models/PlayerMetadata.php b/frontend/models/PlayerMetadata.php new file mode 100644 index 000000000..86ef999a4 --- /dev/null +++ b/frontend/models/PlayerMetadata.php @@ -0,0 +1,67 @@ + 64], + [['player_id'], 'exist', 'skipOnError' => true, 'targetClass' => Player::class, 'targetAttribute' => ['player_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'player_id' => Yii::t('app', 'Player ID'), + 'identificationFile' => Yii::t('app', 'Identification File'), + 'affiliation' => Yii::t('app', 'Affiliation'), + ]; + } + + /** + * Gets query for [[Player]]. + * + * @return \yii\db\ActiveQuery|yii\db\ActiveQuery + */ + public function getPlayer() + { + return $this->hasOne(Player::class, ['id' => 'player_id']); + } + + /** + * {@inheritdoc} + * @return PlayerMetadataQuery the active query used by this AR class. + */ + public static function find() + { + return new PlayerMetadataQuery(get_called_class()); + } +} diff --git a/frontend/models/PlayerMetadataQuery.php b/frontend/models/PlayerMetadataQuery.php new file mode 100644 index 000000000..21d9f4c61 --- /dev/null +++ b/frontend/models/PlayerMetadataQuery.php @@ -0,0 +1,34 @@ +andWhere('[[status]]=1'); + }*/ + + /** + * {@inheritdoc} + * @return PlayerMetadata[]|array + */ + public function all($db = null) + { + return parent::all($db); + } + + /** + * {@inheritdoc} + * @return PlayerMetadata|array|null + */ + public function one($db = null) + { + return parent::one($db); + } +} diff --git a/frontend/models/PlayerMetadataSearch.php b/frontend/models/PlayerMetadataSearch.php new file mode 100644 index 000000000..0c53a1ce4 --- /dev/null +++ b/frontend/models/PlayerMetadataSearch.php @@ -0,0 +1,83 @@ +joinWith(['player']); + + // add conditions that should always apply here + + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'player_id' => $this->player_id, + ]); + + $query->andFilterWhere(['like', 'identificationFile', $this->identificationFile]) + ->andFilterWhere(['like', 'player.username', $this->username]) + ->andFilterWhere(['like', 'affiliation', $this->affiliation]); + + $dataProvider->setSort([ + 'attributes' => array_merge( + $dataProvider->getSort()->attributes, + [ + 'username' => [ + 'asc' => ['player.username' => SORT_ASC], + 'desc' => ['player.username' => SORT_DESC], + ], + ] + ), + ]); + + return $dataProvider; + } +} diff --git a/frontend/widgets/Card.php b/frontend/widgets/Card.php index 0e014fe0a..1dded9de9 100644 --- a/frontend/widgets/Card.php +++ b/frontend/widgets/Card.php @@ -151,7 +151,7 @@ public function getImgtop() */ public function getHeadericon() { - if(str_contains($this->type,'card-stats')!==true) + if(strpos($this->type,'card-stats')===false) return '
'.$this->icon.'