PluginProbe
WebTotem Security / trunk
WebTotem Security vtrunk
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 2.2.4 All 109 releases
wt-security / lib / Option.php

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

764 lines 18.2 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 $parts = explode('.', $params['token']);
180 $token_data = json_decode(WebTotem::base64UrlDecode($parts[1]), true);
181 $token_expired = $token_data['exp'] - 60;
182
183 self::setOptions([
184 'activated' => TRUE,
185 'auth_token_expired' => $token_expired,
186 'auth_token' => $params['token'],
187 'api_key' => $params['api_key'],
188 'multisite_options' => WebTotem::isMultiSite()
189 ]);
190
191 return TRUE;
192 }
193
194 /**
195 * Save authentication token and token expiration dates in settings.
196 *
197 * @param string $token
198 * Parameters for authorization.
199 *
200 * @return bool
201 * Returns TRUE after setting the options.
202 */
203 public static function refreshToken(string $token) {
204 $parts = explode('.', $token);
205 $token_data = json_decode(WebTotem::base64UrlDecode($parts[1]), true);
206 $token_expired = $token_data['exp'] - 60;
207
208 self::setOptions([
209 'auth_token_expired' => $token_expired,
210 'auth_token' => $token,
211 ]);
212
213 return TRUE;
214 }
215
216 /**
217 * Checks whether the user has activated the plugin using the API key.
218 *
219 * @return bool
220 * Returns the module activation status.
221 */
222 public static function isActivated() {
223 return (boolean) self::getOption('activated');
224 }
225
226 /**
227 * Remove module settings.
228 *
229 * @return string
230 * Returns TRUE after clearing the options.
231 */
232 public static function logout() {
233
234 self::clearOptions([
235 'activated',
236 'auth_token_expired',
237 'auth_token',
238 'api_key',
239 'api_url',
240 'host_id',
241 'host_name',
242 ]);
243 return TRUE;
244 }
245
246 /**
247 * Remove module settings.
248 *
249 * @return string
250 * Returns TRUE after clearing the options.
251 */
252 public static function getAuthToken() {
253 WebTotemAPI::auth(self::getOption('api_key'));
254 return self::getOption('auth_token');
255 }
256
257 /**
258 * Set notification.
259 *
260 * @param string $type
261 * Notification Type.
262 * @param string $notice
263 * Notification Text.
264 */
265 public static function setNotification($type, $notice) {
266 $notifications = self::getSessionOption('notifications') ?: [];
267
268 if (array_key_exists($type, $notifications)) {
269 if (!in_array($notice, $notifications[$type])) {
270 $notifications[$type][] = $notice;
271 self::setSessionOptions(['notifications' => $notifications]);
272 }
273 }
274 else {
275 $notifications[$type][] = $notice;
276 self::setSessionOptions(['notifications' => $notifications]);
277 }
278
279 }
280
281 /**
282 * Get notifications.
283 *
284 * @return array
285 * Notifications array.
286 */
287 public static function getNotificationsData() {
288 $types = ['error', 'info', 'warning', 'success'];
289
290 $notifications = self::getSessionOption('notifications') ?: [];
291 $result = [];
292
293 foreach ($types as $type) {
294 if (array_key_exists($type, $notifications)) {
295 foreach ($notifications[$type] as $notification) {
296 $result[] = ['type' => $type, 'notice' => $notification];
297 }
298 }
299 }
300
301 // Remove notifications.
302 self::setSessionOptions(['notifications' => []]);
303
304 return $result;
305 }
306
307 /**
308 * Set host data.
309 *
310 * @return void
311 */
312 public static function setHost($host_name, $host_id) {
313
314 if(WebTotem::isMultiSite()){
315 $blog_id = self::getBlogId($host_name);
316
317 add_blog_option($blog_id, 'wtotem_host_id', $host_id);
318 add_blog_option($blog_id, 'wtotem_host_name', $host_name);
319
320 if(!is_main_site($blog_id)){
321 $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
322 $all_hosts[$host_name] = $host_id;
323
324 self::setOptions([
325 'all_hosts' => $all_hosts,
326 ]);
327 } else {
328 self::setOptions([
329 'host_id' => $host_id,
330 'host_name' => $host_name,
331 ]);
332 }
333
334 } else {
335 self::setOptions([
336 'host_id' => $host_id,
337 'host_name' => $host_name,
338 ]);
339 }
340 }
341
342 /**
343 * Get host data.
344 *
345 * @param string $hid
346 * Host id.
347 *
348 * @return array
349 * Host data.
350 */
351 public static function getHost($hid = false) {
352
353 if ( $hid ) {
354 $all_hosts = self::getAllHosts() ?: [];
355 if ( $all_hosts and in_array( $hid, $all_hosts ) ) {
356 return [
357 'id' => $hid,
358 'name' => array_search( $hid, $all_hosts ),
359 ];
360 }
361 }
362
363 return self::getMainHost();
364 }
365
366 /**
367 * Get host data.
368 *
369 * @return array
370 * Host data.
371 */
372 public static function getAllHosts() {
373 $all_hosts = json_decode(self::getOption('all_hosts'), true) ?: [];
374
375 $main_host = self::getMainHost();
376 $all_hosts = ($main_host['id']) ? [$main_host['name'] => $main_host['id']] + $all_hosts : $all_hosts;
377
378 return $all_hosts;
379 }
380
381 /**
382 * Get main host data.
383 *
384 * @return array
385 * Main host data.
386 */
387 public static function getMainHost() {
388
389 return [
390 'id' => self::getOption('host_id'),
391 'name' => self::getOption('host_name'),
392 ];
393
394 }
395
396 /**
397 * Delete host data from DB.
398 *
399 * @return void
400 */
401 public static function clearAllHosts() {
402
403 $data = WebTotemAPI::getSites(1, 1000000);
404 foreach ($data['edges'] as $site) {
405 $site = $site['node'];
406 $blog_id = self::getBlogId($site['hostname']);
407 delete_blog_option($blog_id, 'wtotem_host_id');
408 delete_blog_option($blog_id, 'wtotem_host_name');
409 }
410
411 }
412
413 /**
414 * Get an array of new sites.
415 *
416 * @return array
417 * Returns either an empty array or an array with new sites.
418 */
419 // public static function checkNewSites() {
420 // $hosts = self::getAllHosts();
421 // $sites = get_sites();
422 // $new_sites = [];
423 //
424 // foreach ($sites as $site){
425 // $host_name = untrailingslashit($site->domain . $site->path);
426 // if(!array_key_exists($host_name, $hosts) and !array_key_exists('www.' . $host_name, $hosts)) {
427 // $new_sites[] = $host_name;
428 // }
429 // }
430 // return $new_sites;
431 // }
432
433 /**
434 * Get host id from host name.
435 *
436 * @param $host_name
437 * Host name.
438 *
439 * @return integer
440 * Blog id.
441 */
442 public static function getBlogId($host_name){
443 $local_sites = get_sites();
444
445 foreach ($local_sites as $site){
446 $domain = untrailingslashit($site->domain . $site->path);
447 if($host_name == $domain){
448 return $site->blog_id;
449 }
450 }
451 return 0;
452 }
453
454 /**
455 * Get all config options name.
456 *
457 * @return array
458 * Returns saved data by option name.
459 */
460 public static function getAllOptions() {
461 return [
462 'api_key',
463 'activated',
464 'auth_token_expired',
465 'auth_token',
466 'am_file',
467 'waf_file',
468 'av_file',
469 'am_installed',
470 'av_installed',
471 'waf_installed',
472 'time_zone_check',
473 'time_zone_offset',
474 'all_hosts',
475 'plugin_version',
476 'sessions',
477 'multisite_options',
478
479 'host_id',
480 'host_name',
481 ];
482 }
483
484 /**
485 * Checking the old version of options.
486 *
487 * @return boolean
488 * If there are old options, it will return true.
489 */
490 public static function checkOldOptions() {
491
492 // Creating a database with plugin settings.
493 if(WebTotemDB::install()){
494
495 $api_key = get_option('wtsec_api_key');
496 $am_file = get_option('wtsec_am_installed_file');
497 $waf_file = get_option('wtsec_waf_installed_file');
498
499 if($api_key){
500 self::setOptions([
501 'api_key' => $api_key,
502 'am_file' => $am_file,
503 'waf_file' => $waf_file,
504 'activated' => true,
505 'am_installed' => true,
506 'av_installed' => true,
507 'waf_installed' => true,
508 ]);
509
510 $old_options = [
511 'api_key',
512 'api_key_safe',
513 'api_key_activated',
514 'authorized',
515 'authToken',
516 'waf_installed_file',
517 'av_installed_file',
518 'am_installed_file',
519 'am_installed',
520 'logout',
521 'av_installed',
522 'waf_installed',
523 'agents_installed',
524 'api_url',
525 'color_scheme' ,
526 'time_zone',
527 'token_expired',
528 'deactivated',
529 'antivirus_event',
530 'antivirus_permissions_changed',
531 'antivirus_endCursor',
532 'antivirus_hasNextPage',
533 'firewall_endCursor',
534 'firewall_hasNextPage',
535 'reports_endCursor',
536 'reports_hasNextPage'
537 ];
538
539 foreach ($old_options as $option) {
540 delete_option('wtsec_' . $option);
541 delete_site_option('wtsec_' .$option);
542 }
543
544 }
545
546 $api_key = get_site_option('wtotem_api_key');
547 $am_file = get_site_option('wtotem_am_installed_file');
548 $waf_file = get_site_option('wtotem_waf_installed_file');
549
550 if($api_key){
551 self::setOptions([
552 'api_key' => $api_key,
553 'am_file' => $am_file,
554 'waf_file' => $waf_file,
555 'activated' => true,
556 'am_installed' => true,
557 'av_installed' => true,
558 'waf_installed' => true,
559 ]);
560
561 foreach (self::getAllOptions() as $option) {
562 delete_option('wtotem_' . $option);
563 delete_site_option('wtotem_' .$option);
564 }
565 }
566 }
567
568 return true;
569 }
570
571 /**
572 * Check multisite.
573 */
574 public static function multisiteCheck() {
575 // Check the transition to/from the multisite.
576 if ( ( WebTotem::isMultiSite() && ! WebTotemOption::getOption( 'multisite_options' ) ) or
577 ( ! WebTotem::isMultiSite() && WebTotemOption::getOption( 'multisite_options' ) ) ) {
578
579 self::setOptions([ 'multisite_options' => WebTotem::isMultiSite() ]);
580
581 if(WebTotem::isMultiSite()){
582 WebTotemOption::clearAllHosts();
583 WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
584 } else {
585 WebTotemOption::clearOptions([ 'host_id', 'host_name' ]);
586 }
587
588 WebTotemAgentManager::removeAgents();
589 }
590 }
591
592 /**
593 * Hide readme file
594 * @param string $readmeFile
595 * @return bool
596 */
597 public static function hideReadme($readmeFile = null) {
598 if ($readmeFile === null) {
599 $readmeFile = ABSPATH . 'readme.html';
600 }
601
602 if (file_exists($readmeFile)) {
603 $readmePathInfo = pathinfo($readmeFile);
604 require_once(ABSPATH . WPINC . '/pluggable.php');
605 $hiddenReadmeFile = $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
606 return @rename($readmeFile, $readmePathInfo['dirname'] . '/' . $hiddenReadmeFile);
607 }
608
609 return false;
610 }
611
612 /**
613 * Restore readme file
614 * @param string $readmeFile
615 * @return bool
616 */
617 public static function restoreReadme($readmeFile = null) {
618 if ($readmeFile === null) {
619 $readmeFile = ABSPATH . 'readme.html';
620 }
621 $readmePathInfo = pathinfo($readmeFile);
622 require_once(ABSPATH . WPINC . '/pluggable.php');
623 $hiddenReadmeFile = $readmePathInfo['dirname'] . '/' . $readmePathInfo['filename'] . '.' . wp_hash('readme') . '.' . $readmePathInfo['extension'];
624 if (file_exists($hiddenReadmeFile)) {
625 return @rename($hiddenReadmeFile, $readmeFile);
626 }
627
628 return false;
629 }
630 /**
631 * Hide WP version
632 * @return void
633 */
634 public static function hideWPVersion() {
635 global $wp_version;
636 global $wp_styles;
637
638 if (!($wp_styles instanceof WP_Styles)) {
639 $wp_styles = new WP_Styles();
640 }
641 if ($wp_styles->default_version === $wp_version) {
642 $wp_styles->default_version = wp_hash($wp_styles->default_version);
643 }
644
645 foreach ($wp_styles->registered as $key => $val) {
646 if ($wp_styles->registered[$key]->ver === $wp_version) {
647 $wp_styles->registered[$key]->ver = wp_hash($wp_styles->registered[$key]->ver);
648 }
649 }
650
651 global $wp_scripts;
652 if (!($wp_scripts instanceof WP_Scripts)) {
653 $wp_scripts = new WP_Scripts();
654 }
655 if ($wp_scripts->default_version === $wp_version) {
656 $wp_scripts->default_version = wp_hash($wp_scripts->default_version);
657 }
658
659 foreach ($wp_scripts->registered as $key => $val) {
660 if ($wp_scripts->registered[$key]->ver === $wp_version) {
661 $wp_scripts->registered[$key]->ver = wp_hash($wp_scripts->registered[$key]->ver);
662 }
663 }
664 }
665
666 public static function replaceVersion($url) {
667 return preg_replace_callback("/([&;\?]ver)=(.+?)(&|$)/", "WebTotemOption::replaceVersionCallback", $url);
668 }
669
670 public static function replaceVersionCallback($matches) {
671 global $wp_version;
672 return $matches[1] . '=' . ($wp_version === $matches[2] ? wp_hash($matches[2]) : $matches[2]) . $matches[3];
673 }
674
675 /**
676 * Check the nonce comming from any of the settings pages.
677 *
678 * @return bool True if the nonce is valid, false otherwise.
679 */
680 public static function checkOptionsNonce() {
681 // Create the option_page value if permalink submission.
682 if (!isset($_POST['option_page']) && isset($_POST['permalink_structure'])) {
683 $_POST['option_page'] = 'permalink';
684 }
685
686 /* check if the option_page has an allowed value */
687 $option_page = WebTotemRequest::post('option_page');
688
689 if (!$option_page) {
690 return false;
691 }
692
693 $action = '';
694 $nonce = '_wpnonce';
695
696 switch ($option_page) {
697 case 'general':
698 case 'writing':
699 case 'reading':
700 case 'discussion':
701 case 'media':
702 case 'options':
703 $action = $option_page . '-options';
704 break;
705 case 'permalink':
706 $action = 'update-permalink';
707 break;
708 }
709
710 /* check the nonce validity */
711 return (bool) (
712 !empty($action)
713 && isset($_REQUEST[$nonce])
714 && wp_verify_nonce($_REQUEST[$nonce], $action)
715 );
716 }
717
718 /**
719 * Retrieve all the options stored by Wordpress in the database.
720 *
721 * @return array All the options stored by Wordpress in the database.
722 */
723 private static function getSiteOptions() {
724 $settings = array();
725
726 if (array_key_exists('wpdb', $GLOBALS)) {
727 $results = $GLOBALS['wpdb']->get_results(
728 'SELECT * FROM ' . $GLOBALS['wpdb']->options . ' WHERE option_name NOT LIKE "%_transient_%" ORDER BY option_id ASC'
729 );
730
731 foreach ($results as $row) {
732 $settings[$row->option_name] = $row->option_value;
733 }
734 }
735
736 return $settings;
737 }
738
739 /**
740 * Check what Wordpress options were changed comparing the values in the database
741 * with the values sent through a simple request using a GET or POST method.
742 *
743 * @param array $request The content of the global variable GET or POST considering SERVER[REQUEST_METHOD].
744 * @return array A list of all the options that were changes through this request.
745 */
746 public static function whatOptionsWereChanged($request = array())
747 {
748 $options_changed = [ 'original' => [], 'changed' => [] ];
749
750 $site_options = self::getSiteOptions();
751
752 foreach ($request as $req_name => $req_value) {
753 if (array_key_exists($req_name, $site_options) && $site_options[ $req_name ] != $req_value ) {
754 $options_changed['original'][ $req_name ] = $site_options[ $req_name ];
755 $options_changed['changed'][ $req_name ] = $req_value;
756 }
757 }
758
759 return $options_changed;
760 }
761
762
763 }
764