PluginProbe
Patchstack – WordPress & Plugins Security / 2.3.7
Patchstack – WordPress & Plugins Security v2.3.7
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
patchstack / includes / admin / general.php

general.php in Patchstack – WordPress & Plugins Security 2.3.7, at includes/admin/general.php

138 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Do not allow the file to be called directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * This class is used for any general admin functionality.
10 * For example to display general errors on all pages or event listeners.
11 */
12 class P_Admin_General extends P_Core {
13
14 /**
15 * Add any general actions for the backend.
16 *
17 * @param Patchstack $core
18 * @return void
19 */
20 public function __construct( $core ) {
21 parent::__construct( $core );
22
23 // Add admin and network notices.
24 add_action( 'admin_notices', [ $this, 'file_error_notice' ] );
25 add_action( 'network_admin_notices', [ $this, 'file_error_notice' ] );
26 add_action( 'update_option_siteurl', [ $this, 'update_option_url' ], 10, 2 );
27 // Use updated_option (fires after the value is written) so auto_prepend_injection()
28 // re-reads the new value; update_option fires before the write and sees the old value.
29 add_action( 'updated_option', [ $this, 'update_option_ap' ], 10, 3 );
30
31 // If the firewall or whitelist rules do not exist, attempt to pull fresh.
32 $token = get_option( 'patchstack_api_token', false );
33 if ( ! empty( $token ) && ( get_option( 'patchstack_firewall_rules', '' ) == '' || get_option( 'patchstack_whitelist_keys_rules' ) == '' ) && get_option( 'patchstack_license_free', 0 ) != 1 ) {
34 do_action( 'patchstack_post_dynamic_firewall_rules' );
35 }
36 }
37
38 /**
39 * Display error message if file/folder permissions are not set properly.
40 *
41 * @return void
42 */
43 public function file_error_notice() {
44 // No need to display this error if the .htaccess functionality has been disabled.
45 if ( get_site_option( 'patchstack_disable_htaccess', 0 ) || ( defined( 'PS_DISABLE_HTACCESS' ) && PS_DISABLE_HTACCESS ) ) {
46 return;
47 }
48
49 // No need to display if a free user without protection.
50 if ( get_option( 'patchstack_license_free', 0 ) == 1 ) {
51 return;
52 }
53
54 // No need to display on nginx.
55 if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stripos( $_SERVER['SERVER_SOFTWARE'], 'nginx' ) !== false ) {
56 return;
57 }
58
59 // Check root .htaccess file and data folder writability.
60 $files = [];
61 if ( file_exists( ABSPATH . '.htaccess' ) && ! wp_is_writable( ABSPATH . '.htaccess' ) ) {
62 array_push( $files, ABSPATH . '.htaccess' );
63 }
64
65 // Are there any errors to display?
66 if ( count( $files ) > 0 ) {
67 ?>
68 <div class="error notice">
69 <h2>Patchstack File Permission Error</h2>
70 <p><?php esc_html_e( 'The following file/folder could not be written to:<br />' . implode( '<br />', $files ), 'patchstack' ); ?></p>
71 <?php
72 foreach ( $files as $file ) {
73 echo wp_kses( '<p><b>Debug info: </b>' . $file . ' chmod permissions: <b>' . substr( decoct( fileperms( $file ) ), -3 ) . '</b>, owned by <b>' . $this->get_file_owner_name( $file ) . '</b></p>', $this->allowed_html );
74 }
75 ?>
76 <p><?php esc_html_e( '<strong>How to fix?</strong><br />CHMOD the file/folder to <strong>755</strong> through a <a href="http://www.dummies.com/web-design-development/wordpress/navigation-customization/how-to-change-file-permissions-using-filezilla-on-your-ftp-site/" target="_blank">FTP client</a>, <a href="http://support.hostgator.com/articles/cpanel/how-to-change-permissions-chmod-of-a-file" target="_blank">CPanel</a>, <a href="https://www.inmotionhosting.com/support/website/managing-files/change-file-permissions" target="_blank">WHM</a> or ask your hosting provider. Make sure file or folder ownership is set to <b>' . $this->get_file_owner_name( ABSPATH . 'index.php' ) . '</b> user .', 'patchstack_file_error_notice' ); ?></p>
77 <p><?php esc_html_e( '<strong>CHMOD properly set but still not working?</strong><br />Make sure the group/owner (chown) settings of the /wp-content/plugins/patchstack/ folder is properly setup, you may have to ask your host to fix this.', 'patchstack_file_error_notice' ); ?></p>
78 </div>
79 <?php
80 }
81 }
82
83 /**
84 * Resolve the owning system user name for a file, guarding the POSIX extension
85 * which is not available on Windows or some hardened hosts.
86 *
87 * @param string $file
88 * @return string
89 */
90 private function get_file_owner_name( $file ) {
91 if ( ! function_exists( 'posix_getpwuid' ) || ! function_exists( 'fileowner' ) ) {
92 return '';
93 }
94
95 $owner = posix_getpwuid( fileowner( $file ) );
96 return isset( $owner['name'] ) ? $owner['name'] : '';
97 }
98
99 /**
100 * When the user updates the site URL, update it on the API side as well.
101 * This needs to be done so we can communicate with the site properly.
102 *
103 * @param mixed $old_value
104 * @param mixed $new_value
105 * @return void
106 */
107 public function update_option_url( $old_value, $new_value ) {
108 if ( $old_value != $new_value ) {
109 $this->plugin->api->update_url( [ 'plugin_url' => $new_value ] );
110 }
111 }
112
113 /**
114 * When the firewall auto prepend option value is changed, ensure that we prepare the environment or remove it from the environment.
115 *
116 * @param mixed $option_name
117 * @param mixed $old_value
118 * @param mixed $new_value
119 * @return void
120 */
121 public function update_option_ap( $option_name, $old_value, $new_value ) {
122 if ( $option_name != 'patchstack_firewall_ap_enabled' ) {
123 return;
124 }
125
126 // No need to perform if user is on free plan.
127 if ( get_option( 'patchstack_license_activated', 0 ) != 1 ) {
128 return;
129 }
130
131 if ( $new_value && (int) get_option( 'patchstack_license_free', 0 ) == 0 ) {
132 $this->plugin->activation->auto_prepend_injection();
133 } else {
134 $this->plugin->activation->auto_prepend_removal();
135 }
136 }
137 }
138