PluginProbe
WebTotem Security / 2.4.19
WebTotem Security v2.4.19
3.0.2 3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 All 110 releases
wt-security / lib / Option.php

Option.php in WebTotem Security 2.4.19, at lib/Option.php

732 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
4 if (!headers_sent()) {
5 header('HTTP/1.1 403 Forbidden');
6 }
7 exit(1);
8 }
9
10 /**
11 * WebTotem Option class.
12 */
13 class WebTotemOption {
14
15 /**
16 * Get config option.
17 *
18 * @param string $option
19 * Option name.
20 *
21 * @return mixed
22 * Returns saved data by option name.
23 */
24 public static function getOption($option) {
25 $data = WebTotemDB::getData([ 'name' => $option ],'settings');
26 return (array_key_exists('value', $data)) ? $data['value'] : '';
27 }
28
29 /**
30 * Save multiple configuration options.
31 *
32 * @param array $options
33 * Array of data, key is name of option.
34 *
35 * @return bool
36 * Returns TRUE after setting the options.
37 */
38 public static function setOptions(array $options) {
39
40 foreach ($options as $option => $value) {
41 $value = is_array($value) ? json_encode($value) : $value;
42 WebTotemDB::setData(['name' => $option, 'value' => $value,], 'settings', ['name' => $option]);
43 }
44
45 return TRUE;
46 }
47
48 /**
49 * Clear multiple configuration options.
50 *
51 * @param array $options
52 * Array of data, key is name of option.
53 *
54 * @return bool
55 * Returns TRUE after clearing the options.
56 */
57 public static function clearOptions(array $options) {
58
59 foreach ($options as $option) {
60 WebTotemDB::deleteData([ 'name' => $option ], 'settings');
61 }
62
63 return TRUE;
64 }
65
66 /**
67 * Save multiple some options to session.
68 *
69 * @param array $options
70 * Array of data, key is name of option.
71 *
72 * @return bool
73 * Returns TRUE after setting the session options.
74 */
75 public static function setSessionOptions(array $options) {
76
77 $sessions = json_decode(self::getOption('sessions'), true) ?: [];
78 $user_id = get_current_user_id();
79
80 foreach ($options as $option => $value){
81 $sessions[$user_id][$option] = $value;
82 }
83
84 self::setOptions(['sessions' => $sessions]);
85
86 return TRUE;
87 }
88
89 /**
90 * Get option from session.
91 *
92 * @param string $option
93 * Option name.
94 *
95 * @return mixed
96 * Returns saved data by option name.
97 */
98 public static function getSessionOption($option) {
99
100 $sessions = json_decode(self::getOption('sessions'), true) ?: [];
101 $user_id = get_current_user_id();
102
103 if(array_key_exists($user_id, $sessions) and array_key_exists($option, $sessions[$user_id])){
104 return $sessions[$user_id][$option];
105 } else {
106 return [];
107 }
108
109 }
110
111 /**
112 * Save multiple some plugin settings.
113 *
114 * @param array $options
115 * Array of data, key is name of option.
116 *
117 * @return bool
118 * Returns TRUE after save settings.
119 */
120 public static function setPluginSettings(array $options) {
121
122 $settings = json_decode(self::getOption('settings'), true) ?: [];
123
124 foreach ($options as $option => $value){
125 $settings[$option] = $value;
126 }
127
128 self::setOptions(['settings' => $settings]);
129
130 return TRUE;
131 }
132
133 /**
134 * Get plugin settings.
135 *
136 * @param string $option
137 * Option name.
138 *
139 * @return mixed
140 * Returns saved data by option name.
141 */
142 public static function getPluginSettings($option = null) {
143
144 $settings = json_decode(self::getOption('settings'), true) ?: [];
145
146 if($option){
147 if(array_key_exists($option, $settings)){
148 return $settings[$option];
149 } else {
150 return [];
151 }
152 } else{
153 return $settings;
154 }
155 }
156
157
158 /**
159 * Check has reCaptcha enabled.
160 *
161 * @return bool
162 * Returns TRUE if reCaptcha enabled.
163 */
164 public static function reCaptchaEnabled() {
165 return self::getPluginSettings('recaptcha') ?: false;
166 }
167
168
169 /**
170 * Save authentication token and token expiration dates in settings.
171 *
172 * @param array $params
173 * Parameters for authorization.
174 *
175 * @return string
176 * Returns TRUE after setting the options.
177 */
178 public static function login(array $params) {
179 $token_expired = time() + $params['token']['expiresIn'] - 60;
180
181 self::setOptions([
182 'activated' => TRUE,
183 'auth_token_expired' => $token_expired,
184 'auth_token' => $params['token']['value'],
185 'api_key' => $params['api_key'],
186 'multisite_options' => WebTotem::isMultiSite()
187 ]);
188
189 return TRUE;
190 }
191
192 /**
193 * Checks whether the user has activated the plugin using the API key.
194 *
195 * @return bool
196 * Returns the module activation status.
197 */
198 public static function isActivated() {
199 return (boolean) self::getOption('activated');
200 }
201
202 /**
203 * Remove module settings.
204 *
205 * @return string
206 * Returns TRUE after clearing the options.
207 */
208 public static function logout() {
209
210 self::clearOptions([
211 'activated',
212 'auth_token_expired',
213 'auth_token',
214 'api_key',
215 'api_url',
216 'host_id',
217 'host_name',
218 ]);
219 return TRUE;
220 }
221
222 /**
223 * Set notification.
224 *
225 * @param string $type
226 * Notification Type.
227 * @param string $notice
228 * Notification Text.
229 */
230 public static function setNotification($type, $notice) {
231 $notifications = self::getSessionOption('notifications') ?: [];
232
233 if (array_key_exists($type, $notifications)) {
234 if (!in_array($notice, $notifications[$type])) {
235 $notifications[$type][] = $notice;
236 self::setSessionOptions(['notifications' => $notifications]);
237 }
238 }
239 else {
240 $notifications[$type][] = $notice;
241 self::setSessionOptions(['notifications' => $notifications]);
242 }
243
244 }
245
246 /**
247 * Get notifications.
248 *
249 * @return array
250 * Notifications array.
251 */
252 public static function getNotificationsData() {
253 $types = ['error', 'info', 'warning', 'success'];
254
255 $notifications = self::getSessionOption('notifications') ?: [];
256 $result = [];
257
258 foreach ($types as $type) {
259 if (array_key_exists($type, $notifications)) {
260 foreach ($notifications[$type] as $notification) {
261 $result[] = ['type' => $type, 'notice' => $notification];
262 }
263 }
264 }
265
266 // Remove notifications.
267 self::setSessionOptions(['notifications' => []]);
268
269 return $result;
270 }
271
272 /**
273 * Set host data.
274 *
275 * @return void
276 */
277 public static function setHost($host_name, $host_id) {
278
279 if(WebTotem::isMultiSite()){
280 $blog_id = self::getBlogId($host_name);
281
282 add_blog_option($blog_id, 'wtotem_host_id', $host_id);
283 add_blog_option($blog_id, 'wtotem_host_name', $host_name);
284
285 if(!is_main_site($blog_id)){
286 $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
287 $all_hosts[$host_name] = $host_id;
288
289 self::setOptions([
290 'all_hosts' => $all_hosts,
291 ]);
292 }
293
294 }
295 else {
296 self::setOptions([
297 'host_id' => $host_id,
298 'host_name' => $host_name,
299 ]);
300 }
301 }
302
303 /**
304 * Get host data.
305 *
306 * @param string $hid
307 * Host id.
308 *
309 * @return array
310 * Host data.
311 */
312 public static function getHost($hid = false) {
313
314 if ( $hid ) {
315 $all_hosts = self::getAllHosts() ?: [];
316 if ( $all_hosts and in_array( $hid, $all_hosts ) ) {
317 return [
318 'id' => $hid,
319 'name' => array_search( $hid, $all_hosts ),
320 ];
321 }
322 }
323
324 return self::getMainHost();
325 }
326
327 /**
328 * Get host data.
329 *
330 * @return array
331 * Host data.
332 */
333 public static function getAllHosts() {
334 $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
335
336 $main_host = self::getMainHost();
337 $all_hosts = ($main_host['id']) ? [$main_host['name'] => $main_host['id']] + $all_hosts : $all_hosts;
338
339 return $all_hosts;
340 }
341
342 /**
343 * Get main host data.
344 *
345 * @return array
346 * Main host data.
347 */
348 public static function getMainHost() {
349
350 if(WebTotem::isMultiSite()){
351 return [
352 'id' => get_blog_option(0, 'wtotem_host_id'),
353 'name' => get_blog_option(0, 'wtotem_host_name'),
354 ];
355 } else{
356 return [
357 'id' => self::getOption('host_id'),
358 'name' => self::getOption('host_name'),
359 ];
360 }
361
362 }
363
364 /**
365 * Delete host data from DB.
366 *
367 * @return void
368 */
369 public static function clearAllHosts() {
370
371 $data = WebTotemAPI::getSites();
372 foreach ($data['edges'] as $site) {
373 $site = $site['node'];
374 $blog_id = self::getBlogId($site['hostname']);
375 delete_blog_option($blog_id, 'wtotem_host_id');
376 delete_blog_option($blog_id, 'wtotem_host_name');
377 }
378
379 }
380
381 /**
382 * Get an array of new sites.
383 *
384 * @return array
385 * Returns either an empty array or an array with new sites.
386 */
387 // public static function checkNewSites() {
388 // $hosts = self::getAllHosts();
389 // $sites = get_sites();
390 // $new_sites = [];
391 //
392 // foreach ($sites as $site){
393 // $host_name = untrailingslashit($site->domain . $site->path);
394 // if(!array_key_exists($host_name, $hosts) and !array_key_exists('www.' . $host_name, $hosts)) {
395 // $new_sites[] = $host_name;
396 // }
397 // }
398 // return $new_sites;
399 // }
400
401 /**
402 * Get host id from host name.
403 *
404 * @param $host_name
405 * Host name.
406 *
407 * @return integer
408 * Blog id.
409 */
410 public static function getBlogId($host_name){
411 $local_sites = get_sites();
412
413 foreach ($local_sites as $site){
414 $domain = untrailingslashit($site->domain . $site->path);
415 if($host_name == $domain){
416 return $site->blog_id;
417 }
418 }
419 return 0;
420 }
421
422 /**
423 * Get all config options name.
424 *
425 * @return array
426 * Returns saved data by option name.
427 */
428 public static function getAllOptions() {
429 return [
430 'api_key',
431 'activated',
432 'auth_token_expired',
433 'auth_token',
434 'am_file',
435 'waf_file',
436 'av_file',
437 'am_installed',
438 'av_installed',
439 'waf_installed',
440 'time_zone_check',
441 'time_zone_offset',
442 'all_hosts',
443 'plugin_version',
444 'sessions',
445 'multisite_options',
446
447 'host_id',
448 'host_name',
449 ];
450 }
451
452 /**
453 * Checking the old version of options.
454 *
455 * @return boolean
456 * If there are old options, it will return true.
457 */
458 public static function checkOldOptions() {
459
460 // Creating a database with plugin settings.
461 if(WebTotemDB::install()){
462
463 $api_key = get_option('wtsec_api_key');
464 $am_file = get_option('wtsec_am_installed_file');
465 $waf_file = get_option('wtsec_waf_installed_file');
466
467 if($api_key){
468 self::setOptions([
469 'api_key' => $api_key,
470 'am_file' => $am_file,
471 'waf_file' => $waf_file,
472 'activated' => true,
473 'am_installed' => true,
474 'av_installed' => true,
475 'waf_installed' => true,
476 ]);
477
478 $old_options = [
479 'api_key',
480 'api_key_safe',
481 'api_key_activated',
482 'authorized',
483 'authToken',
484 'waf_installed_file',
485 'av_installed_file',
486 'am_installed_file',
487 'am_installed',
488 'logout',
489 'av_installed',
490 'waf_installed',
491 'agents_installed',
492 'api_url',
493 'color_scheme' ,
494 'time_zone',
495 'token_expired',
496 'deactivated',
497 'antivirus_event',
498 'antivirus_permissions_changed',
499 'antivirus_endCursor',
500 'antivirus_hasNextPage',
501 'firewall_endCursor',
502 'firewall_hasNextPage',
503 'reports_endCursor',
504 'reports_hasNextPage'
505 ];
506
507 foreach ($old_options as $option) {
508 delete_option('wtsec_' . $option);
509 delete_site_option('wtsec_' .$option);
510 }
511
512 }
513
514 $api_key = get_site_option('wtotem_api_key');
515 $am_file = get_site_option('wtotem_am_installed_file');
516 $waf_file = get_site_option('wtotem_waf_installed_file');
517
518 if($api_key){
519 self::setOptions([
520 'api_key' => $api_key,
521 'am_file' => $am_file,
522 'waf_file' => $waf_file,
523 'activated' => true,
524 'am_installed' => true,
525 'av_installed' => true,
526 'waf_installed' => true,
527 ]);
528
529 foreach (self::getAllOptions() as $option) {
530 delete_option('wtotem_' . $option);
531 delete_site_option('wtotem_' .$option);
532 }
533 }
534 }
535
536 return true;
537 }
538
539 /**
540 * Check multisite.
541 */
542 public static function multisiteCheck() {
543 // Check the transition to/from the multisite.
544 if ( ( WebTotem::isMultiSite() && ! WebTotemOption::getOption( 'multisite_options' ) ) or
545 ( ! WebTotem::isMultiSite() && WebTotemOption::getOption( 'multisite_options' ) ) ) {
546
547 self::setOptions([ 'multisite_options' => WebTotem::isMultiSite() ]);
548
549 if(WebTotem::isMultiSite()){
550 WebTotemOption::clearAllHosts();
551 WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
552 } else {
553 WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
554 }
555
556 WebTotemAgentManager::removeAgents();
557 }
558 }
559
560 /**
561 * Hide readme file
562 * @param string $readmeFile
563 * @return bool
564 */
565 public static function hideReadme($readmeFile = null) {
566 if ($readmeFile === null) {
567 $readmeFile = ABSPATH . '/readme.html';
568 }
569
570 if (file_exists($readmeFile)) {
571 $readmePathInfo = pathinfo($readmeFile);
572 require_once(ABSPATH . WPINC . '/pluggable.php');
573 $hiddenReadmeFile = $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
574 return @rename($readmeFile, $readmePathInfo['dirname'] . '/' . $hiddenReadmeFile);
575 }
576
577 return false;
578 }
579
580 /**
581 * Restore readme file
582 * @param string $readmeFile
583 * @return bool
584 */
585 public static function restoreReadme($readmeFile = null) {
586 if ($readmeFile === null) {
587 $readmeFile = ABSPATH . '/readme.html';
588 }
589 $readmePathInfo = pathinfo($readmeFile);
590 require_once(ABSPATH . WPINC . '/pluggable.php');
591 $hiddenReadmeFile = $readmePathInfo['dirname'] . '/' . $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
592 if (file_exists($hiddenReadmeFile)) {
593 return @rename($hiddenReadmeFile, $readmeFile);
594 }
595
596 return false;
597 }
598 /**
599 * Hide WP version
600 * @return void
601 */
602 public static function hideWPVersion() {
603 global $wp_version;
604 global $wp_styles;
605
606 if (!($wp_styles instanceof WP_Styles)) {
607 $wp_styles = new WP_Styles();
608 }
609 if ($wp_styles->default_version === $wp_version) {
610 $wp_styles->default_version = wp_hash($wp_styles->default_version);
611 }
612
613 foreach ($wp_styles->registered as $key => $val) {
614 if ($wp_styles->registered[$key]->ver === $wp_version) {
615 $wp_styles->registered[$key]->ver = wp_hash($wp_styles->registered[$key]->ver);
616 }
617 }
618
619 global $wp_scripts;
620 if (!($wp_scripts instanceof WP_Scripts)) {
621 $wp_scripts = new WP_Scripts();
622 }
623 if ($wp_scripts->default_version === $wp_version) {
624 $wp_scripts->default_version = wp_hash($wp_scripts->default_version);
625 }
626
627 foreach ($wp_scripts->registered as $key => $val) {
628 if ($wp_scripts->registered[$key]->ver === $wp_version) {
629 $wp_scripts->registered[$key]->ver = wp_hash($wp_scripts->registered[$key]->ver);
630 }
631 }
632 }
633
634 public static function replaceVersion($url) {
635 return preg_replace_callback("/([&;\?]ver)=(.+?)(&|$)/", "WebTotemOption::replaceVersionCallback", $url);
636 }
637
638 public static function replaceVersionCallback($matches) {
639 global $wp_version;
640 return $matches[1] . '=' . ($wp_version === $matches[2] ? wp_hash($matches[2]) : $matches[2]) . $matches[3];
641 }
642
643 /**
644 * Check the nonce comming from any of the settings pages.
645 *
646 * @return bool True if the nonce is valid, false otherwise.
647 */
648 public static function checkOptionsNonce() {
649 // Create the option_page value if permalink submission.
650 if (!isset($_POST['option_page']) && isset($_POST['permalink_structure'])) {
651 $_POST['option_page'] = 'permalink';
652 }
653
654 /* check if the option_page has an allowed value */
655 $option_page = WebTotemRequest::post('option_page');
656
657 if (!$option_page) {
658 return false;
659 }
660
661 $action = '';
662 $nonce = '_wpnonce';
663
664 switch ($option_page) {
665 case 'general':
666 case 'writing':
667 case 'reading':
668 case 'discussion':
669 case 'media':
670 case 'options':
671 $action = $option_page . '-options';
672 break;
673 case 'permalink':
674 $action = 'update-permalink';
675 break;
676 }
677
678 /* check the nonce validity */
679 return (bool) (
680 !empty($action)
681 && isset($_REQUEST[$nonce])
682 && wp_verify_nonce($_REQUEST[$nonce], $action)
683 );
684 }
685
686 /**
687 * Retrieve all the options stored by Wordpress in the database.
688 *
689 * @return array All the options stored by Wordpress in the database.
690 */
691 private static function getSiteOptions() {
692 $settings = array();
693
694 if (array_key_exists('wpdb', $GLOBALS)) {
695 $results = $GLOBALS['wpdb']->get_results(
696 'SELECT * FROM ' . $GLOBALS['wpdb']->options . ' WHERE option_name NOT LIKE "%_transient_%" ORDER BY option_id ASC'
697 );
698
699 foreach ($results as $row) {
700 $settings[$row->option_name] = $row->option_value;
701 }
702 }
703
704 return $settings;
705 }
706
707 /**
708 * Check what Wordpress options were changed comparing the values in the database
709 * with the values sent through a simple request using a GET or POST method.
710 *
711 * @param array $request The content of the global variable GET or POST considering SERVER[REQUEST_METHOD].
712 * @return array A list of all the options that were changes through this request.
713 */
714 public static function whatOptionsWereChanged($request = array())
715 {
716 $options_changed = [ 'original' => [], 'changed' => [] ];
717
718 $site_options = self::getSiteOptions();
719
720 foreach ($request as $req_name => $req_value) {
721 if (array_key_exists($req_name, $site_options) && $site_options[ $req_name ] != $req_value ) {
722 $options_changed['original'][ $req_name ] = $site_options[ $req_name ];
723 $options_changed['changed'][ $req_name ] = $req_value;
724 }
725 }
726
727 return $options_changed;
728 }
729
730
731 }
732