WP fail2ban - Version 4.2.8

Version Description

  • Add link to new support forum.
  • Fix user enumeration conflict with Gutenberg (h/t @dinghy).
  • Fix notices wrt admin menu (h/t @marioivangf).
  • Fix harmless XDebug notice (h/t @dinghy).
  • Update Freemius library.
Download this release

Release Info

Developer invisnet
Plugin Icon 128x128 WP fail2ban
Version 4.2.8
Comparing to
See all releases

Code changes from version 4.3.0-RC3 to 4.2.8

admin/admin.php CHANGED
@@ -4,211 +4,96 @@
4
  * Admin
5
  *
6
  * @package wp-fail2ban
7
- * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
-
12
- if ( defined( 'ABSPATH' ) ) {
13
- require_once __DIR__ . '/config.php';
14
- require_once __DIR__ . '/tools.php';
15
- require_once __DIR__ . '/lib/about.php';
16
- include_once_exists( WP_FAIL2BAN_DIR . '/premium/admin/admin.php' );
17
- /**
18
- * Helper: Security and Settings menu
19
- *
20
- * @since 4.3.0
21
- *
22
- * @param string $capability Capability
23
- */
24
- function _security_settings( $capability = 'manage_options' )
25
- {
26
-
27
- if ( function_exists( '\\add_security_page' ) ) {
28
- $hook = add_security_page(
29
- 'WP fail2ban',
30
- 'WP fail2ban',
31
- plugin_basename( WP_FAIL2BAN_DIR ),
32
- __NAMESPACE__ . '\\security'
33
- );
34
- add_action( "load-{$hook}", function () {
35
- TabBase::setDefaultTab( 'logging' );
36
- TabBase::getActiveTab()->current_screen();
37
- } );
38
- if ( class_exists( __NAMESPACE__ . '\\premium\\WPf2b' ) ) {
39
- _settings( 'status', $capability );
40
- }
41
- } else {
42
- _settings( apply_filters( __METHOD__ . '.page', 'logging' ), $capability );
43
- }
44
-
45
- }
46
 
47
- /**
48
- * Helper: Settings menu
49
- *
50
- * @since 4.3.0
51
- *
52
- * @param $page string|null
53
- * @param $capability string
54
- */
55
- function _settings( $page = null, $capability = 'manage_options' )
56
- {
57
- $hook = add_submenu_page(
58
- 'wp-fail2ban-menu',
59
- __( 'Settings', 'wp-fail2ban' ),
60
- __( 'Settings', 'wp-fail2ban' ),
61
- $capability,
62
- 'wpf2b-settings',
63
- __NAMESPACE__ . '\\settings'
64
  );
65
- add_action( "load-{$hook}", function () use( $page ) {
66
- TabBase::setDefaultTab( $page );
67
- TabBase::getActiveTab()->current_screen();
68
- } );
69
- }
70
-
71
- /**
72
- * Helper: Remote Tools menu
73
- *
74
- * @since 4.3.0
75
- *
76
- * @param string $capability Capability
77
- */
78
- function _remote_tools( $capability = 'manage_options' )
79
- {
80
  add_submenu_page(
81
- 'wp-fail2ban-menu',
82
- __( 'Tools', 'wp-fail2ban' ),
83
- __( ' - Remote Tools (β)', 'wp-fail2ban' ),
84
- $capability,
85
- 'wp-fail2ban-tools',
86
- __NAMESPACE__ . '\\remote_tools'
87
  );
88
  }
89
 
90
- /**
91
- * Register admin menus
92
- *
93
- * @since 4.0.0
94
- */
95
- function admin_menu()
96
- {
97
- if ( wf_fs()->is_free_plan() && !wf_fs()->is_trial() || wf_fs()->is_plan( 'remote', true ) ) {
98
-
99
- if ( !is_multisite() ) {
100
- add_menu_page(
101
- 'WP fail2ban',
102
- 'WP fail2ban',
103
- 'manage_options',
104
- 'wp-fail2ban-menu',
105
- __NAMESPACE__ . '\\about',
106
- plugin_dir_url( WP_FAIL2BAN_FILE ) . 'assets/menu.svg'
107
- );
108
- add_action( 'admin_menu', __NAMESPACE__ . '\\admin_menu_fix', PHP_INT_MAX );
109
-
110
- if ( !is_multisite() ) {
111
- _security_settings();
112
- _remote_tools();
113
- }
114
-
115
- }
116
-
117
- }
118
- }
119
-
120
- add_action( 'admin_menu', __NAMESPACE__ . '\\admin_menu' );
121
- /**
122
- * Register network admin menus
123
- *
124
- * @since 4.3.0
125
- */
126
- function network_admin_menu()
127
- {
128
-
129
- if ( wf_fs()->is_free_plan() && !wf_fs()->is_trial() ) {
130
- add_menu_page(
131
- 'WP fail2ban',
132
- 'WP fail2ban',
133
- 'manage_options',
134
- 'wp-fail2ban-menu',
135
- __NAMESPACE__ . '\\about',
136
- plugin_dir_url( WP_FAIL2BAN_FILE ) . 'assets/menu.svg'
137
- );
138
- add_action( 'network_admin_menu', __NAMESPACE__ . '\\admin_menu_fix', PHP_INT_MAX );
139
- _security_settings();
140
- _remote_tools();
141
- }
142
-
143
- }
144
-
145
- add_action( 'network_admin_menu', __NAMESPACE__ . '\\network_admin_menu' );
146
- /**
147
- * Fix first submenu name.
148
- *
149
- * @since 4.3.0
150
- */
151
- function admin_menu_fix()
152
- {
153
- global $submenu ;
154
- if ( isset( $submenu['wp-fail2ban-menu'] ) && 'WP fail2ban' == @$submenu['wp-fail2ban-menu'][0][0] ) {
155
- $submenu['wp-fail2ban-menu'][0][0] = __( 'Welcome', 'wp-fail2ban' );
156
  }
 
 
 
157
  }
158
-
159
- /**
160
- * Add Settings link on Plugins page
161
- *
162
- * @since 4.2.0
163
- *
164
- * @param string[] $actions An array of plugin action links. By default this can include 'activate',
165
- * 'deactivate', and 'delete'.
166
- * @param string $plugin_file Path to the plugin file relative to the plugins directory.
167
- * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
168
- * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
169
- * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
170
- */
171
- function plugin_action_links(
172
- $actions,
173
- $plugin_file,
174
- $plugin_data,
175
- $context
176
- )
177
- {
178
-
179
- if ( preg_match( "|{$plugin_file}\$|", WP_FAIL2BAN_FILE ) && (!is_multisite() || is_network_admin()) ) {
180
-
181
- if ( function_exists( '\\add_security_page' ) ) {
182
- return $actions;
183
- } else {
184
- $page = 'wpf2b-fail2ban-menu';
185
- }
186
-
187
- $settings = sprintf(
188
- '<a href="%s?page=wpf2b-settings&tab=about" title="%s">%s</a>',
189
- network_admin_url( 'admin.php' ),
190
- __( 'Settings', 'wp-fail2ban' ),
191
- ( function_exists( '\\add_security_page' ) ? '<span class="dashicon dashicons-admin-generic"></span>' : __( 'Settings', 'wp-fail2ban' ) )
192
- );
193
- // Add Settings at the start
194
- $actions = array_merge( [
195
- 'settings' => $settings,
196
- ], $actions );
197
- }
198
-
199
- return $actions;
200
  }
201
-
202
- add_filter(
203
- 'plugin_action_links',
204
- __NAMESPACE__ . '\\plugin_action_links',
205
- 10,
206
- 4
207
- );
208
- add_filter(
209
- 'network_admin_plugin_action_links',
210
- __NAMESPACE__ . '\\plugin_action_links',
211
- 10,
212
- 4
213
- );
214
  }
 
 
 
 
 
 
 
4
  * Admin
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ require __DIR__ . '/config.php';
15
+ require __DIR__ . '/lib/about.php';
16
+ /**
17
+ * Register admin menus
18
+ *
19
+ * @since 4.0.0
20
+ */
21
+ function admin_menu()
22
+ {
23
+ global $submenu ;
24
+ add_menu_page(
25
+ 'WP fail2ban',
26
+ 'WP fail2ban',
27
+ 'manage_options',
28
+ 'wp-fail2ban',
29
+ __NAMESPACE__ . '\\about',
30
+ 'dashicons-analytics'
31
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ if ( function_exists( '\\add_security_page' ) ) {
34
+ $slug = 'wp-fail2ban';
35
+ add_security_page(
36
+ 'WP fail2ban',
37
+ 'WP fail2ban',
38
+ $slug,
39
+ __NAMESPACE__ . '\\security'
 
 
 
 
 
 
 
 
 
 
40
  );
41
+ } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  add_submenu_page(
43
+ 'wp-fail2ban',
44
+ 'Settings',
45
+ 'Settings',
46
+ 'manage_options',
47
+ 'wpf2b-settings',
48
+ __NAMESPACE__ . '\\settings'
49
  );
50
  }
51
 
52
+ $hook = add_submenu_page(
53
+ 'wp-fail2ban',
54
+ 'WP fail2ban - Remote Tools',
55
+ 'Remote Tools',
56
+ 'manage_options',
57
+ 'wp-fail2ban-tools',
58
+ __NAMESPACE__ . '\\remote_tools'
59
+ );
60
+ add_action( "load-{$hook}", function () {
61
+ if ( function_exists( '\\org\\lecklider\\charles\\wordpress\\wp_fail2ban\\addons\\remote_tools\\help' ) ) {
62
+ \org\lecklider\charles\wordpress\wp_fail2ban\addons\remote_tools\help();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
+ } );
65
+ if ( array_key_exists( 'wp-fail2ban', $submenu ) ) {
66
+ $submenu['wp-fail2ban'][0][0] = __( 'Welcome' );
67
  }
68
+ }
69
+
70
+ add_action( 'admin_menu', __NAMESPACE__ . '\\admin_menu' );
71
+ /**
72
+ * Add Settings link on Plugins page
73
+ *
74
+ * @since 4.2.6 Add support for ClassicPress security page
75
+ * @since 4.2.0
76
+ *
77
+ * @param array $links
78
+ * @param string $file
79
+ */
80
+ function plugin_action_links( $links, $file )
81
+ {
82
+ if ( preg_match( "|{$file}\$|", WP_FAIL2BAN_FILE ) ) {
83
+ array_unshift( $links, sprintf(
84
+ '<a href="%s?page=%s" title="%s">%s</a>',
85
+ admin_url( 'admin.php' ),
86
+ 'wpf2b-settings',
87
+ __( 'Settings' ),
88
+ ( function_exists( '\\add_security_page' ) ? '<span class="dashicon dashicons-admin-generic"></span>' : __( 'Settings' ) )
89
+ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
91
+ return $links;
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
+
94
+ add_filter(
95
+ 'plugin_action_links',
96
+ __NAMESPACE__ . '\\plugin_action_links',
97
+ 10,
98
+ 2
99
+ );
admin/config.php CHANGED
@@ -1,186 +1,160 @@
1
  <?php
 
2
  /**
3
  * Config
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- require_once 'lib/tab.php';
12
- require_once 'config/block.php';
13
- require_once 'config/logging.php';
14
- require_once 'config/plugins.php';
15
- require_once 'config/remote-ips.php';
16
- require_once 'config/syslog.php';
17
-
18
- if (false === (@include_once WP_FAIL2BAN_DIR.'/premium/admin/config.php')) {
19
- /**
20
- * Init
21
- *
22
- */
23
- function init_tabs()
24
- {
25
- new TabBlock();
26
- new TabLogging();
27
- new TabPlugins();
28
- new TabRemoteIPs();
29
- new TabSyslog();
30
- }
31
- add_action('init', __NAMESPACE__.'\init_tabs', 999);
32
- } // @include
33
-
34
- /**
35
- * Display settings messages.
36
- *
37
- * @since 4.3.0
38
- */
39
- function admin_notices()
40
- {
41
- $screen = get_current_screen();
42
- switch ($screen->id) {
43
- case 'security_page_wp-fail2ban-premium':
44
- case 'wp-fail2ban_page_wpf2b-settings':
45
- settings_errors();
46
- break;
47
- }
48
  }
49
- add_action('admin_notices', __NAMESPACE__.'\admin_notices');
50
-
51
- /**
52
- * Get network settings messages.
53
- *
54
- * @since 4.3.0
55
- */
56
- function network_admin_notices()
57
- {
58
- $screen = get_current_screen();
59
- switch ($screen->id) {
60
- case 'security_page_wp-fail2ban-premium-network':
61
- case 'wp-fail2ban_page_wpf2b-settings-network':
62
- if ($transients = get_site_transient('settings_errors')) {
63
- global $wp_settings_errors;
64
-
65
- $wp_settings_errors = array_merge((array)$wp_settings_errors, $transients);
66
- delete_site_transient('settings_errors');
67
- }
68
- settings_errors();
69
- break;
70
- }
71
  }
72
- add_action('network_admin_notices', __NAMESPACE__.'\network_admin_notices');
 
73
 
74
- /**
75
- * Render Security settings.
76
- *
77
- * @since 4.3.0
78
- */
79
- function security()
80
- {
 
 
 
81
  $tabs = [
82
  'logging',
83
  'syslog',
84
  'block',
85
- 'remote-ips',
86
- 'plugins'
87
  ];
88
- $tabs = apply_filters(__METHOD__.'.tabs', $tabs);
89
- $page = apply_filters(__METHOD__.'.page', plugin_basename(WP_FAIL2BAN_DIR));
90
-
91
- render_tabs($tabs, $page);
92
- }
93
-
94
- /**
95
- * Render Settings.
96
- *
97
- * @since 4.0.0
98
- */
99
- function settings()
100
- {
101
- $tabs = [];
102
-
103
- if (!function_exists('\add_security_page')) {
104
- $tabs = [
105
- 'logging',
106
- 'syslog',
107
- 'block',
108
- 'remote-ips'
109
- ];
110
- if (version_compare(PHP_VERSION, '5.6.0', '>=')) {
111
- $tabs[] = 'plugins';
112
- }
113
  }
114
- $tabs = apply_filters(__METHOD__.'.tabs', $tabs);
115
-
116
- render_tabs($tabs, 'wpf2b-settings');
117
  }
 
 
 
 
118
 
119
- /**
120
- * Render Tabs.
121
- *
122
- * @since 4.3.0
123
- *
124
- * @param array $tabs List of slugs of tabs to render
125
- * @param string $menu Menu slug
126
- */
127
- function render_tabs(array $tabs, $menu)
128
- {
129
- $active_tab = TabBase::getActiveTab();
130
-
131
- ?>
132
- <div class="wrap">
133
- <?=apply_filters(__METHOD__.'.title', sprintf('<h1>%s</h1>', __('Settings', 'wp-fail2ban')))?>
134
- <hr class="wp-header-end">
135
-
136
- <h2 class="nav-tab-wrapper wp-clearfix">
137
- <?php
138
- foreach ($tabs as $slug) {
139
- $class = 'nav-tab';
140
- if ($active_tab->getSlug() == $slug) {
141
- $class .= ' nav-tab-active';
142
- }
143
- $params = apply_filters(__METHOD__.'.params', [
144
- 'page' => $menu,
145
- 'tab' => $slug
146
- ]);
147
- printf('<a class="%s" href="?%s">%s</a>', $class, http_build_query($params), TabBase::getTabName($slug));
148
  }
149
- ?>
150
- </h2>
151
-
152
- <?php
153
- // Because the settings API was never finished we need an ugly hack
154
- $action = sprintf(
155
- '%s?tab=%s',
156
- admin_url(is_network_admin()
157
- ? 'admin-post.php'
158
- : 'options.php'),
159
- $active_tab->getSlug()
160
  );
161
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- <form action="<?=$action?>" method="post">
164
- <?php
165
- settings_fields('wp-fail2ban');
166
- $active_tab->render();
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  ?>
168
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  </div>
170
- <?php
171
- }
172
-
173
- /**
174
- * Helper: filtered defined(...)
175
- *
176
- * @since 4.3.0
177
- *
178
- * @param string $define
179
- * @return mixed
180
- */
181
- function have_defined($define)
182
- {
183
- return apply_filters(__NAMESPACE__.'\have_defined', defined($define), $define);
184
  }
 
 
 
 
185
  }
186
-
1
  <?php
2
+
3
  /**
4
  * Config
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ require_once 'lib/tab.php';
15
+ foreach ( glob( __DIR__ . '/config/*.php' ) as $filename ) {
16
+ require_once $filename;
17
+ }
18
+ /**
19
+ * Render Security settings.
20
+ *
21
+ * @since 4.2.6
22
+ */
23
+ function security()
24
+ {
25
+ $tabs = [
26
+ 'logging',
27
+ 'syslog',
28
+ 'block',
29
+ 'remote-ips'
30
+ ];
31
+ if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
32
+ $tabs[] = 'plugins';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
+ $page = 'wp-fail2ban';
35
+ if ( wf_fs()->is_premium() ) {
36
+ $page .= '-premium';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
+ render_tabs( $tabs, 'logging', $page );
39
+ }
40
 
41
+ /**
42
+ * Render Settings.
43
+ *
44
+ * @since 4.2.6
45
+ */
46
+ function settings()
47
+ {
48
+ $tabs = [];
49
+
50
+ if ( !function_exists( '\\add_security_page' ) ) {
51
  $tabs = [
52
  'logging',
53
  'syslog',
54
  'block',
55
+ 'remote-ips'
 
56
  ];
57
+ if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
58
+ $tabs[] = 'plugins';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
 
 
 
60
  }
61
+
62
+ $default = 'logging';
63
+ render_tabs( $tabs, $default, 'wpf2b-settings' );
64
+ }
65
 
66
+ /**
67
+ * Render Tabs.
68
+ *
69
+ * @since 4.2.6
70
+ *
71
+ * @param array $tabs List of slugs of tabs to render
72
+ * @param string $default Default tab slug
73
+ * @param string $menu Menu slug
74
+ */
75
+ function render_tabs( array $tabs, $default, $menu )
76
+ {
77
+ ?>
78
+ <div class="wrap">
79
+ <?php
80
+ echo apply_filters( __METHOD__ . '.title', "<h1>WP fail2ban</h1>" ) ;
81
+ ?>
82
+ <hr class="wp-header-end">
83
+
84
+ <h2 class="nav-tab-wrapper wp-clearfix">
85
+ <?php
86
+ $active_tab = Tab::getActiveTab( $default );
87
+ foreach ( $tabs as $slug ) {
88
+ $class = 'nav-tab';
89
+ if ( $active_tab->getSlug() == $slug ) {
90
+ $class .= ' nav-tab-active';
 
 
 
 
91
  }
92
+ $params = apply_filters( __METHOD__ . '.params', [
93
+ 'page' => $menu,
94
+ 'tab' => $slug,
95
+ ] );
96
+ printf(
97
+ '<a class="%s" href="?%s">%s</a>',
98
+ $class,
99
+ http_build_query( $params ),
100
+ Tab::getTabName( $slug )
 
 
101
  );
102
+ }
103
+ ?>
104
+ </h2>
105
+
106
+ <form action="options.php?tab=<?php
107
+ echo $active_tab->getSlug() ;
108
+ ?>" method="post">
109
+ <?php
110
+ settings_fields( 'wp-fail2ban' );
111
+ $active_tab->render();
112
+ echo '<hr><p>' . __( '<strong>Note:</strong> The Free version of <em>WP fail2ban</em> is configured by defining constants in <tt>wp-config.php</tt>; these tabs display those values.' ) . '<br>' . __( 'Upgrade to the Premium version to enable this interface.' ) . '</p>' ;
113
+ ?>
114
+ </form>
115
+ </div>
116
+ <?php
117
+ }
118
 
119
+ /**
120
+ * Proxy for api.wp-fail2ban.com
121
+ *
122
+ * @since 4.2.6
123
+ */
124
+ function remote_tools()
125
+ {
126
+ global $current_user ;
127
+ ?>
128
+ <div class="wrap">
129
+ <h1>Remote Tools (&beta;)</h1>
130
+ <hr class="wp-header-end">
131
+ <?php
132
+
133
+ if ( function_exists( '\\org\\lecklider\\charles\\wordpress\\wp_fail2ban\\addons\\remote_tools\\tab' ) ) {
134
+ \org\lecklider\charles\wordpress\wp_fail2ban\addons\remote_tools\tab();
135
+ } else {
136
  ?>
137
+ <h2 class="nav-tab-wrapper wp-clearfix">
138
+ <a class="nav-tab nav-tab-active" href="#">Overview</a>
139
+ </h2>
140
+ <div class="card">
141
+ <h2>Remote Tools Add-on</h2>
142
+ <p>This add-on provides features that make life with WP fail2ban easier, all from a remote server. This gives access to valuable but infrequently used tools without bloating the core plugin.</p>
143
+ <p>The first of these is a <strong>Custom Filter Tool</strong> (CFT).</p>
144
+ <blockquote>
145
+ <p>The filter files included are intended only as a starting point for those who want <em>WPf2b</em> to work “out of the box”.</p>
146
+ <p>There is no &ldquo;one size fits all&rdquo; configuration possible for <em>fail2ban</em> - what may be a soft failure for one site should be treated as a hard failure for another, and vice versa.</p>
147
+ </blockquote>
148
+ <p>You could simply edit the filter files included, but it&lsquo;s surprisingly easy to make a mistake; I learned this the hard way with earlier versions of <em>WPf2b</em>.... The CFT removes most of the opportunities for human error - always a good thing!</p>
149
+ <hr>
150
+ <p>The Remote Tools Add-on is available from the <a href="<?php
151
+ echo admin_url( 'admin.php?page=wp-fail2ban-addons' ) ;
152
+ ?>">Add-Ons menu</a>.</p>
153
  </div>
154
+ <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
+
157
+ ?>
158
+ </div>
159
+ <?php
160
  }
 
admin/config/block.php CHANGED
@@ -1,144 +1,120 @@
1
  <?php
 
2
  /**
3
  * Settings - Block
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Tab: Block
13
  *
14
  * @since 4.0.0
15
  */
16
- class TabBlock extends TabBase
17
  {
18
- /**
19
- * {@inheritDoc}
20
- *
21
- * @since 4.0.0
22
- */
23
- public function __construct()
24
- {
25
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
26
- $this->__['users'] = __('Users', 'wp-fail2ban');
27
- $this->__['user-enumeration'] = __('Block User Enumeration', 'wp-fail2ban');
28
- $this->__['blacklist'] = __('Blacklisted Usernames', 'wp-fail2ban');
29
- $this->__['username-login'] = __('Block username logins', 'wp-fail2ban');
30
- // phpcs:enable
31
-
32
- parent::__construct('block', __('Block', 'wp-fail2ban'));
33
- }
34
-
35
- /**
36
- * {@inheritDoc}
37
- *
38
- * @since 4.0.0
39
- */
40
- public function admin_init()
41
- {
42
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
43
- add_settings_section('wp-fail2ban-users', $this->__['users'], [$this, 'section'], 'wp-fail2ban-block');
44
- add_settings_field('user-enumeration', $this->__['user-enumeration'], [$this, 'userEnumeration'], 'wp-fail2ban-block', 'wp-fail2ban-users');
45
- add_settings_field('blacklist', $this->__['blacklist'], [$this, 'users'], 'wp-fail2ban-block', 'wp-fail2ban-users');
46
- add_settings_field('username-login', $this->__['username-login'], [$this, 'usernames'], 'wp-fail2ban-block', 'wp-fail2ban-users');
47
- // phpcs:enable
48
- }
49
-
50
- /**
51
- * {*inheritDoc}
52
- *
53
- * @since 4.3.0
54
- */
55
- public function current_screen()
56
- {
57
- $fmt = <<<___FMT___
58
- <dl><style>dt{font-weight:bold;}</style>
59
- <dt>%s</dt>
60
- <dd><p>%s</p><p>%s</p><p>%s</p>%s</dd>
61
- <dt>%s</dt>
62
- <dd><p>%s</p><p>%s</p>%s</dd>
63
- <dt>%s</dt>
64
- <dd><p>%s</p><p>%s</p>%s</dd>
65
- </dl>
66
- ___FMT___;
67
- get_current_screen()->add_help_tab([
68
- 'id' => 'users',
69
- 'title' => $this->__['users'],
70
- 'content' => sprintf(
71
- $fmt,
72
- $this->__['user-enumeration'],
73
- __('Automated brute-force attacks ("bots") typically start by getting a list of valid usernames ("user enumeration").', 'wp-fail2ban'),
74
- __('Blocking user enumeration can force attackers to guess usernames, making these attacks much less likely to succeed.', 'wp-fail2ban'),
75
- __('<strong>N.B.</strong> Some Themes "leak" usernames (for example, via Author profile pages); see <strong>Block username logins</strong> for an alternative.', 'wp-fail2ban'),
76
- $this->see_also(['WP_FAIL2BAN_BLOCK_USER_ENUMERATION']),
77
- $this->__['blacklist'],
78
- __('Automated brute-force attacks ("bots") will often use well-known usernames, e.g. <tt>admin</tt>.', 'wp-fail2ban'),
79
- __('Blacklisted usernames are blocked early in the login process, reducing server load.', 'wp-fail2ban'),
80
- $this->see_also(['WP_FAIL2BAN_BLOCKED_USERS']),
81
- $this->__['username-login'],
82
- __('It is sometimes not possible to block user enumeration (for example, if your theme provides Author profiles). An alternative is to require users to login with their email address.', 'wp-fail2ban'),
83
- __('<strong>N.B.</strong> This also applies to Blacklisted Usernames; you must list <em>email addresses</em>, not usernames.', 'wp-fail2ban'),
84
- $this->see_also(['WP_FAIL2BAN_BLOCK_USERNAME_LOGIN'])
85
- )
86
- ]);
87
-
88
- parent::current_screen();
89
- }
90
-
91
- /**
92
- * {@inheritDoc}
93
- *
94
- * @since 4.0.0
95
- */
96
- public function section()
97
- {
98
- echo '';
99
- }
100
-
101
- /**
102
- * User Enumeration
103
- *
104
- * @since 4.0.0
105
- */
106
- public function userEnumeration()
107
- {
108
- $this->checkbox('WP_FAIL2BAN_BLOCK_USER_ENUMERATION');
109
- }
110
-
111
- /**
112
- * Blocked usernames
113
- *
114
- * @since 4.0.0
115
- */
116
- public function users()
117
- {
118
- if (defined('WP_FAIL2BAN_BLOCKED_USERS')) {
119
- if (is_array(WP_FAIL2BAN_BLOCKED_USERS)) {
120
- $value = join(', ', WP_FAIL2BAN_BLOCKED_USERS);
121
- } else {
122
- $value = WP_FAIL2BAN_BLOCKED_USERS;
123
- }
124
  } else {
125
- $value = '';
126
  }
127
- printf(
128
- '<input class="regular-text" type="text" disabled="disabled" value="%s">',
129
- esc_attr($value)
130
- );
131
- }
132
-
133
- /**
134
- * Block username logins
135
- *
136
- * @since 4.3.0
137
- */
138
- public function usernames()
139
- {
140
- $this->checkbox('WP_FAIL2BAN_BLOCK_USERNAME_LOGIN');
141
  }
 
 
142
  }
143
- }
144
 
 
 
1
  <?php
2
+
3
  /**
4
  * Settings - Block
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
+ namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Tab: Block
16
+ *
17
+ * @since 4.0.0
18
+ */
19
+ class TabBlock extends Tab
20
+ {
21
  /**
22
+ * {@inheritDoc}
23
  *
24
  * @since 4.0.0
25
  */
26
+ public function __construct()
27
  {
28
+ add_action( 'admin_init', [ $this, 'admin_init' ] );
29
+ parent::__construct( 'block', 'Users' );
30
+ }
31
+
32
+ /**
33
+ * {@inheritDoc}
34
+ *
35
+ * @since 4.0.0
36
+ */
37
+ public function admin_init()
38
+ {
39
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
40
+ add_settings_section(
41
+ 'wp-fail2ban-block',
42
+ __( 'Block' ),
43
+ [ $this, 'section' ],
44
+ 'wp-fail2ban-block'
45
+ );
46
+ add_settings_field(
47
+ 'block-user-enumeration',
48
+ parent::doc_link( 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION', __( 'User Enumeration' ) ),
49
+ [ $this, 'userEnumeration' ],
50
+ 'wp-fail2ban-block',
51
+ 'wp-fail2ban-block'
52
+ );
53
+ add_settings_field(
54
+ 'block-users',
55
+ parent::doc_link( 'WP_FAIL2BAN_BLOCKED_USERS', __( 'Usernames' ) ),
56
+ [ $this, 'usernames' ],
57
+ 'wp-fail2ban-block',
58
+ 'wp-fail2ban-block'
59
+ );
60
+ // phpcs:enable
61
+ }
62
+
63
+ /**
64
+ * {@inheritDoc}
65
+ *
66
+ * @since 4.0.0
67
+ *
68
+ * @param array $settings
69
+ * @param array $input
70
+ */
71
+ public function sanitize( array $settings, array $input = null )
72
+ {
73
+ return $settings;
74
+ }
75
+
76
+ /**
77
+ * {@inheritDoc}
78
+ *
79
+ * @since 4.0.0
80
+ */
81
+ public function section()
82
+ {
83
+ echo '' ;
84
+ }
85
+
86
+ /**
87
+ * User Enumeration
88
+ *
89
+ * @since 4.0.0
90
+ */
91
+ public function userEnumeration()
92
+ {
93
+ printf( '<input type="checkbox" disabled="disabled" %s>', checked( WP_FAIL2BAN_BLOCK_USER_ENUMERATION, true, false ) );
94
+ }
95
+
96
+ /**
97
+ * Blocked usernames
98
+ *
99
+ * @since 4.0.0
100
+ */
101
+ public function usernames()
102
+ {
103
+
104
+ if ( defined( 'WP_FAIL2BAN_BLOCKED_USERS' ) ) {
105
+
106
+ if ( is_array( WP_FAIL2BAN_BLOCKED_USERS ) ) {
107
+ $value = join( ', ', WP_FAIL2BAN_BLOCKED_USERS );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  } else {
109
+ $value = WP_FAIL2BAN_BLOCKED_USERS;
110
  }
111
+
112
+ } else {
113
+ $value = '';
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
+
116
+ printf( '<input class="regular-text" type="text" disabled="disabled" value="%s">', esc_attr( $value ) );
117
  }
 
118
 
119
+ }
120
+ new TabBlock();
admin/config/logging.php CHANGED
@@ -1,182 +1,189 @@
1
  <?php
 
2
  /**
3
  * Settings - Logging
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Tab: Logging
13
  *
14
  * @since 4.0.0
15
  */
16
- class TabLogging extends TabBase
17
  {
18
- /**
19
- * {@inheritDoc}
20
- */
21
- public function __construct()
22
- {
23
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
24
- $this->__['what-where'] = __('What & Where', 'wp-fail2ban');
25
- $this->__['authentication'] = __('Authentication', 'wp-fail2ban');
26
- $this->__['comments'] = __('Comments', 'wp-fail2ban');
27
- $this->__['spam'] = __('Spam', 'wp-fail2ban');
28
- $this->__['password-request'] = __('Password Requests', 'wp-fail2ban');
29
- $this->__['pingbacks'] = __('Pingbacks', 'wp-fail2ban');
30
- // phpcs:enable
31
-
32
- parent::__construct('logging', __('Logging', 'wp-fail2ban'));
33
- }
34
-
35
- /**
36
- * {@inheritDoc}
37
- *
38
- * @since 4.0.0
39
- */
40
- public function admin_init()
41
- {
42
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
43
- add_settings_section('wp-fail2ban-logging', $this->__['what-where'], [$this, 'sectionWhatWhere'],'wp-fail2ban-logging');
44
- add_settings_field('logging-log-authentication', $this->__['authentication'], [$this, 'authentication'], 'wp-fail2ban-logging', 'wp-fail2ban-logging');
45
- add_settings_field('logging-log-comments', $this->__['comments'], [$this, 'comments'], 'wp-fail2ban-logging', 'wp-fail2ban-logging');
46
- add_settings_field('logging-log-spam', $this->__['spam'], [$this, 'spam'], 'wp-fail2ban-logging', 'wp-fail2ban-logging');
47
- add_settings_field('logging-log-password-request', $this->__['password-request'], [$this, 'passwordRequest'], 'wp-fail2ban-logging', 'wp-fail2ban-logging');
48
- add_settings_field('logging-log-pingbacks', $this->__['pingbacks'], [$this, 'pingbacks'], 'wp-fail2ban-logging', 'wp-fail2ban-logging');
49
- // phpcs:enable
50
- }
51
-
52
- /**
53
- * {@inheritDoc}
54
- *
55
- * @since 4.3.0
56
- */
57
- public function current_screen()
58
- {
59
- $fmt = <<<___FMT___
60
- <dl><style>dt{font-weight:bold;}</style>
61
- <dt>%s</dt><dd>%s</dd>
62
- <dt>%s</dt><dd>%s</dd>
63
- <dt>%s</dt><dd>%s</dd>
64
- <dt>%s</dt><dd>%s</dd>
65
- <dt>%s</dt><dd>%s</dd>
66
- </dl>
67
- ___FMT___;
68
- get_current_screen()->add_help_tab([
69
- 'id' => 'what-where',
70
- 'title' => $this->__['what-where'],
71
- 'content' => sprintf(
72
- $fmt,
73
- $this->__['authentication'],
74
- $this->see_also([
75
- 'WP_FAIL2BAN_AUTH_LOG'
76
- ]),
77
- $this->__['comments'],
78
- $this->see_also([
79
- 'WP_FAIL2BAN_LOG_COMMENTS',
80
- 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA',
81
- 'WP_FAIL2BAN_COMMENT_EXTRA_LOG'
82
- ]),
83
- $this->__['spam'],
84
- $this->see_also([
85
- 'WP_FAIL2BAN_LOG_SPAM',
86
- 'WP_FAIL2BAN_SPAM_LOG'
87
- ]),
88
- $this->__['password-request'],
89
- $this->see_also([
90
- 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST',
91
- 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG'
92
- ]),
93
- $this->__['pingbacks'],
94
- $this->see_also([
95
- 'WP_FAIL2BAN_LOG_PINGBACKS',
96
- 'WP_FAIL2BAN_PINGBACK_LOG'
97
- ])
98
- )
99
- ]);
100
- parent::current_screen();
101
- }
102
-
103
- /**
104
- * Section summary.
105
- *
106
- * @since 4.0.0
107
- */
108
- public function sectionWhatWhere()
109
- {
110
- // noop
111
- }
112
-
113
- /**
114
- * Authentication.
115
- *
116
- * @since 4.0.0
117
- */
118
- public function authentication()
119
- {
120
- printf(
121
- '<label>%s: %s</label><p class="description">%s</p>',
122
- __('Use facility', 'wp-fail2ban'),
123
- $this->getLogFacilities('WP_FAIL2BAN_AUTH_LOG', true),
124
- Config::desc('WP_FAIL2BAN_AUTH_LOG')
125
- );
126
- }
127
-
128
- /**
129
- * Comments.
130
- *
131
- * @since 4.0.0
132
- */
133
- public function comments()
134
- {
135
- add_filter('wp_fail2ban_log_WP_FAIL2BAN_LOG_COMMENTS', [$this, 'commentsExtra'], 10, 3);
136
-
137
- $this->log(
138
- 'WP_FAIL2BAN_LOG_COMMENTS',
139
- 'WP_FAIL2BAN_COMMENT_LOG',
140
- ['comments-extra', 'logging-comments-extra-facility']
141
- );
142
- }
143
-
144
- /**
145
- * Comments extra helper - checked.
146
- *
147
- * @since 4.0.0
148
- *
149
- * @param int $value Value to check
150
- */
151
- protected function commentExtraChecked($value)
152
- {
153
- return checked($value == ($value & Config::get('WP_FAIL2BAN_LOG_COMMENTS_EXTRA')), true, false);
154
- }
155
-
156
- /**
157
- * Comments extra helper - disabled.
158
- *
159
- * @since 4.0.0
160
- */
161
- protected function commentExtraDisabled()
162
- {
163
- return 'disabled="disabled';
164
  }
165
-
166
- /**
167
- * Comments extra.
168
- *
169
- * @since 4.0.0
170
- *
171
- * @param string $html HTML prefixed to output
172
- * @param string $define_name Not used
173
- * @param string $define_log Not used
174
- *
175
- * @return string
176
- */
177
- public function commentsExtra($html, $define_name, $define_log)
178
- {
179
- $fmt = <<< ___HTML___
 
 
 
 
 
 
 
 
 
 
 
 
180
  <table>
181
  <tr>
182
  <th>%s</th>
@@ -196,63 +203,53 @@ ___FMT___;
196
  </tr>
197
  </table>
198
  ___HTML___;
199
-
200
- return $html.sprintf(
201
- $fmt,
202
- __('Also log:', 'wp-fail2ban'),
203
- $this->commentExtraChecked(WPF2B_EVENT_COMMENT_NOT_FOUND),
204
- __('Post not found', 'wp-fail2ban'),
205
- $this->commentExtraChecked(WPF2B_EVENT_COMMENT_CLOSED),
206
- __('Comments closed', 'wp-fail2ban'),
207
- $this->commentExtraChecked(WPF2B_EVENT_COMMENT_TRASH),
208
- __('Trash post', 'wp-fail2ban'),
209
- $this->commentExtraChecked(WPF2B_EVENT_COMMENT_DRAFT),
210
- __('Draft post', 'wp-fail2ban'),
211
- $this->commentExtraChecked(WPF2B_EVENT_COMMENT_PASSWORD),
212
- __('Password-protected post', 'wp-fail2ban'),
213
- __('Use facility:', 'wp-fail2ban'),
214
- $this->getLogFacilities('WP_FAIL2BAN_COMMENT_EXTRA_LOG', false)
215
- );
216
- }
217
-
218
- /**
219
- * Password request
220
- *
221
- * @since 4.0.0
222
- */
223
- public function passwordRequest()
224
- {
225
- $this->log(
226
- 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST',
227
- 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG'
228
- );
229
- }
230
-
231
- /**
232
- * Pingbacks
233
- *
234
- * @since 4.0.0
235
- */
236
- public function pingbacks()
237
- {
238
- $this->log(
239
- 'WP_FAIL2BAN_LOG_PINGBACKS',
240
- 'WP_FAIL2BAN_PINGBACK_LOG'
241
- );
242
- }
243
-
244
- /**
245
- * Spam
246
- *
247
- * @since 4.0.0
248
- */
249
- public function spam()
250
- {
251
- $this->log(
252
- 'WP_FAIL2BAN_LOG_SPAM',
253
- 'WP_FAIL2BAN_SPAM_LOG'
254
- );
255
- }
256
  }
257
- }
258
 
 
 
1
  <?php
2
+
3
  /**
4
  * Settings - Logging
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
+ namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Tab: Logging
16
+ *
17
+ * @since 4.0.0
18
+ */
19
+ class TabLogging extends Tab
20
+ {
21
+ /**
22
+ * {@inheritDoc}
23
+ */
24
+ public function __construct()
25
+ {
26
+ add_action( 'admin_init', [ $this, 'admin_init' ], 100 );
27
+ parent::__construct( 'logging', 'Logging' );
28
+ }
29
+
30
  /**
31
+ * {@inheritDoc}
32
  *
33
  * @since 4.0.0
34
  */
35
+ public function admin_init()
36
  {
37
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
38
+ add_settings_section(
39
+ 'wp-fail2ban-logging',
40
+ __( 'What & Where' ),
41
+ [ $this, 'sectionWhatWhere' ],
42
+ 'wp-fail2ban-logging'
43
+ );
44
+ add_settings_field(
45
+ 'logging-log-authentication',
46
+ parent::doc_link( 'WP_FAIL2BAN_AUTH_LOG', __( 'Authentication' ) ),
47
+ [ $this, 'authentication' ],
48
+ 'wp-fail2ban-logging',
49
+ 'wp-fail2ban-logging'
50
+ );
51
+ add_settings_field(
52
+ 'logging-log-comments',
53
+ parent::doc_link( 'WP_FAIL2BAN_LOG_COMMENTS', __( 'Comments' ) ),
54
+ [ $this, 'comments' ],
55
+ 'wp-fail2ban-logging',
56
+ 'wp-fail2ban-logging'
57
+ );
58
+ add_settings_field(
59
+ 'logging-log-spam',
60
+ parent::doc_link( 'WP_FAIL2BAN_LOG_SPAM', __( 'Spam' ) ),
61
+ [ $this, 'spam' ],
62
+ 'wp-fail2ban-logging',
63
+ 'wp-fail2ban-logging'
64
+ );
65
+ add_settings_field(
66
+ 'logging-log-password-request',
67
+ parent::doc_link( 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST', __( 'Password Requests' ) ),
68
+ [ $this, 'passwordRequest' ],
69
+ 'wp-fail2ban-logging',
70
+ 'wp-fail2ban-logging'
71
+ );
72
+ add_settings_field(
73
+ 'logging-log-pingbacks',
74
+ parent::doc_link( 'WP_FAIL2BAN_LOG_PINGBACKS', __( 'Pingbacks' ) ),
75
+ [ $this, 'pingbacks' ],
76
+ 'wp-fail2ban-logging',
77
+ 'wp-fail2ban-logging'
78
+ );
79
+ // phpcs:enable
80
+ }
81
+
82
+ /**
83
+ * {@inheritDoc}
84
+ *
85
+ * @since 4.0.0
86
+ */
87
+ public function render()
88
+ {
89
+ parent::render();
90
+ }
91
+
92
+ /**
93
+ * {@inheritDoc}
94
+ *
95
+ * @since 4.0.0
96
+ *
97
+ * @param array $settings {@inheritDoc}
98
+ * @param array $input {@inheritDoc}
99
+ *
100
+ * @return array {@inheritDoc}
101
+ */
102
+ public function sanitize( array $settings, array $input = null )
103
+ {
104
+ return $settings;
105
+ }
106
+
107
+ /**
108
+ * Section summary.
109
+ *
110
+ * @since 4.0.0
111
+ */
112
+ public function sectionWhatWhere()
113
+ {
114
+ echo '' ;
115
+ }
116
+
117
+ /**
118
+ * Authentication.
119
+ *
120
+ * @since 4.0.0
121
+ */
122
+ public function authentication()
123
+ {
124
+ printf( '<label>%s: %s</label>', __( 'Use facility' ), $this->getLogFacilities( 'WP_FAIL2BAN_AUTH_LOG', true ) );
125
+ }
126
+
127
+ /**
128
+ * Comments.
129
+ *
130
+ * @since 4.0.0
131
+ */
132
+ public function comments()
133
+ {
134
+ add_filter(
135
+ 'wp_fail2ban_log_WP_FAIL2BAN_LOG_COMMENTS',
136
+ [ $this, 'commentsExtra' ],
137
+ 10,
138
+ 3
139
+ );
140
+ $this->log(
141
+ 'WP_FAIL2BAN_LOG_COMMENTS',
142
+ 'WP_FAIL2BAN_COMMENT_LOG',
143
+ '',
144
+ [ 'comments-extra', 'logging-comments-extra-facility' ]
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Comments extra helper - checked.
150
+ *
151
+ * @since 4.0.0
152
+ *
153
+ * @param int $value Value to check
154
+ */
155
+ protected function commentExtraChecked( $value )
156
+ {
157
+ if ( !defined( 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA' ) ) {
158
+ return '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  }
160
+ return checked( $value & WP_FAIL2BAN_LOG_COMMENTS_EXTRA, $value, false );
161
+ }
162
+
163
+ /**
164
+ * Comments extra helper - disabled.
165
+ *
166
+ * @since 4.0.0
167
+ */
168
+ protected function commentExtraDisabled()
169
+ {
170
+ return 'disabled="disabled';
171
+ }
172
+
173
+ /**
174
+ * Comments extra.
175
+ *
176
+ * @since 4.0.0
177
+ *
178
+ * @param string $html HTML prefixed to output
179
+ * @param string $define_name Not used
180
+ * @param string $define_log Not used
181
+ *
182
+ * @return string
183
+ */
184
+ public function commentsExtra( $html, $define_name, $define_log )
185
+ {
186
+ $fmt = <<<___HTML___
187
  <table>
188
  <tr>
189
  <th>%s</th>
203
  </tr>
204
  </table>
205
  ___HTML___;
206
+ return $html . sprintf(
207
+ $fmt,
208
+ parent::doc_link( 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA', __( 'Also log:' ) ),
209
+ $this->commentExtraChecked( WPF2B_EVENT_COMMENT_NOT_FOUND ),
210
+ __( 'Post not found' ),
211
+ $this->commentExtraChecked( WPF2B_EVENT_COMMENT_CLOSED ),
212
+ __( 'Comments closed' ),
213
+ $this->commentExtraChecked( WPF2B_EVENT_COMMENT_TRASH ),
214
+ __( 'Trash post' ),
215
+ $this->commentExtraChecked( WPF2B_EVENT_COMMENT_DRAFT ),
216
+ __( 'Draft post' ),
217
+ $this->commentExtraChecked( WPF2B_EVENT_COMMENT_PASSWORD ),
218
+ __( 'Password-protected post' ),
219
+ parent::doc_link( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG', __( 'Use facility:' ) ),
220
+ $this->getLogFacilities( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG', false )
221
+ );
222
+ }
223
+
224
+ /**
225
+ * Password request
226
+ *
227
+ * @since 4.0.0
228
+ */
229
+ public function passwordRequest()
230
+ {
231
+ $this->log( 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST', 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG' );
232
+ }
233
+
234
+ /**
235
+ * Pingbacks
236
+ *
237
+ * @since 4.0.0
238
+ */
239
+ public function pingbacks()
240
+ {
241
+ $this->log( 'WP_FAIL2BAN_LOG_PINGBACKS', 'WP_FAIL2BAN_PINGBACK_LOG' );
242
+ }
243
+
244
+ /**
245
+ * Spam
246
+ *
247
+ * @since 4.0.0
248
+ */
249
+ public function spam()
250
+ {
251
+ $this->log( 'WP_FAIL2BAN_LOG_SPAM', 'WP_FAIL2BAN_SPAM_LOG' );
 
 
 
 
 
 
 
 
 
 
 
252
  }
 
253
 
254
+ }
255
+ new TabLogging();
admin/config/plugins.php CHANGED
@@ -1,124 +1,185 @@
1
  <?php
 
2
  /**
3
  * Settings - Plugins
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.2.0
7
  */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Tab: Plugins
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  *
14
  * @since 4.2.0
15
  */
16
- class TabPlugins extends TabBase
17
  {
18
- /**
19
- * {@inheritDoc}
20
- */
21
- public function __construct()
22
- {
23
- parent::__construct('plugins', __('Plugins', 'wp-fail2ban'));
24
- }
25
-
26
- /**
27
- * {@inheritDoc}
28
- *
29
- * @since 4.0.0
30
- */
31
- public function admin_init()
32
- {
33
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
34
- add_settings_section('wp-fail2ban-plugins', __('Event Class Facilities', 'wp-fail2ban'), [$this, 'sectionLoggingEventClasses'], 'wp-fail2ban-plugins');
35
- add_settings_field('plugins-log-auth', __('Authentication', 'wp-fail2ban'), [$this, 'auth'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
36
- add_settings_field('plugins-log-comment', __('Comment', 'wp-fail2ban'), [$this, 'comment'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
37
- add_settings_field('plugins-log-password', __('Password', 'wp-fail2ban'), [$this, 'password'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
38
- add_settings_field('plugins-log-rest', __('REST', 'wp-fail2ban'), [$this, 'rest'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
39
- add_settings_field('plugins-log-spam', __('Spam', 'wp-fail2ban'), [$this, 'spam'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
40
- add_settings_field('plugins-log-xmlrpc', __('XML-RPC', 'wp-fail2ban'), [$this, 'xmlrpc'], 'wp-fail2ban-plugins', 'wp-fail2ban-plugins');
41
- // phpcs:enable
42
- }
43
-
44
- /**
45
- * {@inheritDoc}
46
- *
47
- * @since 4.3.0
48
- */
49
- public function current_screen()
50
- {
51
- }
52
-
53
- /**
54
- * Section summary.
55
- *
56
- * @since 4.2.0
57
- */
58
- public function sectionLoggingEventClasses()
59
- {
60
- echo __('Facilities to use for plugin-generated messages. The defaults follow the Core defaults.', 'wp-fail2ban');
61
- }
62
-
63
- /**
64
- * Auth
65
- *
66
- * @since 4.2.0
67
- */
68
- public function auth()
69
- {
70
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_AUTH', 'WP_FAIL2BAN_PLUGIN_AUTH_LOG');
71
- }
72
-
73
- /**
74
- * Comment
75
- *
76
- * @since 4.2.0
77
- */
78
- public function comment()
79
- {
80
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_COMMENT', 'WP_FAIL2BAN_PLUGIN_COMMENT_LOG');
81
- }
82
-
83
- /**
84
- * Password
85
- *
86
- * @since 4.2.0
87
- */
88
- public function password()
89
- {
90
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_PASSWORD', 'WP_FAIL2BAN_PLUGIN_PASSWORD_LOG');
91
- }
92
-
93
- /**
94
- * REST
95
- *
96
- * @since 4.2.0
97
- */
98
- public function rest()
99
- {
100
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_REST', 'WP_FAIL2BAN_PLUGIN_REST_LOG');
101
- }
102
-
103
- /**
104
- * Spam
105
- *
106
- * @since 4.2.0
107
- */
108
- public function spam()
109
- {
110
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_SPAM', 'WP_FAIL2BAN_PLUGIN_SPAM_LOG');
111
- }
112
-
113
- /**
114
- * XML-RPC
115
- *
116
- * @since 4.2.0
117
- */
118
- public function xmlrpc()
119
- {
120
- $this->log('WP_FAIL2BAN_PLUGIN_LOG_XMLRPC', 'WP_FAIL2BAN_PLUGIN_XMLRPC_LOG');
121
- }
122
  }
123
- }
124
 
 
 
1
  <?php
2
+
3
  /**
4
  * Settings - Plugins
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.2.0
8
  */
9
+ namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Tab: Plugins
16
+ *
17
+ * @since 4.2.0
18
+ */
19
+ class TabPlugins extends Tab
20
+ {
21
  /**
22
+ * {@inheritDoc}
23
+ */
24
+ public function __construct()
25
+ {
26
+ add_action( 'admin_init', [ $this, 'admin_init' ], 100 );
27
+ parent::__construct( 'plugins', 'Plugins' );
28
+ }
29
+
30
+ /**
31
+ * {@inheritDoc}
32
+ *
33
+ * @since 4.0.0
34
+ */
35
+ public function admin_init()
36
+ {
37
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
38
+ add_settings_section(
39
+ 'wp-fail2ban-plugins',
40
+ __( 'Event Class Facilities' ),
41
+ [ $this, 'sectionLoggingEventClasses' ],
42
+ 'wp-fail2ban-plugins'
43
+ );
44
+ add_settings_field(
45
+ 'plugins-log-auth',
46
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_AUTH', __( 'Authentication' ) ),
47
+ [ $this, 'auth' ],
48
+ 'wp-fail2ban-plugins',
49
+ 'wp-fail2ban-plugins'
50
+ );
51
+ add_settings_field(
52
+ 'plugins-log-comment',
53
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_COMMENT', __( 'Comment' ) ),
54
+ [ $this, 'comment' ],
55
+ 'wp-fail2ban-plugins',
56
+ 'wp-fail2ban-plugins'
57
+ );
58
+ add_settings_field(
59
+ 'plugins-log-password',
60
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_PASSWORD', __( 'Password' ) ),
61
+ [ $this, 'password' ],
62
+ 'wp-fail2ban-plugins',
63
+ 'wp-fail2ban-plugins'
64
+ );
65
+ add_settings_field(
66
+ 'plugins-log-rest',
67
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_REST', __( 'REST' ) ),
68
+ [ $this, 'rest' ],
69
+ 'wp-fail2ban-plugins',
70
+ 'wp-fail2ban-plugins'
71
+ );
72
+ add_settings_field(
73
+ 'plugins-log-spam',
74
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_SPAM', __( 'Spam' ) ),
75
+ [ $this, 'spam' ],
76
+ 'wp-fail2ban-plugins',
77
+ 'wp-fail2ban-plugins'
78
+ );
79
+ add_settings_field(
80
+ 'plugins-log-xmlrpc',
81
+ parent::doc_link( 'WP_FAIL2BAN_PLUGIN_LOG_XMLRPC', __( 'XML-RPC' ) ),
82
+ [ $this, 'xmlrpc' ],
83
+ 'wp-fail2ban-plugins',
84
+ 'wp-fail2ban-plugins'
85
+ );
86
+ // phpcs:enable
87
+ }
88
+
89
+ /**
90
+ * {@inheritDoc}
91
  *
92
  * @since 4.2.0
93
  */
94
+ public function render()
95
  {
96
+ parent::render();
97
+ }
98
+
99
+ /**
100
+ * {@inheritDoc}
101
+ *
102
+ * @since 4.2.0
103
+ *
104
+ * @param array $settings {@inheritDoc}
105
+ * @param array $input {@inheritDoc}
106
+ *
107
+ * @return array {@inheritDoc}
108
+ */
109
+ public function sanitize( array $settings, array $input = null )
110
+ {
111
+ return $settings;
112
+ }
113
+
114
+ /**
115
+ * Section summary.
116
+ *
117
+ * @since 4.2.0
118
+ */
119
+ public function sectionLoggingEventClasses()
120
+ {
121
+ echo __( 'Facilities to use for plugin-generated messages. The defaults follow the Core defaults.' ) ;
122
+ }
123
+
124
+ /**
125
+ * Auth
126
+ *
127
+ * @since 4.2.0
128
+ */
129
+ public function auth()
130
+ {
131
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_AUTH', 'WP_FAIL2BAN_PLUGIN_AUTH_LOG' );
132
+ }
133
+
134
+ /**
135
+ * Comment
136
+ *
137
+ * @since 4.2.0
138
+ */
139
+ public function comment()
140
+ {
141
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_COMMENT', 'WP_FAIL2BAN_PLUGIN_COMMENT_LOG' );
142
+ }
143
+
144
+ /**
145
+ * Password
146
+ *
147
+ * @since 4.2.0
148
+ */
149
+ public function password()
150
+ {
151
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_PASSWORD', 'WP_FAIL2BAN_PLUGIN_PASSWORD_LOG' );
152
+ }
153
+
154
+ /**
155
+ * REST
156
+ *
157
+ * @since 4.2.0
158
+ */
159
+ public function rest()
160
+ {
161
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_REST', 'WP_FAIL2BAN_PLUGIN_REST_LOG' );
162
+ }
163
+
164
+ /**
165
+ * Spam
166
+ *
167
+ * @since 4.2.0
168
+ */
169
+ public function spam()
170
+ {
171
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_SPAM', 'WP_FAIL2BAN_PLUGIN_SPAM_LOG' );
172
+ }
173
+
174
+ /**
175
+ * XML-RPC
176
+ *
177
+ * @since 4.2.0
178
+ */
179
+ public function xmlrpc()
180
+ {
181
+ $this->log( 'WP_FAIL2BAN_PLUGIN_LOG_XMLRPC', 'WP_FAIL2BAN_PLUGIN_XMLRPC_LOG' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
 
183
 
184
+ }
185
+ new TabPlugins();
admin/config/remote-ips.php CHANGED
@@ -1,112 +1,100 @@
1
  <?php
 
2
  /**
3
  * Settings - Remote IPs
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Tab: Remote IPs
13
  *
14
  * @since 4.0.0
15
  */
16
- class TabRemoteIPs extends TabBase
17
  {
18
- /**
19
- * {@inheritDoc}
20
- *
21
- * @since 4.0.0
22
- */
23
- public function __construct()
24
- {
25
- $this->__['wp-fail2ban-proxies'] = __('Proxies', 'wp-fail2ban');
26
- $this->__['remote-ips-proxies'] = __('IP list', 'wp-fail2ban');
27
-
28
- parent::__construct('remote-ips', __('Remote IPs', 'wp-fail2ban'));
29
- }
30
-
31
- /**
32
- * {@inheritDoc}
33
- *
34
- * @since 4.0.0
35
- */
36
- public function admin_init()
37
- {
38
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
39
- add_settings_section('wp-fail2ban-proxies', $this->__['wp-fail2ban-proxies'], [$this, 'section'], 'wp-fail2ban-remote-ips');
40
- add_settings_field('remote-ips-proxies', $this->__['remote-ips-proxies'], [$this, 'proxies'], 'wp-fail2ban-remote-ips', 'wp-fail2ban-proxies');
41
- // phpcs:enable
42
- }
43
-
44
- /**
45
- * {@inheritDoc}
46
- *
47
- * @since 4.3.0
48
- */
49
- public function current_screen()
50
- {
51
- $fmt = <<<___FMT___
52
- <dl><style>dt{font-weight:bold;}</style>
53
- <dt>%s</dt>
54
- <dd><p>%s</p><p>%s</p>%s</dd>
55
- </dl>
56
- ___FMT___;
57
- get_current_screen()->add_help_tab([
58
- 'id' => 'remote-ips-proxies',
59
- 'title' => $this->__['wp-fail2ban-proxies'],
60
- 'content' => sprintf(
61
- $fmt,
62
- $this->__['remote-ips-proxies'],
63
- __('A list of IPv4 addresses in CIDR notation. The list of CloudFlare IPs can be found <a href="https://www.cloudflare.com/ips-v4" rel="noopener" target="_blank">here</a>', 'wp-fail2ban'),
64
- __('<strong>NB:</strong> IPv6 is not yet supported.', 'wp-fail2ban'),
65
- $this->doc_link('WP_FAIL2BAN_PROXIES')
66
- )
67
- ]);
68
- parent::current_screen();
69
- }
70
-
71
- /**
72
- * Section blurb.
73
- *
74
- * @since 4.0.0
75
- */
76
- public function section()
77
- {
78
- echo '';
79
- }
80
-
81
- /**
82
- * Helper - multi-line string from proxies list.
83
- *
84
- * @since 4.3.0
85
- *
86
- * @return string
87
- */
88
- protected function proxies_value()
89
- {
90
- $proxies = Config::get('WP_FAIL2BAN_PROXIES');
91
- return (is_array($proxies))
92
- ? join("\n", $proxies)
93
- : join("\n", array_map('trim', explode(',', $proxies)));
94
- }
95
-
96
- /**
97
- * Proxies.
98
- *
99
- * @since 4.3.0 Refactored.
100
- * @since 4.0.0
101
- */
102
- public function proxies()
103
- {
104
- printf(
105
- '<fieldset><textarea class="code" cols="20" rows="10" disabled="disabled">%s</textarea></fieldset>',
106
- esc_html($this->proxies_value())
107
- );
108
- $this->description('WP_FAIL2BAN_PROXIES');
109
  }
 
110
  }
111
- }
112
 
 
 
1
  <?php
2
+
3
  /**
4
  * Settings - Remote IPs
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
+ namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Tab: Remote IPs
16
+ *
17
+ * @since 4.0.0
18
+ */
19
+ class TabRemoteIPs extends Tab
20
+ {
21
  /**
22
+ * {@inheritDoc}
23
  *
24
  * @since 4.0.0
25
  */
26
+ public function __construct()
27
  {
28
+ add_action( 'admin_init', [ $this, 'admin_init' ] );
29
+ parent::__construct( 'remote-ips', 'Remote IPs' );
30
+ }
31
+
32
+ /**
33
+ * {@inheritDoc}
34
+ *
35
+ * @since 4.0.0
36
+ */
37
+ public function admin_init()
38
+ {
39
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
40
+ add_settings_section(
41
+ 'wp-fail2ban-proxies',
42
+ __( 'Proxies' ),
43
+ [ $this, 'section' ],
44
+ 'wp-fail2ban-remote-ips'
45
+ );
46
+ add_settings_field(
47
+ 'remote-ips-proxies',
48
+ parent::doc_link( 'WP_FAIL2BAN_PROXIES', __( 'IP list' ) ),
49
+ [ $this, 'proxies' ],
50
+ 'wp-fail2ban-remote-ips',
51
+ 'wp-fail2ban-proxies'
52
+ );
53
+ // phpcs:enable
54
+ }
55
+
56
+ /**
57
+ * {@inheritDoc}
58
+ *
59
+ * @since 4.0.0
60
+ *
61
+ * @param array $settings
62
+ * @param array $input
63
+ */
64
+ public function sanitize( array $settings, array $input = null )
65
+ {
66
+ return $settings;
67
+ }
68
+
69
+ /**
70
+ * Section blurb.
71
+ *
72
+ * @since 4.0.0
73
+ */
74
+ public function section()
75
+ {
76
+ echo '' ;
77
+ }
78
+
79
+ /**
80
+ * Proxies.
81
+ *
82
+ * @since 4.0.0
83
+ */
84
+ public function proxies()
85
+ {
86
+ $value = '';
87
+ if ( defined( 'WP_FAIL2BAN_PROXIES' ) ) {
88
+
89
+ if ( is_array( WP_FAIL2BAN_PROXIES ) ) {
90
+ $value = join( "\n", WP_FAIL2BAN_PROXIES );
91
+ } else {
92
+ $value = join( "\n", array_map( 'trim', explode( ',', WP_FAIL2BAN_PROXIES ) ) );
93
+ }
94
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
+ printf( '<fieldset><textarea class="code" cols="20" rows="10" disabled="disabled">%s</textarea></fieldset>', esc_html( $value ) );
97
  }
 
98
 
99
+ }
100
+ new TabRemoteIPs();
admin/config/syslog.php CHANGED
@@ -1,137 +1,103 @@
1
  <?php
 
2
  /**
3
  * Settings - syslog
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Tab: Syslog
 
 
 
 
 
 
 
 
 
13
  *
14
  * @since 4.0.0
15
  */
16
- class TabSyslog extends TabBase
17
  {
18
- /**
19
- * {@inheritDoc}
20
- */
21
- public function __construct()
22
- {
23
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
24
- $this->__['wp-fail2ban-connection'] = __('Connection', 'wp-fail2ban');
25
- $this->__['syslog-connection-options'] = __('Options', 'wp-fail2ban');
26
- $this->__['wp-fail2ban-workarounds'] = __('Workarounds', 'wp-fail2ban');
27
- $this->__['syslog-workarounds'] = __('Options', 'wp-fail2ban');
28
- // phpcs:enable
29
-
30
- parent::__construct('syslog', 'syslog');
31
- }
32
-
33
- /**
34
- * {@inheritDoc}
35
- *
36
- * @since 4.0.0
37
- */
38
- public function admin_init()
39
- {
40
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
41
- add_settings_section('wp-fail2ban-connection', $this->__['wp-fail2ban-connection'], [$this, 'sectionConnection'], 'wp-fail2ban-syslog');
42
- add_settings_field('syslog-connection-options', $this->__['syslog-connection-options'], [$this, 'connection'], 'wp-fail2ban-syslog', 'wp-fail2ban-connection');
43
-
44
- add_settings_section('wp-fail2ban-workarounds', $this->__['wp-fail2ban-workarounds'], [$this, 'sectionWorkarounds'], 'wp-fail2ban-syslog');
45
- add_settings_field('syslog-workarounds', $this->__['syslog-workarounds'], [$this, 'workarounds'], 'wp-fail2ban-syslog', 'wp-fail2ban-workarounds');
46
- // phpcs:enable
47
- }
48
-
49
- /**
50
- * {@inheritDoc}
51
- *
52
- * @since 4.3.0
53
- */
54
- public function current_screen()
55
- {
56
- $fmt = <<<___FMT___
57
- <p>%s</p>
58
- <table><style>th{text-align:left;vertical-align:top;}</style>
59
- <tr><th scope="row">LOG_CONS</th><td>%s</td></tr>
60
- <tr><th scope="row">LOG_NDELAY</th><td>%s</td></tr>
61
- <tr><th scope="row">LOG_ODELAY</th><td>%s</td></tr>
62
- <tr><th scope="row">LOG_PERROR</th><td>%s</td></tr>
63
- <tr><th scope="row">LOG_PID</th><td>%s</td></tr>
64
- </table>
65
- %s
66
- ___FMT___;
67
- get_current_screen()->add_help_tab([
68
- 'id' => 'syslog-connection-options',
69
- 'title' => $this->__['wp-fail2ban-connection'],
70
- 'content' => sprintf(
71
- $fmt,
72
- __('Used to indicate what logging options will be used when generating a log message.', 'wp-fail2ban'),
73
- __('if there is an error while sending data to the system logger, write directly to the system console', 'wp-fail2ban'),
74
- __('open the connection to the logger immediately', 'wp-fail2ban'),
75
- __('(default) delay opening the connection until the first message is logged', 'wp-fail2ban'),
76
- __('print log message also to standard error', 'wp-fail2ban'),
77
- __('include PID with each message', 'wp-fail2ban'),
78
- $this->see_also(['WP_FAIL2BAN_OPENLOG_OPTIONS'])
79
- )
80
- ]);
81
- $fmt = <<<___FMT___
82
- <p>%s</p>
83
- <p>%s</p>
84
- <dl><style>dt{font-weight:bold;}</style>
85
- <dt>%s</dt>
86
- <dd><p>%s</p>%s</dd>
87
- <dt>%s</dt>
88
- <dd><p>%s</p>%s</dd>
89
- <dt>%s</dt>
90
- <dd><p>%s</p><p>%s</p>%s</dd>
91
- </dl>
92
- ___FMT___;
93
- get_current_screen()->add_help_tab([
94
- 'id' => 'syslog-workarounds',
95
- 'title' => $this->__['wp-fail2ban-workarounds'],
96
- 'content' => sprintf(
97
- $fmt,
98
- __('<tt>syslog</tt> was only <a href="https://tools.ietf.org/html/rfc5424" target="_blank">standardised</a> in 2009, so unfortunately there are still implementations that need some help.', 'wp-fail2ban'),
99
- __('By far the most common limitation is the length of the initial information fields; these options provide ways to shorten the data in those fields.', 'wp-fail2ban'),
100
- __('Short Tag', 'wp-fail2ban'),
101
- __('Some syslog implementations assume that the first part of the message (the tag) won&lsquo;t exceed some (small) number of characters. This option tells <em>WPf2b</em> to use <tt>wp</tt> instead of <tt>wordpress</tt>, thereby saving 7 characters; this may be enough to make syslog happy.', 'wp-fail2ban'),
102
- $this->see_also(['WP_FAIL2BAN_SYSLOG_SHORT_TAG']),
103
- __('Specify Host', 'wp-fail2ban'),
104
- __('"Short Tag" may not be enough, so this allows you to specify the hostname. See the <a href="https://docs.wp-fail2ban.com/en/___WPF2BVER___/defines/constants/WP_FAIL2BAN_HTTP_HOST.html" target="_blank">documentation</a> for more details.', 'wp-fail2ban'),
105
- $this->see_also(['WP_FAIL2BAN_HTTP_HOST']),
106
- __('Truncate Host', 'wp-fail2ban'),
107
- __('When all else fails, this allows you to truncate the hostname after a number of characters.', 'wp-fail2ban'),
108
- __('<strong>N.B.</strong> This may be removed in a future release; it was broken prior to 4.3 and there were no bug reports, so it seems likely absolutely no-one is using it.', 'wp-fail2ban'),
109
- $this->see_also(['WP_FAIL2BAN_TRUNCATE_HOST'])
110
- )
111
- ]);
112
-
113
- parent::current_screen();
114
- }
115
-
116
- /**
117
- * Connection section blurb.
118
- *
119
- * @since 4.0.0
120
- */
121
- public function sectionConnection()
122
- {
123
- echo '';
124
- }
125
-
126
- /**
127
- * Connection.
128
- *
129
- * @since 4.3.0 Refactor to premium.
130
- * @since 4.0.0
131
- */
132
- public function connection()
133
- {
134
- $fmt = <<<___STR___
135
  <fieldset>
136
  <label><input type="checkbox" disabled="disabled" %s> <code>LOG_CONS</code></label><br>
137
  <label><input type="checkbox" disabled="disabled" %s> <code>LOG_PERROR</code></label><br>
@@ -140,37 +106,36 @@ ___FMT___;
140
  <label><input type="radio" disabled="disabled" %s> <code>LOG_ODELAY</code></label>
141
  </fieldset>
142
  ___STR___;
143
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing, PSR2.Methods.FunctionCallSignature.MultipleArguments
144
- printf(
145
- $fmt,
146
- checked(WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_CONS, LOG_CONS, false),
147
- checked(WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_PERROR, LOG_PERROR, false),
148
- checked(WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_PID, LOG_PID, false), __('default'),
149
- checked(WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_NDELAY, LOG_NDELAY, false), __('default'),
150
- checked(WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_ODELAY, LOG_ODELAY, false)
151
- );
152
- // phpcs:enable
153
- }
154
-
155
- /**
156
- * Workarounds section blurb.
157
- *
158
- * @since 4.0.0
159
- */
160
- public function sectionWorkarounds()
161
- {
162
- echo '';
163
- }
164
-
165
- /**
166
- * Workarounds.
167
- *
168
- * @since 4.3.0 Refactor to premium.
169
- * @since 4.0.0
170
- */
171
- public function workarounds()
172
- {
173
- $fmt = <<<___STR___
174
  <fieldset>
175
  <label><input type="checkbox" disabled="disabled" %s> %s</label>
176
  <br>
@@ -179,16 +144,16 @@ ___STR___;
179
  <label><input type="checkbox" disabled="disabled" %s> %s</label>
180
  </fieldset>
181
  ___STR___;
182
- printf(
183
- $fmt,
184
- checked(@WP_FAIL2BAN_SYSLOG_SHORT_TAG, true, false),
185
- __('Short Tag', 'wp-fail2ban'),
186
- checked(@WP_FAIL2BAN_HTTP_HOST, true, false),
187
- __('Specify Host', 'wp-fail2ban'),
188
- checked(@WP_FAIL2BAN_TRUNCATE_HOST, true, false),
189
- __('Truncate Host', 'wp-fail2ban')
190
- );
191
- }
192
  }
193
- }
194
 
 
 
1
  <?php
2
+
3
  /**
4
  * Settings - syslog
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
+ namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Tab: Syslog
16
+ *
17
+ * @since 4.0.0
18
+ */
19
+ class TabSyslog extends Tab
20
+ {
21
  /**
22
+ * {@inheritDoc}
23
+ */
24
+ public function __construct()
25
+ {
26
+ add_action( 'admin_init', [ $this, 'admin_init' ], 100 );
27
+ parent::__construct( 'syslog', '<tt>syslog</tt>' );
28
+ }
29
+
30
+ /**
31
+ * {@inheritDoc}
32
  *
33
  * @since 4.0.0
34
  */
35
+ public function admin_init()
36
  {
37
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
38
+ add_settings_section(
39
+ 'wp-fail2ban-connection',
40
+ __( 'Connection' ),
41
+ [ $this, 'sectionConnection' ],
42
+ 'wp-fail2ban-syslog'
43
+ );
44
+ add_settings_field(
45
+ 'logging-connection',
46
+ parent::doc_link( 'WP_FAIL2BAN_OPENLOG_OPTIONS', __( 'Options' ) ),
47
+ [ $this, 'connection' ],
48
+ 'wp-fail2ban-syslog',
49
+ 'wp-fail2ban-connection'
50
+ );
51
+ add_settings_section(
52
+ 'wp-fail2ban-workarounds',
53
+ __( 'Workarounds' ),
54
+ [ $this, 'sectionWorkarounds' ],
55
+ 'wp-fail2ban-syslog'
56
+ );
57
+ add_settings_field(
58
+ 'logging-workarounds',
59
+ parent::doc_link( '../syslog', __( 'Options' ) ),
60
+ [ $this, 'workarounds' ],
61
+ 'wp-fail2ban-syslog',
62
+ 'wp-fail2ban-workarounds'
63
+ );
64
+ // phpcs:enable
65
+ }
66
+
67
+ /**
68
+ * {@inheritDoc}
69
+ *
70
+ * @since 4.0.0
71
+ *
72
+ * @param array $settings {@inheritDoc}
73
+ * @param array $input {@inheritDoc}
74
+ *
75
+ * @return array {@inheritDoc}
76
+ */
77
+ public function sanitize( array $settings, array $input = null )
78
+ {
79
+ return $settings;
80
+ }
81
+
82
+ /**
83
+ * Connection section blurb.
84
+ *
85
+ * @since 4.0.0
86
+ */
87
+ public function sectionConnection()
88
+ {
89
+ echo '' ;
90
+ }
91
+
92
+ /**
93
+ * Connection.
94
+ *
95
+ * @since 4.0.0
96
+ */
97
+ public function connection()
98
+ {
99
+ $class = '';
100
+ $fmt = <<<___STR___
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  <fieldset>
102
  <label><input type="checkbox" disabled="disabled" %s> <code>LOG_CONS</code></label><br>
103
  <label><input type="checkbox" disabled="disabled" %s> <code>LOG_PERROR</code></label><br>
106
  <label><input type="radio" disabled="disabled" %s> <code>LOG_ODELAY</code></label>
107
  </fieldset>
108
  ___STR___;
109
+ printf(
110
+ $fmt,
111
+ checked( WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_CONS, LOG_CONS, false ),
112
+ checked( WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_PERROR, LOG_PERROR, false ),
113
+ checked( WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_PID, LOG_PID, false ),
114
+ __( 'default' ),
115
+ checked( WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_NDELAY, LOG_NDELAY, false ),
116
+ __( 'default' ),
117
+ checked( WP_FAIL2BAN_OPENLOG_OPTIONS & LOG_ODELAY, LOG_ODELAY, false )
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Workarounds section blurb.
123
+ *
124
+ * @since 4.0.0
125
+ */
126
+ public function sectionWorkarounds()
127
+ {
128
+ echo '' ;
129
+ }
130
+
131
+ /**
132
+ * Workarounds.
133
+ *
134
+ * @since 4.0.0
135
+ */
136
+ public function workarounds()
137
+ {
138
+ $fmt = <<<___STR___
 
139
  <fieldset>
140
  <label><input type="checkbox" disabled="disabled" %s> %s</label>
141
  <br>
144
  <label><input type="checkbox" disabled="disabled" %s> %s</label>
145
  </fieldset>
146
  ___STR___;
147
+ printf(
148
+ $fmt,
149
+ checked( @WP_FAIL2BAN_SYSLOG_SHORT_TAG, true, false ),
150
+ __( 'Short Tag' ),
151
+ checked( @WP_FAIL2BAN_HTTP_HOST, true, false ),
152
+ __( 'Specify Host' ),
153
+ checked( @WP_FAIL2BAN_TRUNCATE_HOST, true, false ),
154
+ __( 'Truncate Host' )
155
+ );
 
156
  }
 
157
 
158
+ }
159
+ new TabSyslog();
admin/lib/about.php CHANGED
@@ -1,142 +1,191 @@
1
  <?php
2
-
3
  /**
4
  * About
5
  *
6
  * @package wp-fail2ban
7
- * @since 4.2.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
 
 
 
11
 
12
- if ( defined( 'ABSPATH' ) ) {
13
- /**
14
- * Pull in extra "about" information
15
- *
16
- * @since 4.3.0
17
- *
18
- * @return string
19
- */
20
- function _get_extra_about()
21
- {
22
- $extra = '';
23
- /**
24
- * Don't make a remote call if the user hasn't opted in
25
- */
26
-
27
- if ( !wf_fs()->is_tracking_prohibited() ) {
28
- $extra = get_site_transient( 'wp_fail2ban_extra_about' );
29
-
30
- if ( false === apply_filters( 'wp_fail2ban_extra_about_transient', $extra ) ) {
31
- $url = apply_filters( 'wp_fail2ban_extra_about_url', 'https://wp-fail2ban.com/extra-about/?version=' . $wp_f2b_ver );
32
-
33
- if ( !is_wp_error( $rv = wp_remote_get( $url ) ) ) {
34
- /**
35
- * Try not to fetch more than once per day
36
- */
37
- set_site_transient( 'wp_fail2ban_extra_about', $rv['body'], DAY_IN_SECONDS );
38
- $extra = $rv['body'];
39
- }
40
-
41
- }
42
-
43
- }
44
-
45
- return $extra;
46
  }
47
-
48
- /**
49
- * About content
50
- *
51
- * @since 4.2.0
52
- *
53
- * @param bool $hide_title
54
- */
55
- function about( $hide_title = false )
56
- {
57
- $wp_f2b_ver = substr( WP_FAIL2BAN_VER, 0, strrpos( WP_FAIL2BAN_VER, '.' ) );
58
- $extra = _get_extra_about();
59
- ?>
60
- <div class="wrap">
61
- <style>
62
- div.inside ul {
63
- list-style: disc;
64
- padding-left: 2em;
65
- }
66
- </style>
67
- <?php
68
- if ( !$hide_title ) {
69
- ?>
70
- <h1>WP fail2ban</h1>
71
- <?php
72
- }
73
- ?>
74
- <div id="poststuff">
75
- <div id="post-body" class="metabox-holder columns-2">
76
- <div id="post-body-content">
77
- <div class="meta-box-sortables ui-sortable">
78
- <?php
79
- echo $extra ;
80
- ?>
81
- <div class="postbox">
82
- <h2>Version 4.3.0</h2>
83
- <div class="inside">
84
- <ul>
85
- <li>Add full multisite support. See <a href="https://wp-fail2ban.com/blog/changes-to-multisite-support/" rel="noopener" target="_blank">here</a> for more information.</li>
86
- <li>Add separate logging for empty usernames.</li>
87
- <li>Improve user enumeration blocking compatibility with the WordPress block editor (Gutenberg).</li>
88
- <li>Log extra information for events <em>(premium)</em>.</li>
89
- <li>Add new event class for blocked actions <em>(premium)</em>.</li>
90
- </ul>
91
- </div>
92
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  </div>
94
  </div>
95
- <div id="postbox-container-1" class="postbox-container">
96
- <div class="meta-box-sortables">
97
- <div class="postbox">
98
- <h2>Getting Started</h2>
99
- <div class="inside">
100
- <ol>
101
- <li><a href="https://docs.wp-fail2ban.com/en/<?php
102
- echo $wp_f2b_ver ;
103
- ?>/introduction.html" rel="noopener" target="docs.wp-fail2ban.com">Introduction</a></li>
104
- <li><a href="https://docs.wp-fail2ban.com/en/<?php
105
- echo $wp_f2b_ver ;
106
- ?>/configuration.html" rel="noopener" target="docs.wp-fail2ban.com">Configuration</a></li>
107
- </ol>
108
- </div>
109
- </div>
110
- <div class="postbox">
111
- <h2>Getting Help</h2>
112
- <div class="inside">
113
- <ul>
114
- <?php
115
-
116
- if ( wf_fs()->is_trial() ) {
117
- ?>
118
- <li><a href="https://forums.invis.net/c/wp-fail2ban/support-trial/" rel="noopener" target="_blank">Trial Support Forum</a></li>
119
- <?php
120
- } elseif ( wf_fs()->is_free_plan() ) {
121
- ?>
122
- <li><a href="https://forums.invis.net/c/wp-fail2ban/support-free/" rel="noopener" target="_blank">Free Support Forum</a></li>
123
- <?php
124
- }
125
-
126
- ?>
127
- <?php
128
- ?>
129
- <?php
130
- ?>
131
- </div>
132
- </div>
 
 
 
 
 
 
 
 
 
 
 
133
  </div>
134
  </div>
135
  </div>
136
- &nbsp;
137
  </div>
138
  </div>
139
- <?php
140
- }
141
-
 
142
  }
 
1
  <?php
 
2
  /**
3
  * About
4
  *
5
  * @package wp-fail2ban
6
+ * @since 4.2.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
+ if (!defined('ABSPATH')) {
11
+ exit;
12
+ }
13
 
14
+ /**
15
+ * About content
16
+ *
17
+ * @since 4.2.0
18
+ *
19
+ * @param bool $hide_title
20
+ */
21
+ function about($hide_title = false)
22
+ {
23
+ $wp_f2b_ver = substr(WP_FAIL2BAN_VER, 0, strrpos(WP_FAIL2BAN_VER, '.'));
24
+ $notice = version_compare(PHP_VERSION, '5.6.0', '<');
25
+ ?>
26
+ <div class="wrap">
27
+ <style>
28
+ div.inside ul {
29
+ list-style: disc;
30
+ padding-left: 2em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
+ </style>
33
+ <?php if (!$hide_title): ?>
34
+ <h1>WP fail2ban</h1>
35
+ <?php endif; ?>
36
+ <div id="poststuff">
37
+ <div id="post-body" class="metabox-holder columns-2">
38
+ <div id="post-body-content">
39
+ <div class="meta-box-sortables ui-sortable">
40
+ <div class="postbox">
41
+ <h2>Version 4.2.8</h2>
42
+ <div class="inside">
43
+ <h4>News</h4>
44
+ <ul>
45
+ <?php if (strtotime('1 May 2020') > time()): ?>
46
+ <li><a href="https://forums.invis.net/?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="_blank"><strong>Support has moved</strong></a>. Please come join the new <em>WPf2b</em> community!</li>
47
+ <?php endif; ?>
48
+ <li><a href="https://wp-fail2ban.com/blog/2020/04/16/testers-needed-v4-3-0-is-imminent/?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="_blank">Testers needed</a>! Version 4.3.0 will be released soon - I need your help to make sure it works properly.</li>
49
+ <?php if ($notice): ?>
50
+ <li><strong>This is the last release that supports PHP <?php echo PHP_VERSION; ?></strong>.<br>The <strong>minimum version</strong> required for <strong>v4.3.0</strong> is <strong>PHP 5.6</strong>.<br>Please <a href="https://wordpress.org/support/update-php/" target="_blank"><strong>update your PHP</strong></a>.</li>
51
+ <?php endif; ?>
52
+ </ul>
53
+ <h4>Changes</h4>
54
+ <ul>
55
+ <li>Add link to new <a href="https://forums.invis.net/c/wp-fail2ban/?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="_blank">support forum</a>.</li>
56
+ <li>Fix user enumeration conflict with Gutenberg (h/t @dinghy).</li>
57
+ <li>Fix notices wrt admin menu (h/t @marioivangf).</li>
58
+ <li>Fix harmless XDebug notice (h/t @dinghy).</li>
59
+ <li>Update Freemius library.</li>
60
+ </ul>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ <div class="meta-box-sortables ui-sortable">
65
+ <div class="postbox">
66
+ <h2>Version 4.2.7.1</h2>
67
+ <div class="inside">
68
+ <ul>
69
+ <li>Fix error when blocking user enumeration via <tt>oembed</tt>.</li>
70
+ </ul>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ <div class="meta-box-sortables ui-sortable">
75
+ <div class="postbox">
76
+ <h2>Version 4.2.7</h2>
77
+ <div class="inside">
78
+ <ul>
79
+ <li>Fix error when blocking user enumeration via REST.</li>
80
+ <li>Fix buttons on Settings tabs.</li>
81
+ </ul>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ <div class="meta-box-sortables ui-sortable">
86
+ <div class="postbox">
87
+ <h2>Version 4.2.6</h2>
88
+ <div class="inside">
89
+ <ul>
90
+ <li>Add support for <a href="<?php echo admin_url('admin.php?page=wp-fail2ban-tools'); ?>">Remote Tools</a> add-on.
91
+ <li>Add support for the new ClassicPress security page.</li>
92
+ <li>Improved user enumeration blocking.</li>
93
+ </ul>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ <div class="meta-box-sortables ui-sortable">
98
+ <div class="postbox">
99
+ <h2>Version 4.2.5</h2>
100
+ <div class="inside">
101
+ <ul>
102
+ <li>Properly fix PHP 5.3 support; tested on CentOS 6. Does not support any UI or Premium features.</li>
103
+ <li>Fix potential issue with <tt>WP_FAIL2BAN_BLOCK_USER_ENUMERATION</tt> if calling REST API or XMLRPC from admin area.</li>
104
+ </ul>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ <div class="meta-box-sortables ui-sortable">
109
+ <div class="postbox">
110
+ <h2>Version 4.2.4</h2>
111
+ <div class="inside">
112
+ <ul>
113
+ <li>Add filter for login failed message.</li>
114
+ <li>Fix logging spam comments from admin area.</li>
115
+ <li>Fix Settings link from Plugins page.</li>
116
+ <li>Update Freemius library.</li>
117
+ </ul>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ <div class="meta-box-sortables ui-sortable">
122
+ <div class="postbox">
123
+ <h2>Version 4.2.3</h2>
124
+ <div class="inside">
125
+ <ul>
126
+ <li>Workaround for some versions of PHP 7.x that would cause <tt>define()</tt>s to be ignored.</li>
127
+ <li>Add config note to settings tabs.</li>
128
+ <li>Fix documentation links.</li>
129
+ </ul>
130
  </div>
131
  </div>
132
+ </div>
133
+ <div class="meta-box-sortables ui-sortable">
134
+ <div class="postbox">
135
+ <h2>Version 4.2.2</h2>
136
+ <div class="inside">
137
+ <ul>
138
+ <li>Fix 5.3 compatibility.</li>
139
+ </ul>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ <div class="meta-box-sortables ui-sortable">
144
+ <div class="postbox">
145
+ <h2>Version 4.2.1</h2>
146
+ <div class="inside">
147
+ <ul>
148
+ <li>Completed support for <tt><a href="https://docs.wp-fail2ban.com/en/4.2/defines/WP_FAIL2BAN_COMMENT_EXTRA_LOG.html?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="docs.wp-fail2ban.com">WP_FAIL2BAN_COMMENT_EXTRA_LOG</a></tt>.</li>
149
+ <li>Add support for 3rd-party plugins; see <a href="https://docs.wp-fail2ban.com/en/4.2/developers.html?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="docs.wp-fail2ban.com">Developers</a>.<br>
150
+ <p><ul>
151
+ <li>Add-on for <a href="https://wordpress.org/plugins/wp-fail2ban-addon-contact-form-7/">Contact Form 7</a> (experimental).</li>
152
+ <li>Add-on for <a href="https://wordpress.org/plugins/wp-fail2ban-addon-gravity-forms/">Gravity Forms</a> (experimental).</li>
153
+ </ul></p>
154
+ </li>
155
+ <li>Change logging for known-user with incorrect password; previously logged as unknown user and matched by <tt>hard</tt> filters (due to limitations in older versions of WordPress), now logged as known user and matched by <tt>soft</tt>.</li>
156
+ <li>Bugfix for email-as-username - now logged correctly and matched by <tt>soft</tt>, not <tt>hard</tt>, filters.</li>
157
+ <li>Bugfix for regression in code to prevent Free/Premium conflict.</li>
158
+ </ul>
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </div>
163
+ <div id="postbox-container-1" class="postbox-container">
164
+ <div class="meta-box-sortables">
165
+ <div class="postbox">
166
+ <h2>Getting Started</h2>
167
+ <div class="inside">
168
+ <ol>
169
+ <li><a href="https://docs.wp-fail2ban.com/en/<?=$wp_f2b_ver?>/introduction.html?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="docs.wp-fail2ban.com">Introduction</a></li>
170
+ <li><a href="https://docs.wp-fail2ban.com/en/<?=$wp_f2b_ver?>/configuration.html?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="docs.wp-fail2ban.com">Configuration</a></li>
171
+ </ol>
172
+ </div>
173
+ </div>
174
+ <div class="postbox">
175
+ <h2>Getting Help</h2>
176
+ <div class="inside">
177
+ <ul>
178
+ <li><a href="<?=wf_fs()->apply_filters('support_forum_url', '')?>?utm_source=about&utm_medium=about&utm_campaign=4.2.8" target="_blank">Support Forum</a></li>
179
+ </ul>
180
+ <p><strong>Note:</strong> The WordPress.org forum is no longer used for support. Please do not ask questions there as they are likely to go unanswered.</p>
181
  </div>
182
  </div>
183
  </div>
 
184
  </div>
185
  </div>
186
+ &nbsp;
187
+ </div>
188
+ </div>
189
+ <?php
190
  }
191
+
admin/lib/tab.php CHANGED
@@ -1,499 +1,260 @@
1
  <?php
 
2
  /**
3
  * Tab base class
4
  *
5
- * @package wp-fail2ban
6
- * @since 4.0.0
7
- * @php 5.6
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
- * Tab: Base class
14
  *
15
  * @since 4.0.0
 
 
 
16
  */
17
- abstract class TabBase
18
  {
19
- /**
20
- * @var array Array of Tab objects
21
- */
22
- protected static $tabs = [];
23
- /**
24
- * @var string Default tab slug
25
- */
26
- protected static $default_tab;
27
- /**
28
- * @var string Active tab slug
29
- */
30
- protected static $active_tab;
31
-
32
- /**
33
- * @var string Tab slug
34
- */
35
- protected $tab_slug;
36
- /**
37
- * @var string Tab name
38
- */
39
- protected $tab_name;
40
- /**
41
- * @since 4.3.0
42
- * @var bool Apply/Reset buttons?
43
- */
44
- protected $tab_apply;
45
-
46
- /**
47
- * @var array Settings
48
- * @since 4.3.0
49
- */
50
- protected $settings;
51
-
52
- /**
53
- * @var int admin_init priority
54
- * @since 4.3.0
55
- */
56
- protected $admin_init_priority = 10;
57
-
58
- /**
59
- * Hook: admin_init
60
- *
61
- * @since 4.0.0
62
- */
63
- abstract public function admin_init();
64
-
65
- /**
66
- * Hook: current_screen
67
- *
68
- * @since 4.3.0
69
- */
70
- public function current_screen()
71
- {
72
- get_current_screen()->set_help_sidebar(
73
- '<p><strong>' . __('For more information:') . '</strong></p>' .
74
- '<p>' . __('<a href="https://codex.wordpress.org/Managing_Plugins#Plugin_Management">Documentation on Managing Plugins</a>') . '</p>' .
75
- '<p>' . __('<a href="https://wordpress.org/support/">Support</a>') . '</p>'
76
- );
77
- }
78
-
79
- /**
80
- * Sanitize and store form fields
81
- *
82
- * @since 4.3.0 Refactor
83
- * @since 4.0.0
84
- *
85
- * @param array $input Form fields
86
- */
87
- public function sanitize(array $input = null)
88
- {
89
- return [];
90
- }
91
-
92
- /**
93
- * Contruct.
94
- *
95
- * @since 4.0.0
96
- *
97
- * @param string $slug Tab slug
98
- * @param string $name Tab name
99
- * @param bool $apply Show Apply/Reset buttons
100
- */
101
- public function __construct($slug, $name, $apply = true)
102
- {
103
- $this->tab_slug = $slug;
104
- $this->tab_name = $name;
105
- $this->tab_apply = $apply;
106
-
107
- self::$tabs[$slug] = $this;
108
-
109
- $this->settings = Config::settings();
110
-
111
- add_action('admin_init', [$this, 'admin_init'], $this->admin_init_priority);
112
-
113
- add_filter('gettext', [$this, 'gettext'], PHP_INT_MAX, 3);
114
- }
115
-
116
- /**
117
- * Hook: gettext
118
- *
119
- * @since 4.3.0
120
- *
121
- * @param string $translation
122
- * @param string $text
123
- * @param string $domain
124
- * @return stringq
125
- */
126
- public function gettext($translation, $text, $domain)
127
- {
128
- static $wp_f2b_ver;
129
-
130
- if (empty($wp_f2b_ver)) {
131
- $wp_f2b_ver = substr(WP_FAIL2BAN_VER, 0, strrpos(WP_FAIL2BAN_VER, '.'));
132
- }
133
-
134
- return str_replace('___WPF2BVER___', $wp_f2b_ver, $translation);
135
- }
136
-
137
- /**
138
- * Getter - slug
139
- *
140
- * @since 4.0.0
141
- *
142
- * @return string Tab slug
143
- */
144
- public function getSlug()
145
- {
146
- return $this->tab_slug;
147
- }
148
-
149
- /**
150
- * Getter - name
151
- *
152
- * @since 4.0.0
153
- *
154
- * @return string Tab name
155
- */
156
- public function getName()
157
- {
158
- return $this->tab_name;
159
- }
160
-
161
- /**
162
- * Render settings section
163
- *
164
- * @since 4.3.0 Refactored.
165
- * @since 4.0.0
166
- */
167
- public function render()
168
- {
169
- do_settings_sections('wp-fail2ban-'.$this->tab_slug);
170
- $this->render_buttons();
171
- }
172
-
173
- /**
174
- * Render settings section buttons
175
- *
176
- * @since 4.3.0
177
- */
178
- protected function render_buttons()
179
- {
180
- echo '<hr><p>'.__('<strong>Note:</strong> The Free version of <em>WP fail2ban</em> is configured by defining constants in <tt>wp-config.php</tt>; these tabs display those values.').'<br>'.
181
- __('Upgrade to the Premium version to enable this interface.').'</p>';
182
- }
183
-
184
- /**
185
- * Helper: is this the active tab?
186
- *
187
- * @since 4.3.0
188
- *
189
- * @return bool
190
- */
191
- protected function isActiveTab()
192
- {
193
- return ($this->tab_name == self::getActiveTab()->getName());
194
- }
195
-
196
- /**
197
- * Helper - tab
198
- *
199
- * @since 4.0.0
200
- *
201
- * @param string $slug Tab slug
202
- * @return Tab Tab
203
- */
204
- public static function getTab($slug)
205
- {
206
- return self::$tabs[$slug];
207
- }
208
-
209
- /**
210
- * Helper - set the default tab.
211
- *
212
- * @since 4.3.0
213
- *
214
- * @param string $default Default tab slug
215
- */
216
- public static function setDefaultTab($default)
217
- {
218
- self::$default_tab = $default;
219
- }
220
-
221
- /**
222
- * Helper - current tab
223
- *
224
- * @since 4.0.0
225
- *
226
- * @return TabBase Tab
227
- */
228
- public static function getActiveTab()
229
- {
230
- if (!empty(self::$active_tab)) {
231
- return self::$active_tab;
232
- }
233
-
234
- return (self::$active_tab = (array_key_exists(@$_GET['tab'], self::$tabs))
235
- ? self::$tabs[$_GET['tab']]
236
- : self::$tabs[self::$default_tab]
237
- );
238
- }
239
-
240
- /**
241
- * Helper - tab name
242
- *
243
- * @since 4.0.0
244
- *
245
- * @param string $slug Tab slug
246
- * @return string Tab name
247
- */
248
- public static function getTabName($slug)
249
- {
250
- return self::getTab($slug)->getName();
251
- }
252
-
253
- /**
254
- * Helper - tab exists?
255
- *
256
- * @since 4.3.0
257
- *
258
- * @param string $slug Tab slug
259
- * @return bool
260
- */
261
- public static function tabExists($slug)
262
- {
263
- return array_key_exists($slug, self::$tabs);
264
  }
265
-
266
- /**
267
- * Link to documentation
268
- *
269
- * @since 4.3.0 Protected
270
- * @since 4.2.0
271
- *
272
- * @param string $define
273
- * @return string
274
- */
275
- protected function doc_link($define)
276
- {
277
- static $wp_f2b_ver;
278
-
279
- if (empty($wp_f2b_ver)) {
280
- $wp_f2b_ver = substr(WP_FAIL2BAN_VER, 0, strrpos(WP_FAIL2BAN_VER, '.'));
281
- }
282
-
283
- return sprintf('<a href="https://docs.wp-fail2ban.com/en/%s/defines/constants/%s.html" style="text-decoration: none;" target="_blank" title="%s">%s<span class="dashicons dashicons-external" style="vertical-align: text-bottom"></span></a>', $wp_f2b_ver, $define, __('Documentation', 'wp-fail2ban'), $define);
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  }
285
-
286
- /**
287
- * Standard list of links to docs
288
- *
289
- * @since 4.3.0
290
- *
291
- * @param array $defines List of defines
292
- * @return string HTML
293
- */
294
- protected function see_also(array $defines)
295
- {
296
- return sprintf(
297
- '<p><em>%s</em>&nbsp;&nbsp;%s',
298
- __('See also:', 'wp-fail2ban'),
299
- implode('&nbsp;/&nbsp;', array_map(function ($i) {
300
- return $this->doc_link($i);
301
- }, $defines))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  );
303
  }
304
-
305
- /**
306
- * Helper - build drop-down list of facilities
307
- *
308
- * @since 4.3.0
309
- *
310
- * @param string $def Name of define for selected value
311
- * @param string $str Opening select html
312
- *
313
- * @return string
314
- */
315
- protected function getLogFacilitiesOptions($def, $str)
316
- {
317
- $default = Config::get_default($def);
318
- $value = Config::get($def);
319
-
320
- foreach (ConvertData::$FacilityName2Value as $name => $facility) {
321
- $str .= sprintf(
322
- '<option value="%s" %s>%s%s</option>',
323
- $facility,
324
- selected($value, $facility, false),
325
- $name,
326
- ($facility == $default) ? __(' (default)') : ''
327
- );
328
- }
329
- $str .= '</select>';
330
-
331
- return $str;
332
- }
333
-
334
- /**
335
- * Helper - drop-down list of facilities
336
- *
337
- * @since 4.3.0 Refactored.
338
- * @since 4.0.0
339
- *
340
- * @param string $def Name of define for selected value
341
- * @param bool $_enabled Enabled?
342
- *
343
- * @return string
344
- */
345
- protected function getLogFacilities($def, $_enabled = false)
346
- {
347
- return $this->getLogFacilitiesOptions($def, '<select disabled="disabled">');
348
- }
349
-
350
- /**
351
- * Log helper - enable/disable+facility
352
- *
353
- * @since 4.3.0 Refactored
354
- * @since 4.2.0 Moved to Tab
355
- * @since 4.0.0
356
- *
357
- * @param string $define_name Name of define to enable logging
358
- * @param string $define_log Name of define for log facility
359
- * @param array $toggle Array of IDs to sync toggle state
360
- * @param bool $echo Echo?
361
- */
362
- protected function log($define_name, $define_log, array $toggle = [], $echo = true)
363
- {
364
- $enabled = (true === Config::get($define_name)); // @TODO
365
- $fmt = <<<___FMT___
366
- <input type="checkbox" disabled="disabled" %s> <label>%s</label>,
367
- <label>%s:</label> %s
368
  ___FMT___;
369
- $html = sprintf(
370
- $fmt,
371
- checked($enabled, true, false),
372
- __('Enable logging', 'wp-fail2ban'),
373
- __('use facility', 'wp-fail2ban'),
374
- $this->getLogFacilities($define_log)
375
- );
376
- $html .= sprintf('<p class="description">%s</p>', Config::desc($define_name));
377
- $rv = apply_filters("wp_fail2ban_log_{$define_name}", $html, $define_name, $define_log);
378
- if ($echo) {
379
- echo $rv;
380
- } else {
381
- return $rv;
382
- }
383
- }
384
-
385
- /**
386
- * id="%s" Helper
387
- *
388
- * @since 4.3.0 Moved here.
389
- * @since 4.0.0
390
- *
391
- * @param string $define
392
- *
393
- * @return string
394
- */
395
- protected function field_name($define)
396
- {
397
- global $wp_fail2ban;
398
-
399
- return 'wp-fail2ban['.join('][', $wp_fail2ban['config'][$define]['field']).']';
400
- }
401
-
402
- /**
403
- * name="%s" Helper
404
- *
405
- * @since 4.3.0 Moved here.
406
- * @since 4.0.0
407
- *
408
- * @param string $define
409
- *
410
- * @return string
411
- */
412
- protected function field_id($define)
413
- {
414
- global $wp_fail2ban;
415
-
416
- return join('-', $wp_fail2ban['config'][$define]['field']);
417
- }
418
-
419
- /**
420
- * Helper: checked()
421
- *
422
- * @since 4.3.0
423
- *
424
- * @param string $define
425
- * @param bool $current
426
- * @param bool $echo
427
- * @return mixed
428
- */
429
- protected function def_checked($define, $current = true, $echo = true)
430
- {
431
- return checked(Config::get($define), $current, $echo);
432
- }
433
-
434
- /**
435
- * NDEF disabled helper
436
- *
437
- * @since 4.3.0 Add $override; moved here.
438
- * @since 4.0.0
439
- *
440
- * @param string $define
441
- * @param bool $override
442
- * @return string
443
- */
444
- protected function ndef_disabled($define, $override = false)
445
- {
446
- return disabled(Config::def($define) || $override, true, false);
447
- }
448
-
449
- /**
450
- * Display standard checkbox
451
- *
452
- * @since 4.3.0
453
- *
454
- * @param string $define Constant
455
- * @param bool $show_desc Show description?
456
- * @param string $plan Freemius plan
457
- * @param bool $echo Echo?
458
- *
459
- * @return string
460
- */
461
- protected function checkbox($define, $show_desc = true, $plan = 'bronze', $echo = true)
462
- {
463
- $html = sprintf(
464
- '<input type="checkbox" disabled="disabled" %s>',
465
- checked(constant($define), true, false)
466
- );
467
- if ($show_desc) {
468
- $html = '<label>'.$html.' '.$this->description($define, false).'</label>';
469
- }
470
- if ($echo) {
471
- echo $html;
472
- }
473
- return $html;
474
- }
475
-
476
- /**
477
- * Helper: setting description
478
- *
479
- * @since 4.3.0
480
- *
481
- * @param string $define
482
- * @param bool $echo
483
- *
484
- * @return string
485
- */
486
- protected function description($define, $echo = true)
487
- {
488
- if (!is_null($desc = Config::desc($define))) {
489
- if ($echo) {
490
- echo '<p class="description">'.$desc.'</p>';
491
- }
492
- return $desc;
493
- } else {
494
- return '';
495
- }
496
- }
497
  }
498
- }
499
 
 
1
  <?php
2
+
3
  /**
4
  * Tab base class
5
  *
6
+ * @package wp-fail2ban-premium
7
+ * @since 4.0.0
 
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Base Tab class
16
+ *
17
+ * @since 4.0.0
18
+ */
19
+ abstract class Tab
20
+ {
21
+ /**
22
+ * @var array Array of Tab objects
23
+ */
24
+ protected static $tabs = array() ;
25
+ /**
26
+ * @var string Active tab slug
27
+ */
28
+ protected static $active_tab ;
29
+ /**
30
+ * @var string Tab slug
31
+ */
32
+ protected $tab_slug ;
33
+ /**
34
+ * @var string Tab name
35
+ */
36
+ protected $tab_name ;
37
+ /**
38
+ * Hook: admin_init
39
+ *
40
+ * @since 4.0.0
41
+ */
42
+ public abstract function admin_init();
43
+
44
+ /**
45
+ * Sanitize and store form fields
46
+ *
47
+ * @since 4.0.0
48
+ *
49
+ * @param array $settings Settings to update
50
+ * @param array $input Form fields
51
+ *
52
+ * @return array $settings
53
+ */
54
+ public abstract function sanitize( array $settings, array $input = null );
55
+
56
  /**
57
+ * Contruct.
58
  *
59
  * @since 4.0.0
60
+ *
61
+ * @param string $slug Tab slug
62
+ * @param string $name Tab name
63
  */
64
+ public function __construct( $slug, $name )
65
  {
66
+ $this->tab_slug = $slug;
67
+ $this->tab_name = $name;
68
+ self::$tabs[$slug] = $this;
69
+ }
70
+
71
+ /**
72
+ * Getter - slug
73
+ *
74
+ * @since 4.0.0
75
+ *
76
+ * @return string Tab slug
77
+ */
78
+ public function getSlug()
79
+ {
80
+ return $this->tab_slug;
81
+ }
82
+
83
+ /**
84
+ * Getter - name
85
+ *
86
+ * @since 4.0.0
87
+ *
88
+ * @return string Tab name
89
+ */
90
+ public function getName()
91
+ {
92
+ return $this->tab_name;
93
+ }
94
+
95
+ /**
96
+ * Render settings section
97
+ *
98
+ * @since 4.0.0
99
+ */
100
+ public function render()
101
+ {
102
+ do_settings_sections( 'wp-fail2ban-' . $this->tab_slug );
103
+ }
104
+
105
+ /**
106
+ * Helper - tab
107
+ *
108
+ * @since 4.0.0
109
+ *
110
+ * @param string $slug Tab slug
111
+ *
112
+ * @return Tab Tab
113
+ */
114
+ public static function getTab( $slug )
115
+ {
116
+ return self::$tabs[$slug];
117
+ }
118
+
119
+ /**
120
+ * Helper - current tab
121
+ *
122
+ * @since 4.0.0
123
+ *
124
+ * @param string $default Default slug
125
+ *
126
+ * @return Tab Tab
127
+ */
128
+ public static function getActiveTab( $default = null )
129
+ {
130
+ if ( !empty(self::$active_tab) ) {
131
+ return self::$active_tab;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
133
+ return self::$active_tab = ( array_key_exists( @$_GET['tab'], self::$tabs ) ? self::$tabs[$_GET['tab']] : self::$tabs[$default] );
134
+ }
135
+
136
+ /**
137
+ * Helper - tab name
138
+ *
139
+ * @since 4.0.0
140
+ *
141
+ * @param string $slug Tab slug
142
+ *
143
+ * @return string Tab name
144
+ */
145
+ public static function getTabName( $slug )
146
+ {
147
+ return self::getTab( $slug )->getName();
148
+ }
149
+
150
+ /**
151
+ * Link to documentation
152
+ *
153
+ * @since 4.2.0
154
+ *
155
+ * @param string $define
156
+ * @param string $name
157
+ *
158
+ * @return string
159
+ */
160
+ public static function doc_link( $define, $name )
161
+ {
162
+ static $wp_f2b_ver ;
163
+ if ( empty($wp_f2b_ver) ) {
164
+ $wp_f2b_ver = substr( WP_FAIL2BAN_VER, 0, strrpos( WP_FAIL2BAN_VER, '.' ) );
165
  }
166
+ return sprintf(
167
+ '<a href="https://docs.wp-fail2ban.com/en/%s/defines/constants/%s.html" style="text-decoration: none;" target="_blank" title="Documentation"><span class="dashicons dashicons-external" style="vertical-align: text-bottom"></span></a> %s',
168
+ $wp_f2b_ver,
169
+ $define,
170
+ $name
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Helper - drop-down list of facilities
176
+ *
177
+ * @since 4.0.0
178
+ *
179
+ * @param string $def Name of define for selected value
180
+ * @param bool $_enabled Enabled?
181
+ */
182
+ protected function getLogFacilities( $def, $_enabled = false )
183
+ {
184
+ $enabled = false;
185
+ $facilities = [
186
+ LOG_AUTH => 'LOG_AUTH',
187
+ LOG_AUTHPRIV => 'LOG_AUTHPRIV',
188
+ LOG_CRON => 'LOG_CRON',
189
+ LOG_DAEMON => 'LOG_DAEMON',
190
+ LOG_KERN => 'LOG_KERN',
191
+ LOG_LOCAL0 => 'LOG_LOCAL0',
192
+ LOG_LOCAL1 => 'LOG_LOCAL1',
193
+ LOG_LOCAL2 => 'LOG_LOCAL2',
194
+ LOG_LOCAL3 => 'LOG_LOCAL3',
195
+ LOG_LOCAL4 => 'LOG_LOCAL4',
196
+ LOG_LOCAL5 => 'LOG_LOCAL5',
197
+ LOG_LOCAL6 => 'LOG_LOCAL6',
198
+ LOG_LOCAL7 => 'LOG_LOCAL7',
199
+ LOG_LPR => 'LOG_LPR',
200
+ LOG_MAIL => 'LOG_MAIL',
201
+ LOG_NEWS => 'LOG_NEWS',
202
+ LOG_SYSLOG => 'LOG_SYSLOG',
203
+ LOG_USER => 'LOG_USER',
204
+ LOG_UUCP => 'LOG_UUCP',
205
+ ];
206
+ $default = constant( "DEFAULT_{$def}" );
207
+ $value = ( defined( $def ) ? constant( $def ) : $default );
208
+ $str = '<select disabled="disabled">';
209
+ foreach ( $facilities as $facility => $name ) {
210
+ $str .= sprintf(
211
+ '<option value="%s" %s>%s%s</option>',
212
+ $facility,
213
+ selected( $value, $facility, false ),
214
+ $name,
215
+ ( $facility == $default ? __( ' (default)' ) : '' )
216
  );
217
  }
218
+ $str .= '</select>';
219
+ return $str;
220
+ }
221
+
222
+ /**
223
+ * Log helper - enable/disable+facility
224
+ *
225
+ * @since 4.2.0 Moved to Tab
226
+ * @since 4.0.0
227
+ *
228
+ * @param string $define_name Name of define to enable logging
229
+ * @param string $define_log Name of define for log facility
230
+ * @param string $description Description
231
+ * @param array $toggle Array of IDs to sync toggle state
232
+ */
233
+ protected function log(
234
+ $define_name,
235
+ $define_log,
236
+ $description = '',
237
+ array $toggle = array()
238
+ )
239
+ {
240
+ $enabled = defined( $define_name ) && true === constant( $define_name );
241
+ $fmt = <<<___FMT___
242
+ <label><input type="checkbox" disabled="disabled" %s> Enable logging</label>,
243
+ <label>use facility: %s</label>
244
+ <p class="description">%s</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  ___FMT___;
246
+ $html = sprintf(
247
+ $fmt,
248
+ checked( $enabled, true, false ),
249
+ $this->getLogFacilities( $define_log ),
250
+ $description
251
+ );
252
+ echo apply_filters(
253
+ "wp_fail2ban_log_{$define_name}",
254
+ $html,
255
+ $define_name,
256
+ $define_log
257
+ ) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  }
 
259
 
260
+ }
admin/tools.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- /**
3
- * Tools
4
- *
5
- * @package wp-fail2ban
6
- * @since 4.3.0
7
- */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
-
10
- if (defined('ABSPATH')) {
11
- /**
12
- * Proxy for api.wp-fail2ban.com
13
- *
14
- * @since 4.2.6
15
- */
16
- function remote_tools()
17
- {
18
- global $current_user;
19
-
20
- ?>
21
- <div class="wrap">
22
- <h1><?=__('Remote Tools (&beta;)', 'wp-fail2ban')?></h1>
23
- <hr class="wp-header-end">
24
- <?php
25
- if (function_exists(__NAMESPACE__.'\addons\remote_tools\tab')) {
26
- addons\remote_tools\tab();
27
- } else {
28
- ?>
29
- <h2 class="nav-tab-wrapper wp-clearfix">
30
- <a class="nav-tab nav-tab-active" href="#"><?=__('Overview', 'wp-fail2ban')?></a>
31
- </h2>
32
- <div class="card">
33
- <h2>Remote Tools Add-on</h2>
34
- <p>This add-on provides features that make life with WP fail2ban easier, all from a remote server. This gives access to valuable but infrequently used tools without bloating the core plugin.</p>
35
- <p>The first of these is a <strong>Custom Filter Tool</strong> (CFT).</p>
36
- <blockquote>
37
- <p>The filter files included are intended only as a starting point for those who want <em>WPf2b</em> to work &ldquo;out of the box&rdquo;.</p>
38
- <p>There is no &ldquo;one size fits all&rdquo; configuration possible for <em>fail2ban</em> - what may be a soft failure for one site should be treated as a hard failure for another, and vice versa.</p>
39
- </blockquote>
40
- <p>You could simply edit the filter files included, but it&lsquo;s surprisingly easy to make a mistake; I learned this the hard way with earlier versions of <em>WPf2b</em>.... The CFT removes most of the opportunities for human error - always a good thing!</p>
41
- <hr>
42
- <p>The Remote Tools Add-on is available from the <a href="<?php echo admin_url('admin.php?page=wp-fail2ban-addons') ?>">Add-Ons menu</a>.</p>
43
- </div>
44
- <?php
45
- }
46
-
47
- ?>
48
- </div>
49
- <?php
50
- }
51
- }
52
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/icon.svg DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="-4 -4 40 40" stroke-width="0" fill="#fff">
3
- <style>svg { background-color: #180c30; }</style>
4
- <path d="M16,0 l6.5,6.5 l-3.5,3.5 l-3,-3 l-9,9 l3,3 l-3.5,3.5 L0,16 z" />
5
- <path d="M0,31 L31,0 L32,1 L1,32 z" />
6
- <path d="M16,32 L32,16 l-6.5,-6.5 l-3.5,3.5 l3,3 l-9,9 l-3,-3 l-3.5,3.5 z" />
7
- </svg>
 
 
 
 
 
 
 
assets/menu.svg DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 34 34" fill="#fff" stroke="#fff" width="20" height="20">
3
- <path d="M16,0 l7,7 l-4,4 l-3,-3 l-8,8 l3,3 l-4,4 l-7,-7 z"/>
4
- <path d="M16,32 l16,-16 l-7,-7 l-4,4 l3,3 l-8,8 l-3,-3 l-4,4 z"/>
5
- <path d="M2,31 l-1,-1 l29,-29 l1,1 z"/>
6
- </svg>
7
-
 
 
 
 
 
 
 
feature/comments.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Comment logging
4
  *
@@ -7,176 +8,186 @@
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/comments.php');
 
 
 
 
12
 
 
13
  /**
14
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\notify_post_author')) {
17
- /**
18
- * Log new comment
19
- *
20
- * @since 3.5.0
21
- *
22
- * @param bool $maybe_notify
23
- * @param int $comment_ID
24
- *
25
- * @return bool
26
- *
27
- * @wp-f2b-extra Comment \d+
28
- */
29
- function notify_post_author($maybe_notify, $comment_ID)
30
- {
31
- openlog('WP_FAIL2BAN_COMMENT_LOG');
32
- syslog(LOG_INFO, "Comment {$comment_ID}");
33
- closelog();
34
-
35
- do_action(__FUNCTION__, $maybe_notify, $comment_ID);
36
-
37
- return $maybe_notify;
38
- }
39
- add_filter('notify_post_author', __NAMESPACE__.'\notify_post_author', 10, 2);
40
  }
 
 
 
 
 
 
 
 
 
41
 
42
- if (defined('WP_FAIL2BAN_LOG_COMMENTS_EXTRA')) {
43
- /** WPF2B_EVENT_COMMENT_NOT_FOUND */
44
- if (WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x00020002) {
 
 
 
 
 
45
  /**
46
- * @since 4.0.5 Guard
 
 
 
 
 
 
47
  */
48
- if (!function_exists(__NAMESPACE__.'\comment_id_not_found')) {
49
- /**
50
- * Log attempted comment on non-existent post
51
- *
52
- * @since 4.0.0
53
- *
54
- * @param int $comment_post_ID
55
- *
56
- * @wp-f2b-extra Comment post not found \d+
57
- */
58
- function comment_id_not_found($comment_post_ID)
59
- {
60
- openlog('WP_FAIL2BAN_COMMENT_EXTRA_LOG');
61
- syslog(LOG_NOTICE, "Comment post not found {$comment_post_ID}");
62
- closelog();
63
-
64
- do_action(__FUNCTION__, $comment_post_ID);
65
- }
66
- add_action('comment_id_not_found', __NAMESPACE__.'\comment_id_not_found');
67
  }
 
 
68
  }
69
-
70
- /** LOG_ACTION_LOG_COMMENT_CLOSED */
71
- if (WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x00020004) {
 
 
 
 
 
 
72
  /**
73
- * @since 4.0.5 Guard
 
 
 
 
 
 
74
  */
75
- if (!function_exists(__NAMESPACE__.'\comment_closed')) {
76
- /**
77
- * Log attempted comment on closed post
78
- *
79
- * @since 4.0.0
80
- *
81
- * @param int $comment_post_ID
82
- *
83
- * @wp-f2b-extra Comments closed on post \d+
84
- */
85
- function comment_closed($comment_post_ID)
86
- {
87
- openlog('WP_FAIL2BAN_COMMENT_EXTRA_LOG');
88
- syslog(LOG_NOTICE, "Comments closed on post {$comment_post_ID}");
89
- closelog();
90
-
91
- do_action(__FUNCTION__, $comment_post_ID);
92
- }
93
- add_action('comment_closed', __NAMESPACE__.'\comment_closed');
94
  }
 
 
95
  }
96
-
97
- /** LOG_ACTION_LOG_COMMENT_TRASH */
98
- if (WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x00020008) {
 
 
 
 
 
 
99
  /**
100
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
101
  */
102
- if (!function_exists(__NAMESPACE__.'\comment_on_trash')) {
103
- /**
104
- * Log attempted comment on trashed post
105
- *
106
- * @since 4.0.2 Fix message
107
- * @since 4.0.0
108
- *
109
- * @param int $comment_post_ID
110
- *
111
- * @wp-f2b-extra Comment attempt on trash post \d+
112
- */
113
- function comment_on_trash($comment_post_ID)
114
- {
115
- openlog('WP_FAIL2BAN_COMMENT_EXTRA_LOG');
116
- syslog(LOG_NOTICE, "Comment attempt on trash post {$comment_post_ID}");
117
- closelog();
118
-
119
- do_action(__FUNCTION__, $comment_post_ID);
120
- }
121
- add_action('comment_on_trash', __NAMESPACE__.'\comment_on_trash');
122
  }
 
 
123
  }
124
-
125
- /** LOG_ACTION_LOG_COMMENT_DRAFT */
126
- if (WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x00020010) {
 
 
 
 
 
 
127
  /**
128
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
129
  */
130
- if (!function_exists(__NAMESPACE__.'\comment_on_draft')) {
131
- /**
132
- * Log attempted comment on draft post
133
- *
134
- * @since 4.0.2 Fix message
135
- * @since 4.0.0
136
- *
137
- * @param int $comment_post_ID
138
- *
139
- * @wp-f2b-extra Comment attempt on draft post \d+
140
- */
141
- function comment_on_draft($comment_post_ID)
142
- {
143
- openlog('WP_FAIL2BAN_COMMENT_EXTRA_LOG');
144
- syslog(LOG_NOTICE, "Comment attempt on draft post {$comment_post_ID}");
145
- closelog();
146
-
147
- do_action(__FUNCTION__, $comment_post_ID);
148
- }
149
- add_action('comment_on_draft', __NAMESPACE__.'\comment_on_draft');
150
  }
 
 
151
  }
152
-
153
- /** LOG_ACTION_LOG_COMMENT_PASSWORD */
154
- if (WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x00020020) {
 
 
 
 
 
 
155
  /**
156
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
157
  */
158
- if (!function_exists(__NAMESPACE__.'\comment_on_password_protected')) {
159
- /**
160
- * Log attempted comment on password-protected post
161
- *
162
- * @since 4.0.2 Fix message
163
- * @since 4.0.0
164
- *
165
- * @param int $comment_post_ID
166
- *
167
- * @wp-f2b-extra Comment attempt on password-protected post \d+
168
- */
169
- function comment_on_password_protected($comment_post_ID)
170
- {
171
- openlog('WP_FAIL2BAN_COMMENT_EXTRA_LOG');
172
- syslog(LOG_NOTICE, "Comment attempt on password-protected post {$comment_post_ID}");
173
- closelog();
174
-
175
- do_action(__FUNCTION__, $comment_post_ID);
176
- }
177
- add_action('comment_on_password_protected', __NAMESPACE__.'\comment_on_password_protected');
178
  }
 
 
179
  }
 
180
  }
181
  }
182
-
1
  <?php
2
+
3
  /**
4
  * Comment logging
5
  *
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5 Guard
16
+ */
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\notify_post_author' ) ) {
19
  /**
20
+ * Log new comment
21
+ *
22
+ * @since 3.5.0
23
+ *
24
+ * @param bool $maybe_notify
25
+ * @param int $comment_ID
26
+ *
27
+ * @return bool
28
+ *
29
+ * @wp-f2b-extra Comment \d+
30
  */
31
+ function notify_post_author( $maybe_notify, $comment_ID )
32
+ {
33
+ openlog( 'WP_FAIL2BAN_COMMENT_LOG' );
34
+ syslog( LOG_INFO, "Comment {$comment_ID}" );
35
+ closelog();
36
+ // @codeCoverageIgnoreEnd
37
+ return $maybe_notify;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
+
40
+ add_filter(
41
+ 'notify_post_author',
42
+ __NAMESPACE__ . '\\notify_post_author',
43
+ 10,
44
+ 2
45
+ );
46
+ }
47
+
48
 
49
+ if ( defined( 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA' ) ) {
50
+ /** WPF2B_EVENT_COMMENT_NOT_FOUND */
51
+ if ( WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x20002 ) {
52
+ /**
53
+ * @since 4.0.5 Guard
54
+ */
55
+
56
+ if ( !function_exists( __NAMESPACE__ . '\\comment_id_not_found' ) ) {
57
  /**
58
+ * Log attempted comment on non-existent post
59
+ *
60
+ * @since 4.0.0
61
+ *
62
+ * @param int $comment_post_ID
63
+ *
64
+ * @wp-f2b-extra Comment post not found \d+
65
  */
66
+ function comment_id_not_found( $comment_post_ID )
67
+ {
68
+ openlog( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' );
69
+ syslog( LOG_NOTICE, "Comment post not found {$comment_post_ID}" );
70
+ closelog();
71
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
+
74
+ add_action( 'comment_id_not_found', __NAMESPACE__ . '\\comment_id_not_found' );
75
  }
76
+
77
+ }
78
+ /** LOG_ACTION_LOG_COMMENT_CLOSED */
79
+ if ( WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x20004 ) {
80
+ /**
81
+ * @since 4.0.5 Guard
82
+ */
83
+
84
+ if ( !function_exists( __NAMESPACE__ . '\\comment_closed' ) ) {
85
  /**
86
+ * Log attempted comment on closed post
87
+ *
88
+ * @since 4.0.0
89
+ *
90
+ * @param int $comment_post_ID
91
+ *
92
+ * @wp-f2b-extra Comments closed on post \d+
93
  */
94
+ function comment_closed( $comment_post_ID )
95
+ {
96
+ openlog( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' );
97
+ syslog( LOG_NOTICE, "Comments closed on post {$comment_post_ID}" );
98
+ closelog();
99
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
+
102
+ add_action( 'comment_closed', __NAMESPACE__ . '\\comment_closed' );
103
  }
104
+
105
+ }
106
+ /** LOG_ACTION_LOG_COMMENT_TRASH */
107
+ if ( WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x20008 ) {
108
+ /**
109
+ * @since 4.0.5 Guard
110
+ */
111
+
112
+ if ( !function_exists( __NAMESPACE__ . '\\comment_on_trash' ) ) {
113
  /**
114
+ * Log attempted comment on trashed post
115
+ *
116
+ * @since 4.0.2 Fix message
117
+ * @since 4.0.0
118
+ *
119
+ * @param int $comment_post_ID
120
+ *
121
+ * @wp-f2b-extra Comment attempt on trash post \d+
122
  */
123
+ function comment_on_trash( $comment_post_ID )
124
+ {
125
+ openlog( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' );
126
+ syslog( LOG_NOTICE, "Comment attempt on trash post {$comment_post_ID}" );
127
+ closelog();
128
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
+
131
+ add_action( 'comment_on_trash', __NAMESPACE__ . '\\comment_on_trash' );
132
  }
133
+
134
+ }
135
+ /** LOG_ACTION_LOG_COMMENT_DRAFT */
136
+ if ( WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x20010 ) {
137
+ /**
138
+ * @since 4.0.5 Guard
139
+ */
140
+
141
+ if ( !function_exists( __NAMESPACE__ . '\\comment_on_draft' ) ) {
142
  /**
143
+ * Log attempted comment on draft post
144
+ *
145
+ * @since 4.0.2 Fix message
146
+ * @since 4.0.0
147
+ *
148
+ * @param int $comment_post_ID
149
+ *
150
+ * @wp-f2b-extra Comment attempt on draft post \d+
151
  */
152
+ function comment_on_draft( $comment_post_ID )
153
+ {
154
+ openlog( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' );
155
+ syslog( LOG_NOTICE, "Comment attempt on draft post {$comment_post_ID}" );
156
+ closelog();
157
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
+
160
+ add_action( 'comment_on_draft', __NAMESPACE__ . '\\comment_on_draft' );
161
  }
162
+
163
+ }
164
+ /** LOG_ACTION_LOG_COMMENT_PASSWORD */
165
+ if ( WP_FAIL2BAN_LOG_COMMENTS_EXTRA & 0x20020 ) {
166
+ /**
167
+ * @since 4.0.5 Guard
168
+ */
169
+
170
+ if ( !function_exists( __NAMESPACE__ . '\\comment_on_password_protected' ) ) {
171
  /**
172
+ * Log attempted comment on password-protected post
173
+ *
174
+ * @since 4.0.2 Fix message
175
+ * @since 4.0.0
176
+ *
177
+ * @param int $comment_post_ID
178
+ *
179
+ * @wp-f2b-extra Comment attempt on password-protected post \d+
180
  */
181
+ function comment_on_password_protected( $comment_post_ID )
182
+ {
183
+ openlog( 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' );
184
+ syslog( LOG_NOTICE, "Comment attempt on password-protected post {$comment_post_ID}" );
185
+ closelog();
186
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  }
188
+
189
+ add_action( 'comment_on_password_protected', __NAMESPACE__ . '\\comment_on_password_protected' );
190
  }
191
+
192
  }
193
  }
 
feature/lib.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Library functions
4
  *
@@ -7,171 +8,130 @@
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  /**
12
- * Helper.
13
- *
14
- * @since 4.3.0
15
- *
16
- * @param mixed $key
17
- * @param array $ary
18
- * @return mixed|null Array value if present, null otherwise.
19
  */
20
- function array_value($key, array $ary)
21
- {
22
- return (array_key_exists($key, $ary))
23
- ? $ary[$key]
24
- : null;
25
  }
26
-
27
- /**
28
- * Wrapper for \openlog
29
- *
30
- * @since 3.5.0 Refactored for unit testing
31
- *
32
- * @param string $log
33
- */
34
- function openlog($log = 'WP_FAIL2BAN_AUTH_LOG')
35
- {
36
- $tag = (defined('WP_FAIL2BAN_SYSLOG_SHORT_TAG') && true === WP_FAIL2BAN_SYSLOG_SHORT_TAG)
37
- ? 'wp' // @codeCoverageIgnore
38
- : 'wordpress';
39
- $host = (array_key_exists('WP_FAIL2BAN_HTTP_HOST', $_ENV))
40
- ? $_ENV['WP_FAIL2BAN_HTTP_HOST'] // @codeCoverageIgnore
41
- : $_SERVER['HTTP_HOST'];
42
- if (is_multisite() && !SUBDOMAIN_INSTALL) {
43
- /**
44
- * @todo Test me!
45
- * @codeCoverageIgnore
46
- */
47
- if (1 < ($blog_id = get_current_blog_id())) {
48
- $blog = get_blog_details($blog_id, false);
49
- $host .= '/'.trim($blog->path, '/');
50
- }
51
- }
52
- /**
53
- * Some varieties of syslogd have difficulty if $host is too long
54
- * @since 3.5.0
55
- */
56
- if (defined('WP_FAIL2BAN_TRUNCATE_HOST') && 1 < intval(WP_FAIL2BAN_TRUNCATE_HOST)) {
57
- $host = substr($host, 0, intval(WP_FAIL2BAN_TRUNCATE_HOST));
58
- }
59
- /**
60
- * Refactor for unit testing.
61
- * @since 4.3.0
62
- */
63
- $options = (defined('WP_FAIL2BAN_OPENLOG_OPTIONS')) ? WP_FAIL2BAN_OPENLOG_OPTIONS : null;
64
- if (false === \openlog("$tag($host)", $options, constant($log))) {
65
- error_log('WPf2b: Cannot open syslog', 0); // @codeCoverageIgnore
66
- } elseif (defined('WP_FAIL2BAN_TRACE')) {
67
- error_log('WPf2b: Opened syslog', 0); // @codeCoverageIgnore
68
- }
69
  }
70
 
71
- /**
72
- * Wrapper for \syslog
73
- *
74
- * @since 3.5.0
75
- *
76
- * @param int $level
77
- * @param string $msg
78
- * @param string|null $remote_addr
79
- */
80
- function syslog($level, $msg, $remote_addr = null)
81
- {
82
- $msg .= ' from ';
83
- $msg .= (is_null($remote_addr))
84
- ? remote_addr()
85
- : $remote_addr;
86
-
87
- if (false === \syslog($level, $msg)) {
88
- error_log("WPf2b: Cannot write to syslog: '{$msg}'", 0); // @codeCoverageIgnore
89
- } elseif (defined('WP_FAIL2BAN_TRACE')) {
90
- error_log("WPf2b: Wrote to syslog: '{$msg}'", 0); // @codeCoverageIgnore
91
- }
92
- \closelog();
93
 
94
- if (defined('PHPUNIT_COMPOSER_INSTALL')) {
95
- echo "$level|$msg";
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
 
 
 
 
 
 
98
 
99
- /**
100
- * Graceful immediate exit
101
- *
102
- * @since 4.3.0 Remove JSON support
103
- * @since 4.0.5 Add JSON support
104
- * @since 3.5.0 Refactored for unit testing
105
- *
106
- * @param bool $is_json
107
- */
108
- function bail()
109
- {
110
- \wp_die('Forbidden', 'Forbidden', array('exit' => false, 'response' => 403));
111
-
112
- if (defined('PHPUNIT_COMPOSER_INSTALL')) {
113
- return false; // for testing
114
- } else {
115
- exit;
116
- }
117
- } // @codeCoverageIgnore
118
-
119
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
- * Compute remote IP address
122
- *
123
- * @return string
124
- *
125
- * @todo Test me!
126
- * @codeCoverageIgnore
127
  */
128
- function remote_addr()
129
- {
130
- static $remote_addr = null;
131
-
132
- /**
133
- * @since 4.0.0
134
- */
135
- if (is_null($remote_addr)) {
136
- if (defined('WP_FAIL2BAN_PROXIES')) {
137
- if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
138
- $ip = ip2long($_SERVER['REMOTE_ADDR']);
139
- /**
140
- * PHP 7 lets you define an array
141
- * @since 3.5.4
142
- */
143
- $proxies = (is_array(WP_FAIL2BAN_PROXIES))
144
- ? WP_FAIL2BAN_PROXIES
145
- : explode(',', WP_FAIL2BAN_PROXIES);
146
- foreach ($proxies as $proxy) {
147
- if ('#' == $proxy[0]) {
148
- continue;
149
- } elseif (2 == count($cidr = explode('/', $proxy))) {
150
- $net = ip2long($cidr[0]);
151
- $mask = ~ ( pow(2, (32 - $cidr[1])) - 1 );
152
- } else {
153
- $net = ip2long($proxy);
154
- $mask = -1;
155
- }
156
- if ($net == ($ip & $mask)) {
157
- return (false === ($len = strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')))
158
- ? $_SERVER['HTTP_X_FORWARDED_FOR']
159
- : substr($_SERVER['HTTP_X_FORWARDED_FOR'], 0, $len);
160
- }
161
  }
162
  }
163
  }
164
-
165
- /**
166
- * For plugins and themes that anonymise requests
167
- * @since 3.6.0
168
- */
169
- $remote_addr = (defined('WP_FAIL2BAN_REMOTE_ADDR'))
170
- ? WP_FAIL2BAN_REMOTE_ADDR
171
- : $_SERVER['REMOTE_ADDR'];
172
  }
173
-
174
- return $remote_addr;
 
 
 
175
  }
 
 
176
  }
177
-
1
  <?php
2
+
3
  /**
4
  * Library functions
5
  *
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Wrapper for \openlog
16
+ *
17
+ * @since 3.5.0 Refactored for unit testing
18
+ *
19
+ * @param string $log
20
+ */
21
+ function openlog( $log = 'WP_FAIL2BAN_AUTH_LOG' )
22
+ {
23
+ $tag = ( defined( 'WP_FAIL2BAN_SYSLOG_SHORT_TAG' ) && true === WP_FAIL2BAN_SYSLOG_SHORT_TAG ? 'wp' : 'wordpress' );
24
+ $host = ( array_key_exists( 'WP_FAIL2BAN_HTTP_HOST', $_ENV ) ? $_ENV['WP_FAIL2BAN_HTTP_HOST'] : $_SERVER['HTTP_HOST'] );
25
  /**
26
+ * Some varieties of syslogd have difficulty if $host is too long
27
+ * @since 3.5.0
 
 
 
 
 
28
  */
29
+ if ( defined( 'WP_FAIL2BAN_TRUNCATE_HOST' ) && 1 < intval( WP_FAIL2BAN_TRUNCATE_HOST ) ) {
30
+ $host = substr( $host, 0, intval( WP_FAIL2BAN_TRUNCATE_HOST ) );
 
 
 
31
  }
32
+
33
+ if ( false === \openlog( "{$tag}({$host})", WP_FAIL2BAN_OPENLOG_OPTIONS, constant( $log ) ) ) {
34
+ error_log( 'WPf2b: Cannot open syslog', 0 );
35
+ // @codeCoverageIgnore
36
+ } elseif ( defined( 'WP_FAIL2BAN_TRACE' ) ) {
37
+ error_log( 'WPf2b: Opened syslog', 0 );
38
+ // @codeCoverageIgnore
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ /**
44
+ * Wrapper for \syslog
45
+ *
46
+ * @since 3.5.0
47
+ *
48
+ * @param int $level
49
+ * @param string $msg
50
+ * @param string|null $remote_addr
51
+ */
52
+ function syslog( $level, $msg, $remote_addr = null )
53
+ {
54
+ $msg .= ' from ';
55
+ $msg .= ( is_null( $remote_addr ) ? remote_addr() : $remote_addr );
56
+
57
+ if ( false === \syslog( $level, $msg ) ) {
58
+ error_log( "WPf2b: Cannot write to syslog: '{$msg}'", 0 );
59
+ // @codeCoverageIgnore
60
+ } elseif ( defined( 'WP_FAIL2BAN_TRACE' ) ) {
61
+ error_log( "WPf2b: Wrote to syslog: '{$msg}'", 0 );
62
+ // @codeCoverageIgnore
63
  }
64
+
65
+ \closelog();
66
+ if ( defined( 'PHPUNIT_COMPOSER_INSTALL' ) ) {
67
+ echo "{$level}|{$msg}" ;
68
+ }
69
+ }
70
 
71
+ /**
72
+ * Graceful immediate exit
73
+ *
74
+ * @since 4.2.7 Remove JSON support
75
+ * @since 4.0.5 Add JSON support
76
+ * @since 3.5.0 Refactored for unit testing
77
+ */
78
+ function bail()
79
+ {
80
+ wp_die( 'Forbidden', 'Forbidden', array(
81
+ 'response' => 403,
82
+ ) );
83
+ }
 
 
 
 
 
 
 
84
 
85
+ /**
86
+ * Compute remote IP address
87
+ *
88
+ * @return string
89
+ *
90
+ * @todo Test me!
91
+ * @codeCoverageIgnore
92
+ */
93
+ function remote_addr()
94
+ {
95
+ static $remote_addr = null ;
96
  /**
97
+ * @since 4.0.0
 
 
 
 
 
98
  */
99
+
100
+ if ( is_null( $remote_addr ) ) {
101
+ if ( defined( 'WP_FAIL2BAN_PROXIES' ) ) {
102
+
103
+ if ( array_key_exists( 'HTTP_X_FORWARDED_FOR', $_SERVER ) ) {
104
+ $ip = ip2long( $_SERVER['REMOTE_ADDR'] );
105
+ /**
106
+ * PHP 7 lets you define an array
107
+ * @since 3.5.4
108
+ */
109
+ $proxies = ( is_array( WP_FAIL2BAN_PROXIES ) ? WP_FAIL2BAN_PROXIES : explode( ',', WP_FAIL2BAN_PROXIES ) );
110
+ foreach ( $proxies as $proxy ) {
111
+
112
+ if ( '#' == $proxy[0] ) {
113
+ continue;
114
+ } elseif ( 2 == count( $cidr = explode( '/', $proxy ) ) ) {
115
+ $net = ip2long( $cidr[0] );
116
+ $mask = ~(pow( 2, 32 - $cidr[1] ) - 1);
117
+ } else {
118
+ $net = ip2long( $proxy );
119
+ $mask = -1;
120
+ }
121
+
122
+ if ( $net == ($ip & $mask) ) {
123
+ return ( false === ($len = strpos( $_SERVER['HTTP_X_FORWARDED_FOR'], ',' )) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : substr( $_SERVER['HTTP_X_FORWARDED_FOR'], 0, $len ) );
 
 
 
 
 
 
 
 
124
  }
125
  }
126
  }
127
+
 
 
 
 
 
 
 
128
  }
129
+ /**
130
+ * For plugins and themes that anonymise requests
131
+ * @since 3.6.0
132
+ */
133
+ $remote_addr = ( defined( 'WP_FAIL2BAN_REMOTE_ADDR' ) ? WP_FAIL2BAN_REMOTE_ADDR : $_SERVER['REMOTE_ADDR'] );
134
  }
135
+
136
+ return $remote_addr;
137
  }
 
feature/password.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Password-related functionality
4
  *
@@ -7,31 +8,30 @@
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/password.php');
 
 
 
 
12
 
 
13
  /**
14
- * @since 4.0.5
 
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\retrieve_password')) {
17
- /**
18
- * Log password reset requests
19
- *
20
- * @since 3.5.0
21
- *
22
- * @param string $user_login
23
- *
24
- * @wp-f2b-extra Password reset requested for .*
25
- */
26
- function retrieve_password($user_login)
27
- {
28
- openlog('WP_FAIL2BAN_PASSWORD_REQUEST_LOG');
29
- syslog(LOG_NOTICE, "Password reset requested for {$user_login}");
30
- closelog();
31
-
32
- do_action(__FUNCTION__, $user_login);
33
- }
34
- add_action('retrieve_password', __NAMESPACE__.'\retrieve_password');
35
  }
 
 
36
  }
37
-
1
  <?php
2
+
3
  /**
4
  * Password-related functionality
5
  *
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5
16
+ */
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\retrieve_password' ) ) {
19
  /**
20
+ * Log password reset requests
21
+ *
22
+ * @since 3.5.0
23
+ *
24
+ * @param string $user_login
25
+ *
26
+ * @wp-f2b-extra Password reset requested for .*
27
  */
28
+ function retrieve_password( $user_login )
29
+ {
30
+ openlog( 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG' );
31
+ syslog( LOG_NOTICE, "Password reset requested for {$user_login}" );
32
+ closelog();
33
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
+
36
+ add_action( 'retrieve_password', __NAMESPACE__ . '\\retrieve_password' );
37
  }
 
feature/plugins.php CHANGED
@@ -1,255 +1,233 @@
1
  <?php
 
2
  /**
3
  * Library functions
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.2.0
7
- * @php 5.6
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
- if (defined('ABSPATH')) {
12
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/plugins.php');
13
-
14
- /**
15
- * @since 4.2.0
16
- */
17
- global $wp_fail2ban;
18
- $wp_fail2ban['plugins'] = array();
19
-
20
- /**
21
- * Hook: plugins_loaded
22
- *
23
- * @codeCoverageIgnore
24
- *
25
- * @since 4.2.0
26
- */
27
- function wp_fail2ban_register()
28
- {
29
- do_action('wp_fail2ban_register');
30
- }
31
- add_action('plugins_loaded', __NAMESPACE__.'\wp_fail2ban_register');
32
-
33
- /**
34
- * Register plugin
35
- *
36
- * @since 4.2.0
37
- *
38
- * @param string $slug Plugin slug. This must be the actual plugin slug. Maximum length is 255 which should be more than enough.
39
- * @param string $name Plugin display name. This should be an unescaped string - HTML is allowed.
40
- *
41
- * @return int|false ID
42
- */
43
- function register_plugin($slug, $name)
44
- {
45
- global $wp_fail2ban, $wpdb;
46
-
47
- if (255 < strlen($slug)) {
48
- throw new \LengthException('slug too long');
49
- }
50
-
51
- if (255 < strlen($name)) {
52
- throw new \LengthException('name too long');
53
- }
54
-
55
- if (!is_array(@$wp_fail2ban['plugins'])) {
56
- $wp_fail2ban['plugins'] = [];
57
- }
58
-
59
- if (array_key_exists($slug, $wp_fail2ban['plugins'])) {
60
- return $wp_fail2ban['plugins'][$slug];
61
- }
62
-
63
- if (is_null($rv = apply_filters(__FUNCTION__, null, $slug, $name))) {
64
- static $id = 0;
65
 
66
- return ($wp_fail2ban['plugins'][$slug] = [
67
- 'id' => ++$id,
68
- 'name' => $name,
69
- 'messages' => []
70
- ]);
71
- } else {
72
- return $rv;
73
- }
 
 
 
 
 
 
 
 
74
  }
75
- add_action('wp_fail2ban_register_plugin', __NAMESPACE__.'\register_plugin', 1, 2);
76
-
77
- /**
78
- * Check if plugin is registered.
79
- *
80
- * @since 4.2.0
81
- *
82
- * @param string $plugin_slug
83
- *
84
- * @return bool
85
- */
86
- function is_registered_plugin($plugin_slug)
87
- {
88
- global $wp_fail2ban;
89
-
90
- return array_key_exists($plugin_slug, $wp_fail2ban['plugins']);
91
  }
92
-
93
- /**
94
- * Register plugin message.
95
- *
96
- * @since 4.2.0
97
- *
98
- * @param string $plugin_slug
99
- * @param array $msg [
100
- * string slug: Message slug
101
- * string fail: hard|soft|extra
102
- * int facility: syslog facility
103
- * int priority: syslog priority
104
- * string event_class: Event Class
105
- * int event_id: Event ID
106
- * string message: Message with placeholders
107
- * HOST: Remote IP
108
- * USER: Current user name
109
- * array vars: Array of [name => regex] pairs
110
- */
111
- function register_message($plugin_slug, array $msg)
112
- {
113
- global $wp_fail2ban;
114
- $event_classes = [
115
- 'auth' => WPF2B_EVENT_CLASS_AUTH,
116
- 'comment' => WPF2B_EVENT_CLASS_COMMENT,
117
- 'password' => WPF2B_EVENT_CLASS_PASSWORD,
118
- 'rest' => WPF2B_EVENT_CLASS_REST,
119
- 'spam' => WPF2B_EVENT_CLASS_SPAM,
120
- 'xmlrpc' => WPF2B_EVENT_CLASS_XMLRPC,
121
- 'other' => 0
122
- ];
123
-
124
- $args = [];
125
-
126
- if (!is_registered_plugin($plugin_slug)) {
127
- throw new \InvalidArgumentException('plugin not registered');
128
- }
129
-
130
- if (!array_key_exists('slug', $msg)) {
131
- throw new \InvalidArgumentException("Missing 'slug'");
132
- }
133
- if (!is_string($msg['slug'])) {
134
- throw new \InvalidArgumentException("'slug' must be string");
135
- }
136
-
137
- if (!array_key_exists('fail', $msg)) {
138
- throw new \InvalidArgumentException("Missing 'fail'");
139
- }
140
- if (!in_array($msg['fail'], ['hard', 'soft', 'extra'])) {
141
- throw new \UnexpectedValueException("'fail' must be one of 'hard', 'soft', 'extra'");
142
- }
143
- $args['fail'] = $msg['fail'];
144
-
145
- if (!array_key_exists('priority', $msg)) {
146
- throw new \InvalidArgumentException("Missing 'priority'");
147
- }
148
- if (!in_array($msg['priority'], [
149
- LOG_CRIT,
150
- LOG_ERR,
151
- LOG_WARNING,
152
- LOG_NOTICE,
153
- LOG_INFO,
154
- LOG_DEBUG
155
- ])) {
156
- throw new \UnexpectedValueException("Invalid 'priority'");
157
- }
158
- $args['priority'] = $msg['priority'];
159
-
160
- if (!array_key_exists('event_class', $msg)) {
161
- throw new \InvalidArgumentException("Missing 'event_class'");
162
- }
163
- if (!array_key_exists($event_class = strtolower($msg['event_class']), $event_classes)) {
164
- throw new \UnexpectedValueException("Invalid 'event_class'");
165
- }
166
- $args['class'] = $event_class;
167
- $event_class = $event_classes[$event_class];
168
-
169
- $log = sprintf("WP_FAIL2BAN_%s_LOG", strtoupper($event_class));
170
-
171
- if (!array_key_exists('event_id', $msg)) {
172
- throw new \InvalidArgumentException("Missing 'event_id'");
173
- }
174
- if (($msg['event_id'] & 0x0000FFFF) !== $msg['event_id']) {
175
- throw new \UnexpectedValueException("Invalid 'event_id'");
176
- }
177
- $args['event_id'] = WPF2B_EVENT_TYPE_PLUGIN | $event_class | $msg['event_id'];
178
-
179
- if (!array_key_exists('message', $msg)) {
180
- throw new \InvalidArgumentException("Missing 'message'");
181
- }
182
- if (!is_string($msg['message'])) {
183
- throw new \UnexpectedValueException("Invalid 'message'");
184
- }
185
- $args['message'] = $msg['message'];
186
-
187
- if (!array_key_exists('vars', $msg)) {
188
- throw new \InvalidArgumentException("Missing 'vars'");
189
- }
190
- if (!is_array($msg['vars'])) {
191
- throw new \UnexpectedValueException("Invalid 'vars'");
192
- }
193
- $args['vars'] = $msg['vars'];
194
-
195
- $wp_fail2ban['plugins'][$plugin_slug]['messages'][$msg['slug']] = $args;
196
  }
197
- add_action('wp_fail2ban_register_message', __NAMESPACE__.'\register_message', 1, 2);
198
-
199
- /**
200
- * Check if message is registered.
201
- *
202
- * NB: Assumes plugin is registered.
203
- *
204
- * @since 4.2.0
205
- *
206
- * @param string $plugin_slug
207
- * @param string $message_slug
208
- *
209
- * @return bool
210
- */
211
- function is_registered_plugin_message($plugin_slug, $message_slug)
212
- {
213
- global $wp_fail2ban;
214
-
215
- return array_key_exists($message_slug, $wp_fail2ban['plugins'][$plugin_slug]['messages']);
216
  }
 
 
 
 
 
 
 
217
 
218
- /**
219
- * Log plugin message.
220
- *
221
- * @since 4.2.0
222
- *
223
- * @param string $plugin_slug Plugin slug for registered message
224
- * @param string $message_slug Message slug for registered message
225
- * @param array $vars Substitution vars
226
- */
227
- function log_message($plugin_slug, $message_slug = null, array $vars = [])
228
- {
229
- global $wp_fail2ban;
 
 
 
 
 
 
 
 
230
 
231
- if (!is_registered_plugin($plugin_slug)) {
232
- throw new \InvalidArgumentException('plugin not registered');
233
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
- if (!is_registered_plugin_message($plugin_slug, $message_slug)) {
236
- throw new \InvalidArgumentException('message not registered');
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
- $args = $wp_fail2ban['plugins'][$plugin_slug]['messages'][$message_slug];
240
- $msg = $args['message'];
241
- foreach ($args['vars'] as $name => $regex) {
242
- if (array_key_exists($name, $vars)) {
243
- $msg = str_replace("___{$name}___", $vars[$name], $msg);
244
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  }
246
-
247
- openlog(sprintf('WP_FAIL2BAN_PLUGIN_%s_LOG', strtoupper($args['class'])));
248
- syslog($args['priority'], "($plugin_slug) $msg");
249
- closelog();
250
-
251
- do_action(__FUNCTION__, $plugin_slug, $message_slug, $vars, $args);
252
  }
253
- add_action('wp_fail2ban_log_message', __NAMESPACE__.'\log_message', 1, 3);
 
 
 
254
  }
255
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
  * Library functions
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.2.0
 
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * Hook: plugins_loaded
16
+ *
17
+ * @since 4.2.0
18
+ */
19
+ function plugins_loaded()
20
+ {
21
+ do_action( 'wp_fail2ban_register' );
22
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ add_action( 'plugins_loaded', __NAMESPACE__ . '\\plugins_loaded' );
25
+ /**
26
+ * Register plugin
27
+ *
28
+ * @since 4.2.0
29
+ *
30
+ * @param string $slug Plugin slug. This must be the actual plugin slug. Maximum length is 255 which should be more than enough.
31
+ * @param string $name Plugin display name. This should be an unescaped string - HTML is allowed.
32
+ *
33
+ * @return int|false ID
34
+ */
35
+ function register_plugin( $slug, $name )
36
+ {
37
+ global $wp_fail2ban, $wpdb ;
38
+ if ( 255 < strlen( $slug ) ) {
39
+ throw new \LengthException( 'slug too long' );
40
  }
41
+ if ( 255 < strlen( $name ) ) {
42
+ throw new \LengthException( 'name too long' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
+ if ( !is_array( @$wp_fail2ban['plugins'] ) ) {
45
+ $wp_fail2ban['plugins'] = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
+ if ( array_key_exists( $slug, $wp_fail2ban['plugins'] ) ) {
48
+ return $wp_fail2ban['plugins'][$slug];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
+ static $id = 0 ;
51
+ return $wp_fail2ban['plugins'][$slug] = [
52
+ 'id' => ++$id,
53
+ 'name' => $name,
54
+ 'messages' => [],
55
+ ];
56
+ }
57
 
58
+ add_action(
59
+ 'wp_fail2ban_register_plugin',
60
+ __NAMESPACE__ . '\\register_plugin',
61
+ 1,
62
+ 2
63
+ );
64
+ /**
65
+ * Check if plugin is registered.
66
+ *
67
+ * @since 4.2.0
68
+ *
69
+ * @param string $plugin_slug
70
+ *
71
+ * @return bool
72
+ */
73
+ function is_registered_plugin( $plugin_slug )
74
+ {
75
+ global $wp_fail2ban ;
76
+ return array_key_exists( $plugin_slug, $wp_fail2ban['plugins'] );
77
+ }
78
 
79
+ /**
80
+ * Register plugin message.
81
+ *
82
+ * @since 4.2.0
83
+ *
84
+ * @param string $plugin_slug
85
+ * @param array $msg [
86
+ * string slug: Message slug
87
+ * string fail: hard|soft|extra
88
+ * int facility: syslog facility
89
+ * int priority: syslog priority
90
+ * string event_class: Event Class
91
+ * int event_id: Event ID
92
+ * string message: Message with placeholders
93
+ * HOST: Remote IP
94
+ * USER: Current user name
95
+ * array vars: Array of [name => regex] pairs
96
+ */
97
+ function register_message( $plugin_slug, array $msg )
98
+ {
99
+ global $wp_fail2ban ;
100
+ $event_classes = [
101
+ 'auth' => WPF2B_EVENT_CLASS_AUTH,
102
+ 'comment' => WPF2B_EVENT_CLASS_COMMENT,
103
+ 'password' => WPF2B_EVENT_CLASS_PASSWORD,
104
+ 'rest' => WPF2B_EVENT_CLASS_REST,
105
+ 'spam' => WPF2B_EVENT_CLASS_SPAM,
106
+ 'xmlrpc' => WPF2B_EVENT_CLASS_XMLRPC,
107
+ 'other' => 0,
108
+ ];
109
+ $args = [];
110
+ if ( !is_registered_plugin( $plugin_slug ) ) {
111
+ throw new \InvalidArgumentException( 'plugin not registered' );
112
+ }
113
+ if ( !array_key_exists( 'slug', $msg ) ) {
114
+ throw new \InvalidArgumentException( "Missing 'slug'" );
115
+ }
116
+ if ( !is_string( $msg['slug'] ) ) {
117
+ throw new \InvalidArgumentException( "'slug' must be string" );
118
+ }
119
+ if ( !array_key_exists( 'fail', $msg ) ) {
120
+ throw new \InvalidArgumentException( "Missing 'fail'" );
121
+ }
122
+ if ( !in_array( $msg['fail'], [ 'hard', 'soft', 'extra' ] ) ) {
123
+ throw new \UnexpectedValueException( "'fail' must be one of 'hard', 'soft', 'extra'" );
124
+ }
125
+ $args['fail'] = $msg['fail'];
126
+ if ( !array_key_exists( 'priority', $msg ) ) {
127
+ throw new \InvalidArgumentException( "Missing 'priority'" );
128
+ }
129
+ if ( !in_array( $msg['priority'], [
130
+ LOG_CRIT,
131
+ LOG_ERR,
132
+ LOG_WARNING,
133
+ LOG_NOTICE,
134
+ LOG_INFO,
135
+ LOG_DEBUG
136
+ ] ) ) {
137
+ throw new \UnexpectedValueException( "Invalid 'priority'" );
138
+ }
139
+ $args['priority'] = $msg['priority'];
140
+ if ( !array_key_exists( 'event_class', $msg ) ) {
141
+ throw new \InvalidArgumentException( "Missing 'event_class'" );
142
+ }
143
+ if ( !array_key_exists( $event_class = strtolower( $msg['event_class'] ), $event_classes ) ) {
144
+ throw new \UnexpectedValueException( "Invalid 'event_class'" );
145
+ }
146
+ $args['class'] = $event_class;
147
+ $event_class = $event_classes[$event_class];
148
+ $log = sprintf( "WP_FAIL2BAN_%s_LOG", strtoupper( $event_class ) );
149
+ if ( !array_key_exists( 'event_id', $msg ) ) {
150
+ throw new \InvalidArgumentException( "Missing 'event_id'" );
151
+ }
152
+ if ( ($msg['event_id'] & 0xffff) !== $msg['event_id'] ) {
153
+ throw new \UnexpectedValueException( "Invalid 'event_id'" );
154
+ }
155
+ $args['event_id'] = WPF2B_EVENT_TYPE_PLUGIN | $event_class | $msg['event_id'];
156
+ if ( !array_key_exists( 'message', $msg ) ) {
157
+ throw new \InvalidArgumentException( "Missing 'message'" );
158
+ }
159
+ if ( !is_string( $msg['message'] ) ) {
160
+ throw new \UnexpectedValueException( "Invalid 'message'" );
161
+ }
162
+ $args['message'] = $msg['message'];
163
+ if ( !array_key_exists( 'vars', $msg ) ) {
164
+ throw new \InvalidArgumentException( "Missing 'vars'" );
165
+ }
166
+ if ( !is_array( $msg['vars'] ) ) {
167
+ throw new \UnexpectedValueException( "Invalid 'vars'" );
168
+ }
169
+ $args['vars'] = $msg['vars'];
170
+ $wp_fail2ban['plugins'][$plugin_slug]['messages'][$msg['slug']] = $args;
171
+ }
172
 
173
+ add_action(
174
+ 'wp_fail2ban_register_message',
175
+ __NAMESPACE__ . '\\register_message',
176
+ 1,
177
+ 2
178
+ );
179
+ /**
180
+ * Check if message is registered.
181
+ *
182
+ * NB: Assumes plugin is registered.
183
+ *
184
+ * @since 4.2.0
185
+ *
186
+ * @param string $plugin_slug
187
+ * @param string $message_slug
188
+ *
189
+ * @return bool
190
+ */
191
+ function is_registered_plugin_message( $plugin_slug, $message_slug )
192
+ {
193
+ global $wp_fail2ban ;
194
+ return array_key_exists( $message_slug, $wp_fail2ban['plugins'][$plugin_slug]['messages'] );
195
+ }
196
 
197
+ /**
198
+ * Log plugin message.
199
+ *
200
+ * @since 4.2.0
201
+ *
202
+ * @param string $plugin_slug Plugin slug for registered message
203
+ * @param string $message_slug Message slug for registered message
204
+ * @param array $vars Substitution vars
205
+ */
206
+ function log_message( $plugin_slug, $message_slug = null, array $vars = array() )
207
+ {
208
+ global $wp_fail2ban ;
209
+ if ( !is_registered_plugin( $plugin_slug ) ) {
210
+ throw new \InvalidArgumentException( 'plugin not registered' );
211
+ }
212
+ if ( !is_registered_plugin_message( $plugin_slug, $message_slug ) ) {
213
+ throw new \InvalidArgumentException( 'message not registered' );
214
+ }
215
+ $args = $wp_fail2ban['plugins'][$plugin_slug]['messages'][$message_slug];
216
+ $msg = $args['message'];
217
+ foreach ( $args['vars'] as $name => $regex ) {
218
+ if ( array_key_exists( $name, $vars ) ) {
219
+ $msg = str_replace( "___{$name}___", $vars[$name], $msg );
220
  }
 
 
 
 
 
 
221
  }
222
+ openlog( sprintf( 'WP_FAIL2BAN_PLUGIN_%s_LOG', strtoupper( $args['class'] ) ) );
223
+ syslog( $args['priority'], "({$plugin_slug}) {$msg}" );
224
+ closelog();
225
+ // @codeCoverageIgnoreEnd
226
  }
227
 
228
+ add_action(
229
+ 'wp_fail2ban_log_message',
230
+ __NAMESPACE__ . '\\log_message',
231
+ 1,
232
+ 3
233
+ );
feature/spam.php CHANGED
@@ -1,51 +1,60 @@
1
  <?php
 
2
  /**
3
  * Spam comments
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/spam.php');
 
 
 
 
12
 
 
13
  /**
14
- * @since 4.0.5
 
 
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\log_spam_comment')) {
17
- /**
18
- * Catch comments marked as spam
19
- *
20
- * @since 3.5.0
21
- *
22
- * @param int $comment_id
23
- * @param string $comment_status
24
- *
25
- * @wp-f2b-hard Spam comment \d+
26
- */
27
- function log_spam_comment($comment_id, $comment_status)
28
- {
29
- if ('spam' === $comment_status) {
30
- if (is_null($comment = get_comment($comment_id, ARRAY_A))) {
31
- /**
32
- * @todo: decide what to do about this
33
- */
34
- } else {
35
- $remote_addr = (empty($comment['comment_author_IP']))
36
- ? 'unknown' // @codeCoverageIgnore
37
- : $comment['comment_author_IP'];
38
-
39
- openlog('WP_FAIL2BAN_SPAM_LOG');
40
- syslog(LOG_NOTICE, "Spam comment {$comment_id}", $remote_addr);
41
- closelog();
42
-
43
- do_action(__FUNCTION__, $comment_id, $comment_status);
44
- }
45
  }
46
- };
47
- add_action('comment_post', __NAMESPACE__.'\log_spam_comment', 10, 2);
48
- add_action('wp_set_comment_status', __NAMESPACE__.'\log_spam_comment', 10, 2);
49
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
-
1
  <?php
2
+
3
  /**
4
  * Spam comments
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5
16
+ */
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\log_spam_comment' ) ) {
19
  /**
20
+ * Catch comments marked as spam
21
+ *
22
+ * @since 3.5.0
23
+ *
24
+ * @param int $comment_id
25
+ * @param string $comment_status
26
+ *
27
+ * @wp-f2b-hard Spam comment \d+
28
  */
29
+ function log_spam_comment( $comment_id, $comment_status )
30
+ {
31
+ if ( 'spam' === $comment_status ) {
32
+
33
+ if ( is_null( $comment = get_comment( $comment_id, ARRAY_A ) ) ) {
34
+ /**
35
+ * @todo: decide what to do about this
36
+ */
37
+ } else {
38
+ $remote_addr = ( empty($comment['comment_author_IP']) ? 'unknown' : $comment['comment_author_IP'] );
39
+ openlog( 'WP_FAIL2BAN_SPAM_LOG' );
40
+ syslog( LOG_NOTICE, "Spam comment {$comment_id}", $remote_addr );
41
+ closelog();
42
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
+
45
+ }
 
46
  }
47
+
48
+ add_action(
49
+ 'comment_post',
50
+ __NAMESPACE__ . '\\log_spam_comment',
51
+ 10,
52
+ 2
53
+ );
54
+ add_action(
55
+ 'wp_set_comment_status',
56
+ __NAMESPACE__ . '\\log_spam_comment',
57
+ 10,
58
+ 2
59
+ );
60
  }
 
feature/user-enum.php CHANGED
@@ -1,129 +1,145 @@
1
  <?php
 
2
  /**
3
  * User enumeration
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/user-enum.php');
12
-
 
 
 
 
13
  /**
14
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\_log_bail_user_enum')) {
17
- /**
18
- * Common enumeration handling
19
- *
20
- * @since 4.3.0 Remove JSON support
21
- * @since 4.1.0 Add JSON support
22
- * @since 4.0.0
23
- *
24
- * @param bool $is_json
25
- *
26
- * @return \WP_Error
27
- *
28
- * @wp-f2b-hard Blocked user enumeration attempt
29
- */
30
- function _log_bail_user_enum()
31
- {
32
- openlog();
33
- syslog(LOG_NOTICE, 'Blocked user enumeration attempt');
34
- closelog();
35
-
36
- do_action(__FUNCTION__);
37
-
38
- return bail();
39
- }
40
  }
41
 
 
 
 
 
 
 
42
  /**
43
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
 
 
44
  */
45
- if (!function_exists(__NAMESPACE__.'\parse_request')) {
46
- /**
47
- * Catch traditional user enum
48
- *
49
- * @see \WP::parse_request()
50
- *
51
- * @since 4.3.0 Refactored to make XDebug happy; h/t @dinghy
52
- * Changed cap to 'edit_others_posts'
53
- * @since 3.5.0 Refactored for unit testing
54
- * @since 2.1.0
55
- *
56
- * @param \WP $query
57
- *
58
- * @return \WP
59
- */
60
- function parse_request($query)
61
- {
62
- if (!current_user_can('edit_others_posts') && intval(array_value('author', $query->query_vars))) {
63
- _log_bail_user_enum();
64
- }
65
-
66
- return $query;
67
  }
68
- add_filter('parse_request', __NAMESPACE__.'\parse_request', 1);
69
  }
 
 
 
 
 
 
 
 
 
 
 
 
70
 
 
71
  /**
72
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
 
 
73
  */
74
- if (!function_exists(__NAMESPACE__.'\rest_user_query')) {
75
- /**
76
- * Catch RESTful user list
77
- *
78
- * @see \WP_REST_Users_Controller::get_items()
79
- *
80
- * @since 4.3.0 Change to 'edit_others_posts'
81
- * @since 4.0.0
82
- *
83
- * @param array $prepared_args
84
- * @param \WP_REST_Request $request
85
- *
86
- * @return array|\WP_Error
87
- */
88
- function rest_user_query($prepared_args, $request)
89
- {
90
- if (!current_user_can('edit_others_posts')) {
91
- return _log_bail_user_enum();
92
- }
93
-
94
- return $prepared_args;
95
  }
96
- add_filter('rest_user_query', __NAMESPACE__.'\rest_user_query', 10, 2);
97
  }
 
 
 
 
 
 
 
 
98
 
 
 
 
 
 
99
  /**
100
- * @since 4.2.7
 
 
 
 
 
 
 
 
 
 
 
101
  */
102
- if (!function_exists(__NAMESPACE__.'\oembed_response_data')) {
103
- /**
104
- * Catch oembed user info
105
- *
106
- * @codeCoverageIgnore
107
- *
108
- * @see \get_oembed_response_data()
109
- *
110
- * @since 4.2.7
111
- *
112
- * @param array $data The response data.
113
- * @param WP_Post $post The post object.
114
- * @param int $width The requested width.
115
- * @param int $height The calculated height.
116
- *
117
- * @return array
118
- */
119
- function oembed_response_data($data, $post, $width, $height)
120
- {
121
- unset($data['author_name']);
122
- unset($data['author_url']);
123
-
124
- return $data;
125
- }
126
- add_filter('oembed_response_data', __NAMESPACE__.'\oembed_response_data', PHP_INT_MAX-1, 4);
127
  }
 
 
 
 
 
 
 
 
128
  }
129
-
1
  <?php
2
+
3
  /**
4
  * User enumeration
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5 Guard
16
+ */
17
+ if ( !function_exists( __NAMESPACE__ . '\\_log_bail_user_enum' ) ) {
18
  /**
19
+ * Common enumeration handling
20
+ *
21
+ * @since 4.2.7 Remove JSON support
22
+ * @since 4.1.0 Add JSON support
23
+ * @since 4.0.0
24
+ *
25
+ * @return \WP_Error
26
+ *
27
+ * @wp-f2b-hard Blocked user enumeration attempt
28
  */
29
+ function _log_bail_user_enum()
30
+ {
31
+ openlog();
32
+ syslog( LOG_NOTICE, 'Blocked user enumeration attempt' );
33
+ closelog();
34
+ // @codeCoverageIgnoreEnd
35
+ return bail();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
+ }
39
+ /**
40
+ * @since 4.0.5 Guard
41
+ */
42
+
43
+ if ( !function_exists( __NAMESPACE__ . '\\parse_request' ) ) {
44
  /**
45
+ * Catch traditional user enum
46
+ *
47
+ * @see \WP::parse_request()
48
+ *
49
+ * @since 4.2.8 Refactor to make XDebug happy (h/t @dinghy)
50
+ * @since 3.5.0 Refactored for unit testing
51
+ * @since 2.1.0
52
+ *
53
+ * @param \WP $query
54
+ *
55
+ * @return \WP
56
  */
57
+ function parse_request( $query )
58
+ {
59
+ if ( !current_user_can( 'list_users' ) && array_key_exists( 'author', $query->query_vars ) && intval( $query->query_vars['author'] ) ) {
60
+ _log_bail_user_enum();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
+ return $query;
63
  }
64
+
65
+ add_filter(
66
+ 'parse_request',
67
+ __NAMESPACE__ . '\\parse_request',
68
+ 1,
69
+ 2
70
+ );
71
+ }
72
+
73
+ /**
74
+ * @since 4.0.5 Guard
75
+ */
76
 
77
+ if ( !function_exists( __NAMESPACE__ . '\\rest_user_query' ) ) {
78
  /**
79
+ * Catch RESTful user list
80
+ *
81
+ * @see \WP_REST_Users_Controller::get_items()
82
+ *
83
+ * @since 4.2.8 Change cap to edit_others_posts to play better with GB
84
+ * @since 4.0.0
85
+ *
86
+ * @param array $prepared_args
87
+ * @param \WP_REST_Request $request
88
+ *
89
+ * @return array|\WP_Error
90
  */
91
+ function rest_user_query( $prepared_args, $request )
92
+ {
93
+ if ( !current_user_can( 'edit_others_posts' ) ) {
94
+ return _log_bail_user_enum();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
+ return $prepared_args;
97
  }
98
+
99
+ add_filter(
100
+ 'rest_user_query',
101
+ __NAMESPACE__ . '\\rest_user_query',
102
+ 10,
103
+ 2
104
+ );
105
+ }
106
 
107
+ /**
108
+ * @since 4.2.6 Guard
109
+ */
110
+
111
+ if ( !function_exists( __NAMESPACE__ . '\\oembed_response_data' ) ) {
112
  /**
113
+ *
114
+ * @see \get_oembed_response_data()
115
+ *
116
+ * @since 4.2.7.1 Fix `add_filter()` params
117
+ * @since 4.2.6
118
+ *
119
+ * @param array $data The response data.
120
+ * @param \WP_Post $post The post object.
121
+ * @param int $width The requested width.
122
+ * @param int $height The calculated height.
123
+ *
124
+ * @return array
125
  */
126
+ function oembed_response_data(
127
+ $data,
128
+ $post,
129
+ $width,
130
+ $height
131
+ )
132
+ {
133
+ unset( $data['author_name'] );
134
+ unset( $data['author_url'] );
135
+ return $data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
+
138
+ add_filter(
139
+ 'oembed_response_data',
140
+ __NAMESPACE__ . '\\oembed_response_data',
141
+ PHP_INT_MAX - 1,
142
+ // almost last in case something expects author_xxx to be set
143
+ 4
144
+ );
145
  }
 
feature/user.php CHANGED
@@ -1,77 +1,61 @@
1
  <?php
 
2
  /**
3
  * Blocked user functionality
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/user.php');
 
 
 
 
12
 
 
13
  /**
14
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\block_users')) {
17
- /**
18
- * Catch blocked users
19
- *
20
- * @see \wp_authenticate()
21
- *
22
- * @since 4.3.0 Add blocking username logins
23
- * @since 3.5.0 Refactored for unit testing
24
- * @since 2.0.0
25
- *
26
- * @param mixed|null $user
27
- * @param string $username
28
- * @param string $password
29
- *
30
- * @return mixed|null
31
- *
32
- * @wp-f2b-hard Blocked authentication attempt for .*
33
- * @wp-f2b-hard Blocked username authentication attempt for .*
34
- */
35
- function block_users($user, $username, $password)
36
- {
37
- if (!empty($username)) {
38
- if (defined('WP_FAIL2BAN_BLOCK_USERNAME_LOGIN') && WP_FAIL2BAN_BLOCK_USERNAME_LOGIN) {
39
- if (is_email($username)) {
40
- // OK!
41
- } else {
42
- openlog();
43
- syslog(LOG_NOTICE, "Blocked username authentication attempt for {$username}");
44
- closelog();
45
-
46
- do_action(__FUNCTION__.'.block_username_login', $user, $username, $password);
47
-
48
- return bail(); // for testing
49
- }
50
- }
51
-
52
- if (defined('WP_FAIL2BAN_BLOCKED_USERS') && WP_FAIL2BAN_BLOCKED_USERS) {
53
- /**
54
- * @since 3.5.0 Arrays allowed in PHP 7
55
- */
56
- $matched = (is_array(WP_FAIL2BAN_BLOCKED_USERS))
57
- ? in_array($username, WP_FAIL2BAN_BLOCKED_USERS)
58
- : preg_match('/'.WP_FAIL2BAN_BLOCKED_USERS.'/i', $username);
59
-
60
- if ($matched) {
61
- openlog();
62
- syslog(LOG_NOTICE, "Blocked authentication attempt for {$username}");
63
- closelog();
64
-
65
- do_action(__FUNCTION__.'.blocked_users', $user, $username, $password);
66
-
67
- return bail(); // for testing
68
- }
69
- }
70
  }
71
-
72
- return $user;
73
  }
74
- add_filter('authenticate', __NAMESPACE__.'\block_users', 1, 3);
 
75
  }
 
 
 
 
 
 
 
76
  }
77
-
1
  <?php
2
+
3
  /**
4
  * Blocked user functionality
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5 Guard
16
+ */
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\authenticate' ) ) {
19
  /**
20
+ * Catched blocked users
21
+ *
22
+ * @since 3.5.0 Refactored for unit testing
23
+ * @since 2.0.0
24
+ *
25
+ * @param mixed|null $user
26
+ * @param string $username
27
+ * @param string $password
28
+ *
29
+ * @return mixed|null
30
+ *
31
+ * @wp-f2b-hard Blocked authentication attempt for .*
32
  */
33
+ function authenticate( $user, $username, $password )
34
+ {
35
+
36
+ if ( !empty($username) ) {
37
+ /**
38
+ * @since 3.5.0 Arrays allowed in PHP 7
39
+ */
40
+ $matched = ( is_array( WP_FAIL2BAN_BLOCKED_USERS ) ? in_array( $username, WP_FAIL2BAN_BLOCKED_USERS ) : preg_match( '/' . WP_FAIL2BAN_BLOCKED_USERS . '/i', $username ) );
41
+
42
+ if ( $matched ) {
43
+ openlog();
44
+ syslog( LOG_NOTICE, "Blocked authentication attempt for {$username}" );
45
+ closelog();
46
+ // @codeCoverageIgnoreEnd
47
+ bail();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  }
49
+
 
50
  }
51
+
52
+ return $user;
53
  }
54
+
55
+ add_filter(
56
+ 'authenticate',
57
+ __NAMESPACE__ . '\\authenticate',
58
+ 1,
59
+ 3
60
+ );
61
  }
 
feature/xmlrpc.php CHANGED
@@ -1,102 +1,108 @@
1
  <?php
 
2
  /**
3
  * XML-RPC functionality
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/xmlrpc.php');
12
-
13
- /**
14
- * @since 4.0.5 Guard
15
- */
16
- if (!function_exists(__NAMESPACE__.'\xmlrpc_login_error')) {
17
- /**
18
- * Catch multiple XML-RPC authentication failures
19
- *
20
- * @see \wp_xmlrpc_server::login()
21
- *
22
- * @since 4.0.0 Return $error
23
- * @since 3.5.0 Refactored for unit testing
24
- * @since 3.0.0
25
- *
26
- * @param \IXR_Error $error
27
- * @param \WP_Error $user
28
- *
29
- * @return \IXR_Error
30
- *
31
- * @wp-f2b-hard XML-RPC multicall authentication failure
32
- */
33
- function xmlrpc_login_error($error, $user)
34
- {
35
- static $attempts = 0;
36
-
37
- if (++$attempts > 1) {
38
- openlog();
39
- syslog(LOG_NOTICE, 'XML-RPC multicall authentication failure');
40
- closelog();
41
-
42
- do_action(__FUNCTION__, $error, $user);
43
-
44
- bail();
45
- } else {
46
- return $error;
47
- }
48
- } // @codeCoverageIgnore
49
- add_action('xmlrpc_login_error', __NAMESPACE__.'\xmlrpc_login_error', 10, 2);
50
- }
51
 
 
52
  /**
53
- * @since 4.0.5 Guard
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  */
55
- if (!function_exists(__NAMESPACE__.'\xmlrpc_pingback_error')) {
56
- /**
57
- * Catch failed pingbacks
58
- *
59
- * @see \wp_xmlrpc_server::pingback_error()
60
- *
61
- * @since 4.0.0 Return $ixr_error
62
- * @since 3.5.0 Refactored for unit testing
63
- * @since 3.0.0
64
- *
65
- * @param \IXR_Error $ixr_error
66
- *
67
- * @return \IXR_Error
68
- *
69
- * @wp-f2b-hard Pingback error .* generated
70
- */
71
- function xmlrpc_pingback_error($ixr_error)
72
- {
73
- if (48 !== $ixr_error->code) {
74
- openlog();
75
- syslog(LOG_NOTICE, 'Pingback error '.$ixr_error->code.' generated');
76
- closelog();
77
-
78
- do_action(__FUNCTION__, $ixr_error);
79
- }
80
- return $ixr_error;
81
  }
82
- add_filter('xmlrpc_pingback_error', __NAMESPACE__.'\xmlrpc_pingback_error', 5);
83
  }
 
 
 
 
 
 
 
 
84
 
 
 
 
85
 
 
86
  /**
87
- * @since 4.0.0 Refactored
88
- * @since 2.2.0
89
- */
90
- if (defined('WP_FAIL2BAN_LOG_PINGBACKS') && true === WP_FAIL2BAN_LOG_PINGBACKS) {
91
- require_once 'xmlrpc/pingback.php';
92
- }
93
-
94
- /**
95
- * @since 4.0.0 Refactored
96
- * @since 3.6.0
 
 
 
97
  */
98
- if (defined('WP_FAIL2BAN_XMLRPC_LOG') && '' < WP_FAIL2BAN_XMLRPC_LOG) {
99
- require_once 'xmlrpc/log.php';
 
 
 
 
 
 
 
 
 
100
  }
 
 
101
  }
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
  * XML-RPC functionality
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5 Guard
16
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\xmlrpc_login_error' ) ) {
19
  /**
20
+ * Catch multiple XML-RPC authentication failures
21
+ *
22
+ * @see \wp_xmlrpc_server::login()
23
+ *
24
+ * @since 4.0.0 Return $error
25
+ * @since 3.5.0 Refactored for unit testing
26
+ * @since 3.0.0
27
+ *
28
+ * @param \IXR_Error $error
29
+ * @param \WP_Error $user
30
+ *
31
+ * @return \IXR_Error
32
+ *
33
+ * @wp-f2b-hard XML-RPC multicall authentication failure
34
  */
35
+ function xmlrpc_login_error( $error, $user )
36
+ {
37
+ static $attempts = 0 ;
38
+
39
+ if ( ++$attempts > 1 ) {
40
+ openlog();
41
+ syslog( LOG_NOTICE, 'XML-RPC multicall authentication failure' );
42
+ closelog();
43
+ // @codeCoverageIgnoreEnd
44
+ bail();
45
+ } else {
46
+ return $error;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
+
49
  }
50
+
51
+ add_action(
52
+ 'xmlrpc_login_error',
53
+ __NAMESPACE__ . '\\xmlrpc_login_error',
54
+ 10,
55
+ 2
56
+ );
57
+ }
58
 
59
+ /**
60
+ * @since 4.0.5 Guard
61
+ */
62
 
63
+ if ( !function_exists( __NAMESPACE__ . '\\xmlrpc_pingback_error' ) ) {
64
  /**
65
+ * Catch failed pingbacks
66
+ *
67
+ * @see \wp_xmlrpc_server::pingback_error()
68
+ *
69
+ * @since 4.0.0 Return $ixr_error
70
+ * @since 3.5.0 Refactored for unit testing
71
+ * @since 3.0.0
72
+ *
73
+ * @param \IXR_Error $ixr_error
74
+ *
75
+ * @return \IXR_Error
76
+ *
77
+ * @wp-f2b-hard Pingback error .* generated
78
  */
79
+ function xmlrpc_pingback_error( $ixr_error )
80
+ {
81
+
82
+ if ( 48 !== $ixr_error->code ) {
83
+ openlog();
84
+ syslog( LOG_NOTICE, 'Pingback error ' . $ixr_error->code . ' generated' );
85
+ closelog();
86
+ // @codeCoverageIgnoreEnd
87
+ }
88
+
89
+ return $ixr_error;
90
  }
91
+
92
+ add_filter( 'xmlrpc_pingback_error', __NAMESPACE__ . '\\xmlrpc_pingback_error', 5 );
93
  }
94
 
95
+ /**
96
+ * @since 4.0.0 Refactored
97
+ * @since 2.2.0
98
+ */
99
+ if ( defined( 'WP_FAIL2BAN_LOG_PINGBACKS' ) && true === WP_FAIL2BAN_LOG_PINGBACKS ) {
100
+ require_once 'xmlrpc/pingback.php';
101
+ }
102
+ /**
103
+ * @since 4.0.0 Refactored
104
+ * @since 3.6.0
105
+ */
106
+ if ( defined( 'WP_FAIL2BAN_XMLRPC_LOG' ) && '' < WP_FAIL2BAN_XMLRPC_LOG ) {
107
+ require_once 'xmlrpc/log.php';
108
+ }
feature/xmlrpc/log.php CHANGED
@@ -4,30 +4,32 @@
4
  *
5
  * @package wp-fail2ban
6
  * @since 4.0.0
7
- * @codeCoverageIgnore
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
- if (defined('ABSPATH')) {
12
- /**
13
- * Log XML-RPC requests
14
- *
15
- * It seems attackers are doing weird things with XML-RPC. This makes it easy to
16
- * log them for analysis and future blocking.
17
- *
18
- * @since 4.0.0 Fix: Removed HTTP_RAW_POST_DATA
19
- * https://wordpress.org/support/?p=10971843
20
- * @since 3.6.0
21
- */
22
- if (false === ($fp = fopen(WP_FAIL2BAN_XMLRPC_LOG, 'a+'))) {
23
- // TODO: decided whether to log this
24
- } else {
25
- $raw_data = (version_compare(PHP_VERSION, '7.0.0') >= 0)
26
- ? file_get_contents('php://input')
27
- : $HTTP_RAW_POST_DATA;
28
-
29
- fprintf($fp, "# ---\n# Date: %s\n# IP: %s\n\n%s\n", date(DATE_ATOM), remote_addr(), $raw_data);
30
- fclose($fp);
31
- }
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  *
5
  * @package wp-fail2ban
6
  * @since 4.0.0
 
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
+ if (!defined('ABSPATH')) {
11
+ exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
+ /**
15
+ * Log XML-RPC requests
16
+ *
17
+ * It seems attackers are doing weird things with XML-RPC. This makes it easy to
18
+ * log them for analysis and future blocking.
19
+ *
20
+ * @since 4.0.0 Fix: Removed HTTP_RAW_POST_DATA
21
+ * https://wordpress.org/support/?p=10971843
22
+ * @since 3.6.0
23
+ *
24
+ * @codeCoverageIgnore
25
+ */
26
+ if (false === ($fp = fopen(WP_FAIL2BAN_XMLRPC_LOG, 'a+'))) {
27
+ // TODO: decided whether to log this
28
+ } else {
29
+ $raw_data = (version_compare(PHP_VERSION, '7.0.0') >= 0)
30
+ ? file_get_contents('php://input')
31
+ : $HTTP_RAW_POST_DATA;
32
+
33
+ fprintf($fp, "# ---\n# Date: %s\n# IP: %s\n\n%s\n", date(DATE_ATOM), remote_addr(), $raw_data);
34
+ fclose($fp);
35
+ }
feature/xmlrpc/pingback.php CHANGED
@@ -1,38 +1,40 @@
1
  <?php
 
2
  /**
3
  * pingback logging
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- include_once_exists(WP_FAIL2BAN_DIR.'/premium/feature/xmlrpc/pingback.php');
 
 
 
 
12
 
 
13
  /**
14
- * @since 4.0.5 Guard
 
 
 
 
 
15
  */
16
- if (!function_exists(__NAMESPACE__.'\xmlrpc_call')) {
17
- /**
18
- * Log pingbacks
19
- *
20
- * @since 3.5.0 Refactored for unit testing
21
- * @since 2.2.0
22
- *
23
- * @param string $call
24
- */
25
- function xmlrpc_call($call)
26
- {
27
- if ('pingback.ping' == $call) {
28
- openlog('WP_FAIL2BAN_PINGBACK_LOG');
29
- syslog(LOG_INFO, 'Pingback requested');
30
- closelog();
31
-
32
- do_action(__FUNCTION__, $call);
33
- }
34
  }
35
- add_action('xmlrpc_call', __NAMESPACE__.'\xmlrpc_call');
36
  }
 
 
37
  }
38
-
1
  <?php
2
+
3
  /**
4
  * pingback logging
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.0.0
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ /**
15
+ * @since 4.0.5 Guard
16
+ */
17
 
18
+ if ( !function_exists( __NAMESPACE__ . '\\xmlrpc_call' ) ) {
19
  /**
20
+ * Log pingbacks
21
+ *
22
+ * @since 3.5.0 Refactored for unit testing
23
+ * @since 2.2.0
24
+ *
25
+ * @param string $call
26
  */
27
+ function xmlrpc_call( $call )
28
+ {
29
+
30
+ if ( 'pingback.ping' == $call ) {
31
+ openlog( 'WP_FAIL2BAN_PINGBACK_LOG' );
32
+ syslog( LOG_INFO, 'Pingback requested' );
33
+ closelog();
34
+ // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
35
  }
36
+
37
  }
38
+
39
+ add_action( 'xmlrpc_call', __NAMESPACE__ . '\\xmlrpc_call' );
40
  }
 
filters.d/wordpress-extra.conf CHANGED
@@ -1,5 +1,5 @@
1
  # Fail2Ban filter for WordPress extra failures
2
- # Auto-generated: 2020-04-16T05:48:22+00:00
3
  #
4
 
5
  [INCLUDES]
1
  # Fail2Ban filter for WordPress extra failures
2
+ # Auto-generated: 2020-04-17T15:52:10+00:00
3
  #
4
 
5
  [INCLUDES]
filters.d/wordpress-hard.conf CHANGED
@@ -1,5 +1,5 @@
1
  # Fail2Ban filter for WordPress hard failures
2
- # Auto-generated: 2020-04-16T05:48:22+00:00
3
  #
4
 
5
  [INCLUDES]
@@ -16,7 +16,6 @@ failregex = ^%(__prefix_line)sAuthentication attempt for unknown user .* from <H
16
  ^%(__prefix_line)sSpam comment \d+ from <HOST>$
17
  ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$
18
  ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
19
- ^%(__prefix_line)sBlocked username authentication attempt for .* from <HOST>$
20
  ^%(__prefix_line)sXML-RPC multicall authentication failure from <HOST>$
21
  ^%(__prefix_line)sPingback error .* generated from <HOST>$
22
 
1
  # Fail2Ban filter for WordPress hard failures
2
+ # Auto-generated: 2020-04-17T15:52:10+00:00
3
  #
4
 
5
  [INCLUDES]
16
  ^%(__prefix_line)sSpam comment \d+ from <HOST>$
17
  ^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$
18
  ^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
 
19
  ^%(__prefix_line)sXML-RPC multicall authentication failure from <HOST>$
20
  ^%(__prefix_line)sPingback error .* generated from <HOST>$
21
 
filters.d/wordpress-soft.conf CHANGED
@@ -1,5 +1,5 @@
1
  # Fail2Ban filter for WordPress soft failures
2
- # Auto-generated: 2020-04-16T05:48:22+00:00
3
  #
4
 
5
  [INCLUDES]
@@ -10,8 +10,7 @@ before = common.conf
10
 
11
  _daemon = (?:wordpress|wp)
12
 
13
- failregex = ^%(__prefix_line)sEmpty username from <HOST>$
14
- ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
15
  ^%(__prefix_line)sREST authentication failure for .* from <HOST>$
16
  ^%(__prefix_line)sXML-RPC authentication failure for .* from <HOST>$
17
 
1
  # Fail2Ban filter for WordPress soft failures
2
+ # Auto-generated: 2020-04-17T15:52:10+00:00
3
  #
4
 
5
  [INCLUDES]
10
 
11
  _daemon = (?:wordpress|wp)
12
 
13
+ failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
 
14
  ^%(__prefix_line)sREST authentication failure for .* from <HOST>$
15
  ^%(__prefix_line)sXML-RPC authentication failure for .* from <HOST>$
16
 
lib/activation.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /**
3
- * WP fail2ban activation
4
- *
5
- * @package wp-fail2ban
6
- * @since 4.3.0
7
- */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
-
10
- if (defined('ABSPATH')) {
11
- \register_activation_hook(WP_FAIL2BAN_FILE, function () {
12
- foreach (get_mu_plugins() as $plugin => $data) {
13
- if (0 === strpos($data['Name'], 'WP fail2ban')) {
14
- $wp_f2b_ver = substr(WP_FAIL2BAN_VER, 0, strrpos(WP_FAIL2BAN_VER, '.'));
15
- $error_msg = __('<h1>Cannot activate WP fail2ban</h1>', 'wp-fail2ban');
16
- $mu_file = WPMU_PLUGIN_DIR.'/'.$plugin;
17
- if (is_link($mu_file)) {
18
- if (false === ($link = readlink($mu_file)) ||
19
- false === ($path = realpath($mu_file)))
20
- {
21
- $h3 = __('A broken symbolic link was found in <tt>mu-plugins</tt>:');
22
- $error_msg .= <<<__ERROR__
23
- <h3>{$h3}</h3>
24
- <p><tt>{$mu_file}</tt></p>
25
- __ERROR__;
26
- } elseif (WP_FAIL2BAN_FILE == $path) {
27
- // OK, we're linking to ourself
28
- } else {
29
- $mu_file = str_replace('/', '/<wbr>', $mu_file);
30
- $mu_file = substr($mu_file, strlen(WPMU_PLUGIN_DIR)-1);
31
-
32
- $h3 = __('A conflicting symbolic link was found in <tt>mu-plugins</tt>:');
33
- $error_msg .= <<<__ERROR__
34
- <h3>{$h3}</h3>
35
- <style>
36
- table { text-align: center; }
37
- td { width: 50%; }
38
- th { font-size: 200%; }
39
- td, th { font-family: monospace; }
40
- span.tt { font-weight: bold; }
41
- </style>
42
- <table>
43
- <tr>
44
- <td>{$mu_file}</td>
45
- <th>&DoubleRightArrow;</th>
46
- <td>{$link}</td>
47
- </tr>
48
- <tr>
49
- <td colspan="3"><span class="tt">&equiv;</span> <span>{$path}</span></td>
50
- </tr>
51
- <tr>
52
- <td colspan="3"></td>
53
- </tr>
54
- </table>
55
- __ERROR__;
56
- }
57
-
58
- } else {
59
- $mu_file = str_replace('/', '/<wbr>', $mu_file);
60
- $mu_file = substr($mu_file, strlen(WPMU_PLUGIN_DIR)-1);
61
-
62
- $h3 = __('A conflicting file was found in <tt>mu-plugins</tt>:');
63
- $error_msg .= <<<__ERROR__
64
- <h3>{$h3}</h3>
65
- <p><tt>{$mu_file}</tt></p>
66
- __ERROR__;
67
- }
68
- $error_msg .= sprintf(
69
- __('<p>Please see the <a href="%s" target="_blank">documentation</a> for how to configure %s for <tt>mu-plugins</tt>.</p>'),
70
- "https://docs.wp-fail2ban.com/en/{$wp_f2b_ver}/configuration.html#mu-plugins-support",
71
- $wpf2b
72
- );
73
- $error_msg .= sprintf(__('<p>Click <a href="%s">here</a> to return to the plugins page.</p>'), admin_url('plugins.php'));
74
-
75
- deactivate_plugins(plugin_basename(WP_FAIL2BAN_FILE));
76
- wp_die($error_msg);
77
- }
78
- }
79
-
80
- @include_once WP_FAIL2BAN_DIR.'/premium/activation.php';
81
- });
82
- }
83
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/constants.php CHANGED
@@ -3,120 +3,142 @@
3
  * Constants
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.2.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- // @codeCoverageIgnoreStart
11
- if (defined('ABSPATH')) {
12
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
13
- /*
14
- 31 | Test
15
- 30 | Plugin
16
- 29 |
17
- 28 |
18
- 27 |
19
- 26 |
20
- 25 |
21
- 24 |
22
- ---
23
- 23 | Event Class
24
- 22 | ..
25
- 21 | ..
26
- 20 | ..
27
- 19 | ..
28
- 18 | ..
29
- 17 | ..
30
- 16 | ..
31
- ---
32
- 15 | ID
33
- 14 | ..
34
- 13 | ..
35
- 12 | ..
36
- 11 | ..
37
- 10 | ..
38
- 09 | ..
39
- 08 | ..
40
- ---
41
- 07 | ..
42
- 06 | ..
43
- 05 | ..
44
- 04 | ..
45
- 03 | ..
46
- 02 | ..
47
- 01 | ..
48
- 00 | ..
49
- */
50
-
51
-
52
-
53
- define('WPF2B_EVENT_CLASS_AUTH', 0x00010000);
54
- define('WPF2B_EVENT_CLASS_COMMENT', 0x00020000);
55
- define('WPF2B_EVENT_CLASS_XMLRPC', 0x00040000);
56
- define('WPF2B_EVENT_CLASS_PASSWORD', 0x00080000);
57
- define('WPF2B_EVENT_CLASS_REST', 0x00100000); /** @since 4.1.0 */
58
- define('WPF2B_EVENT_CLASS_SPAM', 0x00200000); /** @since 4.2.0 */
59
- define('WPF2B_EVENT_CLASS_BLOCK', 0x00400000); /** @since 4.3.0*/
60
- define('WPF2B_EVENT_TYPE_PLUGIN', 0x40000000); /** @since 4.2.0 */
61
- define('WPF2B_EVENT_TYPE_TEST', 0x80000000); /** @since 4.2.0 */
62
-
63
-
64
- /**
65
- *
66
- */
67
- define('WPF2B_EVENT_ACTIVATED', 0xffffffff);
68
-
69
-
70
- /**
71
- * Auth
72
- */
73
- define('WPF2B_EVENT_AUTH_OK', WPF2B_EVENT_CLASS_AUTH | 0x0001);
74
- define('WPF2B_EVENT_AUTH_FAIL', WPF2B_EVENT_CLASS_AUTH | 0x0002);
75
- define('WPF2B_EVENT_AUTH_BLOCK_USER', WPF2B_EVENT_CLASS_AUTH | WPF2B_EVENT_CLASS_BLOCK | 0x0004);
76
- define('WPF2B_EVENT_AUTH_BLOCK_USER__', WPF2B_EVENT_CLASS_AUTH | 0x0004); /** @deprecated 4.3.0 */
77
- define('WPF2B_EVENT_AUTH_BLOCK_USER_ENUM', WPF2B_EVENT_CLASS_AUTH | WPF2B_EVENT_CLASS_BLOCK | 0x0008);
78
- define('WPF2B_EVENT_AUTH_BLOCK_USER_ENUM__', WPF2B_EVENT_CLASS_AUTH | 0x0008); /** @deprecated 4.3.0 */
79
- define('WPF2B_EVENT_AUTH_EMPTY_USER', WPF2B_EVENT_CLASS_AUTH | 0x0010);
80
- define('WPF2B_EVENT_AUTH_BLOCK_USERNAME_LOGIN', WPF2B_EVENT_CLASS_AUTH | WPF2B_EVENT_CLASS_BLOCK | 0x0020); /** @since 4.3.0 */
81
-
82
- /**
83
- * Comment
84
- */
85
- define('WPF2B_EVENT_COMMENT', WPF2B_EVENT_CLASS_COMMENT | 0x0001); // 0x00020001
86
- define('WPF2B_EVENT_COMMENT_SPAM', WPF2B_EVENT_CLASS_COMMENT | WPF2B_EVENT_CLASS_SPAM | 0x0001); // 0x00220001
87
- // comment extra
88
- define('WPF2B_EVENT_COMMENT_NOT_FOUND', WPF2B_EVENT_CLASS_COMMENT | 0x0002); // 0x00020002
89
- define('WPF2B_EVENT_COMMENT_CLOSED', WPF2B_EVENT_CLASS_COMMENT | 0x0004); // 0x00020004
90
- define('WPF2B_EVENT_COMMENT_TRASH', WPF2B_EVENT_CLASS_COMMENT | 0x0008); // 0x00020008
91
- define('WPF2B_EVENT_COMMENT_DRAFT', WPF2B_EVENT_CLASS_COMMENT | 0x0010); // 0x00020010
92
- define('WPF2B_EVENT_COMMENT_PASSWORD', WPF2B_EVENT_CLASS_COMMENT | WPF2B_EVENT_CLASS_PASSWORD | 0x0020); // 0x000A0020
93
-
94
- /**
95
- * XML-RPC
96
- */
97
- define('WPF2B_EVENT_XMLRPC_PINGBACK', WPF2B_EVENT_CLASS_XMLRPC | 0x0001);
98
- define('WPF2B_EVENT_XMLRPC_PINGBACK_ERROR', WPF2B_EVENT_CLASS_XMLRPC | 0x0002);
99
- define('WPF2B_EVENT_XMLRPC_MULTI_AUTH_FAIL', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0004);
100
- define('WPF2B_EVENT_XMLRPC_AUTH_OK', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0008);
101
- define('WPF2B_EVENT_XMLRPC_AUTH_FAIL', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0010);
102
-
103
- /**
104
- * Password
105
- */
106
- define('WPF2B_EVENT_PASSWORD_REQUEST', WPF2B_EVENT_CLASS_PASSWORD | 0x0001);
107
-
108
- /**
109
- * REST
110
- * @since 4.1.0
111
- */
112
- define('WPF2B_EVENT_REST_AUTH_OK', WPF2B_EVENT_CLASS_REST | WPF2B_EVENT_CLASS_AUTH | 0x0001);
113
- define('WPF2B_EVENT_REST_AUTH_FAIL', WPF2B_EVENT_CLASS_REST | WPF2B_EVENT_CLASS_AUTH | 0x0002);
114
-
115
- /**
116
- *
117
- */
118
- define('WPF2B_EVENT_DEACTIVATED', 0x00000000);
119
- // phpcs:enable
120
  }
121
- // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
3
  * Constants
4
  *
5
  * @package wp-fail2ban
6
+ * @since 4.2.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
+ if (!defined('ABSPATH')) {
11
+ exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
+
14
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
15
+ /**
16
+ * Defaults
17
+ *
18
+ * @since 4.0.0
19
+ */
20
+ define('DEFAULT_WP_FAIL2BAN_OPENLOG_OPTIONS', LOG_PID|LOG_NDELAY);
21
+ define('DEFAULT_WP_FAIL2BAN_AUTH_LOG', LOG_AUTH);
22
+ define('DEFAULT_WP_FAIL2BAN_COMMENT_LOG', LOG_USER);
23
+ define('DEFAULT_WP_FAIL2BAN_PINGBACK_LOG', LOG_USER);
24
+ define('DEFAULT_WP_FAIL2BAN_PASSWORD_REQUEST_LOG', LOG_USER);
25
+ define('DEFAULT_WP_FAIL2BAN_SPAM_LOG', LOG_AUTH);
26
+ /**
27
+ * @since 4.0.5
28
+ */
29
+ define('DEFAULT_WP_FAIL2BAN_COMMENT_EXTRA_LOG', LOG_AUTH);
30
+ define('DEFAULT_WP_FAIL2BAN_PINGBACK_ERROR_LOG', LOG_AUTH);
31
+ /**
32
+ * @since 4.2.0
33
+ */
34
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_AUTH_LOG', LOG_AUTH);
35
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_COMMENT_LOG', LOG_USER);
36
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_OTHER_LOG', LOG_USER);
37
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_PASSWORD_LOG', LOG_USER);
38
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_REST_LOG', LOG_USER);
39
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_SPAM_LOG', LOG_AUTH);
40
+ define('DEFAULT_WP_FAIL2BAN_PLUGIN_XMLRPC_LOG', LOG_USER);
41
+
42
+ /*
43
+ 31 | Test
44
+ 30 | Plugin
45
+ 29 |
46
+ 28 |
47
+ 27 |
48
+ 26 |
49
+ 25 |
50
+ 24 |
51
+ ---
52
+ 23 | Event Class
53
+ 22 | ..
54
+ 21 | ..
55
+ 20 | ..
56
+ 19 | ..
57
+ 18 | ..
58
+ 17 | ..
59
+ 16 | ..
60
+ ---
61
+ 15 | ID
62
+ 14 | ..
63
+ 13 | ..
64
+ 12 | ..
65
+ 11 | ..
66
+ 10 | ..
67
+ 09 | ..
68
+ 08 | ..
69
+ ---
70
+ 07 | ..
71
+ 06 | ..
72
+ 05 | ..
73
+ 04 | ..
74
+ 03 | ..
75
+ 02 | ..
76
+ 01 | ..
77
+ 00 | ..
78
+ */
79
+
80
+
81
+
82
+ define('WPF2B_EVENT_CLASS_AUTH', 0x00010000);
83
+ define('WPF2B_EVENT_CLASS_COMMENT', 0x00020000);
84
+ define('WPF2B_EVENT_CLASS_XMLRPC', 0x00040000);
85
+ define('WPF2B_EVENT_CLASS_PASSWORD', 0x00080000);
86
+ define('WPF2B_EVENT_CLASS_REST', 0x00100000); /** @since 4.1.0 */
87
+ define('WPF2B_EVENT_CLASS_SPAM', 0x00200000); /** @since 4.2.0 */
88
+ define('WPF2B_EVENT_TYPE_PLUGIN', 0x40000000); /** @since 4.2.0 */
89
+ define('WPF2B_EVENT_TYPE_TEST', 0x80000000); /** @since 4.2.0 */
90
+
91
+
92
+ /**
93
+ *
94
+ */
95
+ define('WPF2B_EVENT_ACTIVATED', 0xffffffff);
96
+
97
+
98
+ /**
99
+ * Auth
100
+ */
101
+ define('WPF2B_EVENT_AUTH_OK', WPF2B_EVENT_CLASS_AUTH | 0x0001);
102
+ define('WPF2B_EVENT_AUTH_FAIL', WPF2B_EVENT_CLASS_AUTH | 0x0002);
103
+ define('WPF2B_EVENT_AUTH_BLOCK_USER', WPF2B_EVENT_CLASS_AUTH | 0x0004);
104
+ define('WPF2B_EVENT_AUTH_BLOCK_USER_ENUM', WPF2B_EVENT_CLASS_AUTH | 0x0008);
105
+
106
+ /**
107
+ * Comment
108
+ */
109
+ define('WPF2B_EVENT_COMMENT', WPF2B_EVENT_CLASS_COMMENT | 0x0001); // 0x00020001
110
+ define('WPF2B_EVENT_COMMENT_SPAM', WPF2B_EVENT_CLASS_COMMENT | WPF2B_EVENT_CLASS_SPAM | 0x0001); // 0x00220001
111
+ // comment extra
112
+ define('WPF2B_EVENT_COMMENT_NOT_FOUND', WPF2B_EVENT_CLASS_COMMENT | 0x0002); // 0x00020002
113
+ define('WPF2B_EVENT_COMMENT_CLOSED', WPF2B_EVENT_CLASS_COMMENT | 0x0004); // 0x00020004
114
+ define('WPF2B_EVENT_COMMENT_TRASH', WPF2B_EVENT_CLASS_COMMENT | 0x0008); // 0x00020008
115
+ define('WPF2B_EVENT_COMMENT_DRAFT', WPF2B_EVENT_CLASS_COMMENT | 0x0010); // 0x00020010
116
+ define('WPF2B_EVENT_COMMENT_PASSWORD', WPF2B_EVENT_CLASS_COMMENT | WPF2B_EVENT_CLASS_PASSWORD | 0x0020); // 0x00020020
117
+
118
+ /**
119
+ * XML-RPC
120
+ */
121
+ define('WPF2B_EVENT_XMLRPC_PINGBACK', WPF2B_EVENT_CLASS_XMLRPC | 0x0001);
122
+ define('WPF2B_EVENT_XMLRPC_PINGBACK_ERROR', WPF2B_EVENT_CLASS_XMLRPC | 0x0002);
123
+ define('WPF2B_EVENT_XMLRPC_MULTI_AUTH_FAIL', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0004);
124
+ define('WPF2B_EVENT_XMLRPC_AUTH_OK', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0008);
125
+ define('WPF2B_EVENT_XMLRPC_AUTH_FAIL', WPF2B_EVENT_CLASS_XMLRPC | WPF2B_EVENT_CLASS_AUTH | 0x0010);
126
+
127
+ /**
128
+ * Password
129
+ */
130
+ define('WPF2B_ACTION_PASSWORD_REQUEST', WPF2B_EVENT_CLASS_PASSWORD | 0x0001);
131
+
132
+ /**
133
+ * REST
134
+ * @since 4.1.0
135
+ */
136
+ define('WPF2B_EVENT_REST_AUTH_OK', WPF2B_EVENT_CLASS_REST | WPF2B_EVENT_CLASS_AUTH | 0x0001);
137
+ define('WPF2B_EVENT_REST_AUTH_FAIL', WPF2B_EVENT_CLASS_REST | WPF2B_EVENT_CLASS_AUTH | 0x0002);
138
+
139
+ /**
140
+ *
141
+ */
142
+ define('WPF2B_EVENT_DEACTIVATED', 0x00000000);
143
+ // phpcs:enable
144
 
lib/convert-data.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
- /**
3
- * Convertors
4
- *
5
- * @package wp-fail2ban
6
- * @since __NEXT_RELEASE
7
- * @php 5.3
8
- */
9
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
-
11
- if (defined('ABSPATH')) { // @codeCoverageIgnore
12
- /**
13
- * Convert various things to various other things.
14
- *
15
- * @since 4.3.0
16
- */
17
- abstract class ConvertData
18
- {
19
- /**
20
- * @var string[] Map Event ID to Slug.
21
- */
22
- public static $Event2Slug = array(
23
- 0x00000000 => 'deactivated',
24
- WPF2B_EVENT_AUTH_OK => 'auth_ok',
25
- WPF2B_EVENT_AUTH_FAIL => 'auth_fail',
26
- WPF2B_EVENT_AUTH_BLOCK_USER => 'auth_block_user',
27
- WPF2B_EVENT_AUTH_BLOCK_USER_ENUM => 'auth_block_user_enum',
28
- WPF2B_EVENT_AUTH_BLOCK_USERNAME_LOGIN => 'auth_block_usernames',
29
- WPF2B_EVENT_AUTH_EMPTY_USER => 'auth_empty_user',
30
- WPF2B_EVENT_COMMENT => 'comment',
31
- WPF2B_EVENT_COMMENT_SPAM => 'comment_spam',
32
- WPF2B_EVENT_COMMENT_NOT_FOUND => 'comment_not_found',
33
- WPF2B_EVENT_COMMENT_CLOSED => 'comment_closed',
34
- WPF2B_EVENT_COMMENT_TRASH => 'comment_trash',
35
- WPF2B_EVENT_COMMENT_DRAFT => 'comment_draft',
36
- WPF2B_EVENT_COMMENT_PASSWORD => 'comment_password',
37
- WPF2B_EVENT_XMLRPC_PINGBACK => 'xmlrpc_pingback',
38
- WPF2B_EVENT_XMLRPC_PINGBACK_ERROR => 'xmlrpc_pingback_error',
39
- WPF2B_EVENT_XMLRPC_MULTI_AUTH_FAIL => 'xmlrpc_multi_auth_fail',
40
- WPF2B_EVENT_XMLRPC_AUTH_OK => 'xmlrpc_auth_ok',
41
- WPF2B_EVENT_XMLRPC_AUTH_FAIL => 'xmlrpc_auth_fail',
42
- WPF2B_EVENT_PASSWORD_REQUEST => 'password_request',
43
- WPF2B_EVENT_REST_AUTH_OK => 'rest_auth_ok',
44
- WPF2B_EVENT_REST_AUTH_FAIL => 'rest_auth_fail',
45
- 0xFFFFFFFF => 'activated',
46
- );
47
-
48
- /**
49
- * @var int[] Map Event Slug to ID.
50
- */
51
- public static $Slug2Event = array(
52
- 'deactivated' => 0x00000000,
53
- 'auth_ok' => WPF2B_EVENT_AUTH_OK,
54
- 'auth_fail' => WPF2B_EVENT_AUTH_FAIL,
55
- 'auth_block_user' => WPF2B_EVENT_AUTH_BLOCK_USER,
56
- 'auth_block_user_enum' => WPF2B_EVENT_AUTH_BLOCK_USER_ENUM,
57
- 'auth_block_usernames' => WPF2B_EVENT_AUTH_BLOCK_USERNAME_LOGIN,
58
- 'auth_empty_user' => WPF2B_EVENT_AUTH_EMPTY_USER,
59
- 'comment_spam' => WPF2B_EVENT_COMMENT_SPAM,
60
- 'comment_not_found' => WPF2B_EVENT_COMMENT_NOT_FOUND,
61
- 'comment_closed' => WPF2B_EVENT_COMMENT_CLOSED,
62
- 'comment_trash' => WPF2B_EVENT_COMMENT_TRASH,
63
- 'comment_draft' => WPF2B_EVENT_COMMENT_DRAFT,
64
- 'comment_password' => WPF2B_EVENT_COMMENT_PASSWORD,
65
- 'xmlrpc_pingback' => WPF2B_EVENT_XMLRPC_PINGBACK,
66
- 'xmlrpc_pingback_error' => WPF2B_EVENT_XMLRPC_PINGBACK_ERROR,
67
- 'xmlrpc_multi_auth_fail' => WPF2B_EVENT_XMLRPC_MULTI_AUTH_FAIL,
68
- 'xmlrpc_auth_ok' => WPF2B_EVENT_XMLRPC_AUTH_OK,
69
- 'xmlrpc_auth_fail' => WPF2B_EVENT_XMLRPC_AUTH_FAIL,
70
- 'password_request' => WPF2B_EVENT_PASSWORD_REQUEST,
71
- 'rest_auth_ok' => WPF2B_EVENT_REST_AUTH_OK,
72
- 'rest_auth_fail' => WPF2B_EVENT_REST_AUTH_FAIL,
73
- 'activated' => 0xFFFFFFFF,
74
- );
75
-
76
- /**
77
- * @var int[] Map syslog facility name to value.
78
- */
79
- public static $FacilityName2Value = array(
80
- 'LOG_AUTH' => LOG_AUTH,
81
- 'LOG_AUTHPRIV' => LOG_AUTHPRIV,
82
- 'LOG_CRON' => LOG_CRON,
83
- 'LOG_DAEMON' => LOG_DAEMON,
84
- 'LOG_KERN' => LOG_KERN,
85
- 'LOG_LOCAL0' => LOG_LOCAL0,
86
- 'LOG_LOCAL1' => LOG_LOCAL1,
87
- 'LOG_LOCAL2' => LOG_LOCAL2,
88
- 'LOG_LOCAL3' => LOG_LOCAL3,
89
- 'LOG_LOCAL4' => LOG_LOCAL4,
90
- 'LOG_LOCAL5' => LOG_LOCAL5,
91
- 'LOG_LOCAL6' => LOG_LOCAL6,
92
- 'LOG_LOCAL7' => LOG_LOCAL7,
93
- 'LOG_LPR' => LOG_LPR,
94
- 'LOG_MAIL' => LOG_MAIL,
95
- 'LOG_NEWS' => LOG_NEWS,
96
- 'LOG_SYSLOG' => LOG_SYSLOG,
97
- 'LOG_USER' => LOG_USER,
98
- 'LOG_UUCP' => LOG_UUCP,
99
- );
100
- }
101
- } // @codeCoverageIgnore
102
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/defaults.php CHANGED
@@ -1,42 +1,79 @@
1
  <?php
2
  /**
3
- * Defaults
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.3.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- // @codeCoverageIgnoreStart
11
- if (defined('ABSPATH')) {
12
- // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
13
- /**
14
- * Defaults
15
- *
16
- * @since 4.0.0
17
- */
18
- define('DEFAULT_WP_FAIL2BAN_OPENLOG_OPTIONS', LOG_PID|LOG_NDELAY);
19
- define('DEFAULT_WP_FAIL2BAN_AUTH_LOG', LOG_AUTH);
20
- define('DEFAULT_WP_FAIL2BAN_COMMENT_LOG', LOG_USER);
21
- define('DEFAULT_WP_FAIL2BAN_PINGBACK_LOG', LOG_USER);
22
- define('DEFAULT_WP_FAIL2BAN_PASSWORD_REQUEST_LOG', LOG_USER);
23
- define('DEFAULT_WP_FAIL2BAN_SPAM_LOG', LOG_AUTH);
24
- /**
25
- * @since 4.0.5
26
- */
27
- define('DEFAULT_WP_FAIL2BAN_COMMENT_EXTRA_LOG', LOG_AUTH);
28
- define('DEFAULT_WP_FAIL2BAN_PINGBACK_ERROR_LOG', LOG_AUTH);
29
- /**
30
- * @since 4.2.0
31
- */
32
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_AUTH_LOG', LOG_AUTH);
33
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_COMMENT_LOG', LOG_USER);
34
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_OTHER_LOG', LOG_USER);
35
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_PASSWORD_LOG', LOG_USER);
36
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_REST_LOG', LOG_USER);
37
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_SPAM_LOG', LOG_AUTH);
38
- define('DEFAULT_WP_FAIL2BAN_PLUGIN_XMLRPC_LOG', LOG_USER);
39
- // phpcs:enable
40
- }
41
- // @codeCoverageIgnoreEnd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
1
  <?php
2
  /**
3
+ * Default Constants
4
  *
5
  * @package wp-fail2ban
6
+ * @since 4.2.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
+ if (!defined('ABSPATH')) {
11
+ exit;
12
+ }
13
+
14
+ /**
15
+ * Allow custom openlog options.
16
+ * e.g. you may not want the PID if logging remotely.
17
+ *
18
+ * @since 3.6.0 Add LOG_NDELAY
19
+ * @since 3.5.0
20
+ */
21
+ if (!defined('WP_FAIL2BAN_OPENLOG_OPTIONS')) {
22
+ define('WP_FAIL2BAN_OPENLOG_OPTIONS', DEFAULT_WP_FAIL2BAN_OPENLOG_OPTIONS);
23
+ }
24
+ /**
25
+ * Make sure all custom logs are defined.
26
+ * @since 3.5.0
27
+ */
28
+ if (!defined('WP_FAIL2BAN_AUTH_LOG')) {
29
+ define('WP_FAIL2BAN_AUTH_LOG', DEFAULT_WP_FAIL2BAN_AUTH_LOG);
30
+ }
31
+ if (!defined('WP_FAIL2BAN_COMMENT_LOG')) {
32
+ define('WP_FAIL2BAN_COMMENT_LOG', DEFAULT_WP_FAIL2BAN_COMMENT_LOG);
33
+ }
34
+ if (!defined('WP_FAIL2BAN_PINGBACK_LOG')) {
35
+ define('WP_FAIL2BAN_PINGBACK_LOG', DEFAULT_WP_FAIL2BAN_PINGBACK_LOG);
36
+ }
37
+ /**
38
+ * @since 4.0.0
39
+ */
40
+ if (!defined('WP_FAIL2BAN_PASSWORD_REQUEST_LOG')) {
41
+ define('WP_FAIL2BAN_PASSWORD_REQUEST_LOG', DEFAULT_WP_FAIL2BAN_PASSWORD_REQUEST_LOG);
42
+ }
43
+ if (!defined('WP_FAIL2BAN_SPAM_LOG')) {
44
+ define('WP_FAIL2BAN_SPAM_LOG', DEFAULT_WP_FAIL2BAN_SPAM_LOG);
45
+ }
46
+ /**
47
+ * @since 4.0.5
48
+ */
49
+ if (!defined('WP_FAIL2BAN_COMMENT_EXTRA_LOG')) {
50
+ define('WP_FAIL2BAN_COMMENT_EXTRA_LOG', DEFAULT_WP_FAIL2BAN_COMMENT_EXTRA_LOG);
51
+ }
52
+ if (!defined('WP_FAIL2BAN_PINGBACK_ERROR_LOG')) {
53
+ define('WP_FAIL2BAN_PINGBACK_ERROR_LOG', DEFAULT_WP_FAIL2BAN_PINGBACK_ERROR_LOG);
54
+ }
55
+ /**
56
+ * @since 4.2.0
57
+ */
58
+ if (!defined('WP_FAIL2BAN_PLUGIN_AUTH_LOG')) {
59
+ define('WP_FAIL2BAN_PLUGIN_AUTH_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_AUTH_LOG);
60
+ }
61
+ if (!defined('WP_FAIL2BAN_PLUGIN_COMMENT_LOG')) {
62
+ define('WP_FAIL2BAN_PLUGIN_COMMENT_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_COMMENT_LOG);
63
+ }
64
+ if (!defined('WP_FAIL2BAN_PLUGIN_OTHER_LOG')) {
65
+ define('WP_FAIL2BAN_PLUGIN_OTHER_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_OTHER_LOG);
66
+ }
67
+ if (!defined('WP_FAIL2BAN_PLUGIN_PASSWORD_LOG')) {
68
+ define('WP_FAIL2BAN_PLUGIN_PASSWORD_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_PASSWORD_LOG);
69
+ }
70
+ if (!defined('WP_FAIL2BAN_PLUGIN_REST_LOG')) {
71
+ define('WP_FAIL2BAN_PLUGIN_REST_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_REST_LOG);
72
+ }
73
+ if (!defined('WP_FAIL2BAN_PLUGIN_SPAM_LOG')) {
74
+ define('WP_FAIL2BAN_PLUGIN_SPAM_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_SPAM_LOG);
75
+ }
76
+ if (!defined('WP_FAIL2BAN_PLUGIN_XMLRPC_LOG')) {
77
+ define('WP_FAIL2BAN_PLUGIN_XMLRPC_LOG', DEFAULT_WP_FAIL2BAN_PLUGIN_XMLRPC_LOG);
78
+ }
79
 
lib/loader.php CHANGED
@@ -1,454 +1,327 @@
1
  <?php
 
2
  /**
3
  * Loader
4
  *
5
  * @package wp-fail2ban
6
- * @since 4.2.0
7
- * @php 5.6
8
  */
9
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
-
11
- if (defined('PHPUNIT_COMPOSER_INSTALL')) {
12
- return;
13
-
14
- } elseif (defined('ABSPATH')) {
15
- /**
16
- * Config
17
- *
18
- * @since 4.2.0
19
- */
20
- class Config
21
- {
22
- /**
23
- * @var array Settings
24
- * @since 4.3.0
25
- */
26
- protected static $settings = null;
27
- /**
28
- * @var Config Instance.
29
- * @since 4.3.0
30
- */
31
- protected static $instance = null;
32
-
33
- /**
34
- * Construct
35
- *
36
- * @since 4.3.0
37
- */
38
- public static function load(array $config = [])
39
- {
40
- if (is_null(self::$instance)) {
41
- global $wp_fail2ban;
42
-
43
- $class = get_called_class();
44
- self::$instance = new $class();
45
-
46
- $wp_fail2ban['config'] = apply_filters(
47
- __METHOD__.'.config',
48
- array_merge(
49
- $config,
50
- array(
51
- 'WP_FAIL2BAN_AUTH_LOG' => array(
52
- 'validate' => 'intval',
53
- 'unset' => true,
54
- 'field' => array(
55
- 'logging',
56
- 'authentication',
57
- 'facility')),
58
- 'WP_FAIL2BAN_LOG_COMMENTS' => array(
59
- 'validate' => 'boolval',
60
- 'unset' => true,
61
- 'field' => array(
62
- 'logging',
63
- 'comments',
64
- 'enabled')),
65
- 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA' => array(
66
- 'validate' => 'intval',
67
- 'unset' => true,
68
- 'field' => array(
69
- 'logging',
70
- 'comments',
71
- 'extra')),
72
- 'WP_FAIL2BAN_COMMENT_LOG' => array(
73
- 'validate' => 'intval',
74
- 'unset' => false,
75
- 'field' => array(
76
- 'logging',
77
- 'comments',
78
- 'facility')),
79
- 'WP_FAIL2BAN_COMMENT_EXTRA_LOG' => array(
80
- 'validate' => 'intval',
81
- 'unset' => false,
82
- 'field' => array(
83
- 'logging',
84
- 'comments-extra',
85
- 'facility')),
86
- 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST' => array(
87
- 'validate' => 'boolval',
88
- 'unset' => true,
89
- 'field' => array(
90
- 'logging',
91
- 'password-request',
92
- 'enabled')),
93
- 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG' => array(
94
- 'validate' => 'intval',
95
- 'unset' => false,
96
- 'field' => array(
97
- 'logging',
98
- 'password-request',
99
- 'facility')),
100
- 'WP_FAIL2BAN_LOG_PINGBACKS' => array(
101
- 'validate' => 'boolval',
102
- 'unset' => true,
103
- 'field' => array(
104
- 'logging',
105
- 'pingback',
106
- 'enabled')),
107
- 'WP_FAIL2BAN_PINGBACK_LOG' => array(
108
- 'validate' => 'intval',
109
- 'unset' => false,
110
- 'field' => array(
111
- 'logging',
112
- 'pingback',
113
- 'facility')),
114
- 'WP_FAIL2BAN_LOG_SPAM' => array(
115
- 'validate' => 'boolval',
116
- 'unset' => true,
117
- 'field' => array(
118
- 'logging',
119
- 'spam',
120
- 'enabled')),
121
- 'WP_FAIL2BAN_SPAM_LOG' => array(
122
- 'validate' => 'intval',
123
- 'unset' => false,
124
- 'field' => array(
125
- 'logging',
126
- 'spam',
127
- 'facility')),
128
-
129
- /**
130
- * syslog
131
- */
132
- 'WP_FAIL2BAN_OPENLOG_OPTIONS' => array(
133
- 'validate' => 'intval',
134
- 'unset' => true,
135
- 'field' => array(
136
- 'syslog',
137
- 'connection')),
138
- 'WP_FAIL2BAN_SYSLOG_SHORT_TAG' => array(
139
- 'validate' => 'boolval',
140
- 'unset' => true,
141
- 'field' => array(
142
- 'syslog',
143
- 'workaround',
144
- 'short_tag')),
145
- 'WP_FAIL2BAN_HTTP_HOST' => array(
146
- 'validate' => 'boolval',
147
- 'unset' => true,
148
- 'field' => array(
149
- 'syslog',
150
- 'workaround',
151
- 'http_host')),
152
- 'WP_FAIL2BAN_TRUNCATE_HOST' => array(
153
- 'validate' => 'boolval',
154
- 'unset' => true,
155
- 'field' => array(
156
- 'syslog',
157
- 'workaround',
158
- 'truncate_host')),
159
-
160
- /**
161
- * Block
162
- */
163
- 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION' => array(
164
- 'validate' => 'boolval',
165
- 'unset' => true,
166
- 'field' => array(
167
- 'block',
168
- 'user_enumeration')),
169
- 'WP_FAIL2BAN_BLOCKED_USERS' => array(
170
- 'validate' => 'strval',
171
- 'unset' => true,
172
- 'field' => array(
173
- 'block',
174
- 'users')),
175
- 'WP_FAIL2BAN_BLOCK_USERNAME_LOGIN' => array(
176
- 'validate' => 'boolval',
177
- 'unset' => true,
178
- 'field' => array(
179
- 'block',
180
- 'usernames')),
181
-
182
- /**
183
- * Plugins
184
- */
185
- 'WP_FAIL2BAN_PLUGIN_LOG_AUTH' => array(
186
- 'validate' => 'boolval',
187
- 'unset' => true,
188
- 'field' => array(
189
- 'logging',
190
- 'plugins',
191
- 'auth',
192
- 'enabled')),
193
- 'WP_FAIL2BAN_PLUGIN_LOG_COMMENT' => array(
194
- 'validate' => 'boolval',
195
- 'unset' => true,
196
- 'field' => array(
197
- 'logging',
198
- 'plugins',
199
- 'comment',
200
- 'enabled')),
201
- 'WP_FAIL2BAN_PLUGIN_LOG_PASSWORD' => array(
202
- 'validate' => 'boolval',
203
- 'unset' => true,
204
- 'field' => array(
205
- 'logging',
206
- 'plugins',
207
- 'password',
208
- 'enabled')),
209
- 'WP_FAIL2BAN_PLUGIN_LOG_REST' => array(
210
- 'validate' => 'boolval',
211
- 'unset' => true,
212
- 'field' => array(
213
- 'logging',
214
- 'plugins',
215
- 'rest',
216
- 'enabled')),
217
- 'WP_FAIL2BAN_PLUGIN_LOG_SPAM' => array(
218
- 'validate' => 'boolval',
219
- 'unset' => true,
220
- 'field' => array(
221
- 'logging',
222
- 'plugins',
223
- 'spam',
224
- 'enabled')),
225
- 'WP_FAIL2BAN_PLUGIN_LOG_XMLRPC' => array(
226
- 'validate' => 'boolval',
227
- 'unset' => true,
228
- 'field' => array(
229
- 'logging',
230
- 'plugins',
231
- 'xmlrpc',
232
- 'enabled')),
233
- 'WP_FAIL2BAN_PLUGIN_AUTH_LOG' => array(
234
- 'validate' => 'intval',
235
- 'unset' => false,
236
- 'field' => array(
237
- 'logging',
238
- 'plugins',
239
- 'auth',
240
- 'facility')),
241
- 'WP_FAIL2BAN_PLUGIN_COMMENT_LOG' => array(
242
- 'validate' => 'intval',
243
- 'unset' => false,
244
- 'field' => array(
245
- 'logging',
246
- 'plugins',
247
- 'comment',
248
- 'facility')),
249
- 'WP_FAIL2BAN_PLUGIN_PASSWORD_LOG' => array(
250
- 'validate' => 'intval',
251
- 'unset' => false,
252
- 'field' => array(
253
- 'logging',
254
- 'plugins',
255
- 'password',
256
- 'facility')),
257
- 'WP_FAIL2BAN_PLUGIN_REST_LOG' => array(
258
- 'validate' => 'intval',
259
- 'unset' => false,
260
- 'field' => array(
261
- 'logging',
262
- 'plugins',
263
- 'rest',
264
- 'facility')),
265
- 'WP_FAIL2BAN_PLUGIN_SPAM_LOG' => array(
266
- 'validate' => 'intval',
267
- 'unset' => false,
268
- 'field' => array(
269
- 'logging',
270
- 'plugins',
271
- 'spam',
272
- 'facility')),
273
- 'WP_FAIL2BAN_PLUGIN_XMLRPC_LOG' => array(
274
- 'validate' => 'intval',
275
- 'unset' => false,
276
- 'field' => array(
277
- 'logging',
278
- 'plugins',
279
- 'xmlrpc',
280
- 'facility')),
281
-
282
- 'WP_FAIL2BAN_PROXIES' => array(
283
- 'validate' => __CLASS__.'::validate_ips',
284
- 'unset' => true,
285
- 'field' => array(
286
- 'remote-ip',
287
- 'proxies')),
288
- )
289
- )
290
- );
291
-
292
- static::init();
293
- }
294
- }
295
-
296
- protected static function init()
297
- {
298
- global $wp_fail2ban;
299
-
300
- self::$settings = array();
301
-
302
- foreach ($wp_fail2ban['config'] as $define => $args) {
303
- if ($wp_fail2ban['config'][$define]['ndef'] = !defined($define)) {
304
- if (defined("DEFAULT_{$define}")) {
305
- define($define, $args['validate'](constant("DEFAULT_{$define}")));
306
- } else {
307
- // bah
308
- define($define, call_user_func($args['validate'], false));
309
- }
310
- }
311
- }
312
- }
313
-
314
- /**
315
- * Validate IP list.
316
- *
317
- * @since 4.3.0 Refactored
318
- * @since 4.0.0
319
- *
320
- * @param array|string $value
321
- * @return string
322
- */
323
- public static function validate_ips($value)
324
- {
325
- return self::$instance->doValidateIPs($value);
326
- }
327
-
328
- public function doValidateIPs($value)
329
- {
330
- return (false === $value) ? '' : $value;
331
- }
332
-
333
- /**
334
- * Helper: filtered get_site_option('wp-fail2ban')
335
- *
336
- * @since 4.3.0
337
- *
338
- * @param bool $filter
339
- * @return array
340
- */
341
- public static function settings($filter = true)
342
- {
343
- return self::$instance->getSettings($filter);
344
- }
345
-
346
- public function getSettings($filter = true)
347
- {
348
- return self::$settings;
349
- }
350
-
351
- // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
352
- /**
353
- * Helper: default value
354
- *
355
- * @since 4.3.0
356
- *
357
- * @param string $define
358
- * @return mixed
359
- */
360
- public static function get_default($define)
361
- {
362
- $const = "DEFAULT_{$define}";
363
-
364
- return (defined($const))
365
- ? constant($const)
366
- : null;
367
- }
368
- // phpcs:enable
369
-
370
- /**
371
- * Help:er: is defined?
372
- *
373
- * @since 4.3.0
374
- *
375
- * @param string $define Constant name
376
- * @return bool Is defined?
377
- */
378
- public static function def($define)
379
- {
380
- return !self::ndef($define);
381
- }
382
-
383
  /**
384
- * Helper: is not defined?
385
  *
386
- * @since 4.3.0
387
  *
388
- * @param string $define Constant name
389
- * @return bool Is not defined?
390
- */
391
- public static function ndef($define)
392
- {
393
- return self::$instance->getNdef($define);
394
- }
395
-
396
- public function getNdef($define)
397
- {
398
- global $wp_fail2ban;
399
-
400
- return @$wp_fail2ban['config'][$define]['ndef'];
401
- }
402
-
403
- /**
404
- * Helper: get value
405
  *
406
- * @since 4.3.0
407
- *
408
- * @param string $define Constant name
409
- * @param array $settings Premium: settings to use
410
- * @return mixed Constant value
411
  */
412
- public static function get($define, array $settings = null)
413
  {
414
- return self::$instance->getter($define, $settings);
415
  }
416
-
417
- public function getter($define, array $settings = null)
418
- {
419
- return (defined($define)) ? constant($define) : null;
420
- }
421
-
422
- /**
423
- * Helper: get description
424
- *
425
- * @since 4.3.0
426
- *
427
- * @param string $define Constant name.
428
- * @return string|null Description.
429
- */
430
- public static function desc($define)
431
- {
432
- return self::$instance->getDesc($define);
433
- }
434
-
435
- public function getDesc($define)
436
- {
437
- switch ($define) {
438
- case 'WP_FAIL2BAN_AUTH_LOG':
439
- return __('Logins and attempted logins.', 'wp-fail2ban');
440
- case 'WP_FAIL2BAN_LOG_SPAM':
441
- return __('Log comments marked as spam.', 'wp-fail2ban');
442
- case 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION':
443
- return __('Stop attackers listing existing usernames.', 'wp-fail2ban');
444
- case 'WP_FAIL2BAN_BLOCK_USERNAME_LOGIN':
445
- return __('Allow <b>email addresses only</b> for login.', 'wp-fail2ban');
446
- case 'WP_FAIL2BAN_PROXIES':
447
- return __('Trusted IPv4 list.', 'wp-fail2ban');
448
- default:
449
- return null;
 
 
450
  }
 
451
  }
452
  }
453
- }
454
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
  * Loader
5
  *
6
  * @package wp-fail2ban
7
+ * @since 4.2.0
 
8
  */
9
+ namespace {
10
+ if ( !defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }
13
+ if ( defined( 'PHPUNIT_COMPOSER_INSTALL' ) ) {
14
+ return;
15
+ }
16
+ if ( !function_exists( 'boolval' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  /**
18
+ * PHP 5.3 helper
19
  *
20
+ * @since 4.2.5
21
  *
22
+ * @param mixed $val
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  *
24
+ * @return bool
 
 
 
 
25
  */
26
+ function boolval( $val )
27
  {
28
+ return (bool) $val;
29
  }
30
+
31
+ }
32
+ }
33
+ namespace org\lecklider\charles\wordpress\wp_fail2ban {
34
+ /**
35
+ * Helper
36
+ *
37
+ * @since 4.0.0
38
+ *
39
+ * @param string $define
40
+ * @param callable $cast
41
+ * @param bool $unset
42
+ * @param array $field
43
+ */
44
+ function _load(
45
+ $define,
46
+ $cast,
47
+ $unset,
48
+ array $field
49
+ )
50
+ {
51
+ global $wp_fail2ban ;
52
+ $wp_fail2ban['config'][$define] = array(
53
+ 'validate' => $cast,
54
+ 'unset' => $unset,
55
+ 'field' => $field,
56
+ 'ndef' => !defined( $define ),
57
+ );
58
+ if ( !defined( $define ) ) {
59
+
60
+ if ( defined( "DEFAULT_{$define}" ) ) {
61
+ // we've got a default
62
+ define( $define, $cast( constant( "DEFAULT_{$define}" ) ) );
63
+ } else {
64
+ // bah
65
+ define( $define, $cast( false ) );
66
  }
67
+
68
  }
69
  }
70
+
71
+ /**
72
+ * Validate IP list
73
+ *
74
+ * @since 4.0.0
75
+ *
76
+ * @param array|string $value
77
+ *
78
+ * @return string
79
+ */
80
+ function validate_ips( $value )
81
+ {
82
+ return $value;
83
+ }
84
+
85
+ // phpcs:disable Generic.Functions.FunctionCallArgumentSpacing
86
+ _load(
87
+ 'WP_FAIL2BAN_AUTH_LOG',
88
+ 'intval',
89
+ true,
90
+ array( 'logging', 'authentication', 'facility' )
91
+ );
92
+ _load(
93
+ 'WP_FAIL2BAN_LOG_COMMENTS',
94
+ 'boolval',
95
+ true,
96
+ array( 'logging', 'comments', 'enabled' )
97
+ );
98
+ _load(
99
+ 'WP_FAIL2BAN_LOG_COMMENTS_EXTRA',
100
+ 'intval',
101
+ true,
102
+ array( 'logging', 'comments', 'extra' )
103
+ );
104
+ _load(
105
+ 'WP_FAIL2BAN_COMMENT_LOG',
106
+ 'intval',
107
+ false,
108
+ array( 'logging', 'comments', 'facility' )
109
+ );
110
+ _load(
111
+ 'WP_FAIL2BAN_COMMENT_EXTRA_LOG',
112
+ 'intval',
113
+ false,
114
+ array( 'logging', 'comments-extra', 'facility' )
115
+ );
116
+ _load(
117
+ 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST',
118
+ 'boolval',
119
+ true,
120
+ array( 'logging', 'password-request', 'enabled' )
121
+ );
122
+ _load(
123
+ 'WP_FAIL2BAN_PASSWORD_REQUEST_LOG',
124
+ 'intval',
125
+ false,
126
+ array( 'logging', 'password-request', 'facility' )
127
+ );
128
+ _load(
129
+ 'WP_FAIL2BAN_LOG_PINGBACKS',
130
+ 'boolval',
131
+ true,
132
+ array( 'logging', 'pingback', 'enabled' )
133
+ );
134
+ _load(
135
+ 'WP_FAIL2BAN_PINGBACK_LOG',
136
+ 'intval',
137
+ false,
138
+ array( 'logging', 'pingback', 'facility' )
139
+ );
140
+ _load(
141
+ 'WP_FAIL2BAN_LOG_SPAM',
142
+ 'boolval',
143
+ true,
144
+ array( 'logging', 'spam', 'enabled' )
145
+ );
146
+ _load(
147
+ 'WP_FAIL2BAN_SPAM_LOG',
148
+ 'intval',
149
+ false,
150
+ array( 'logging', 'spam', 'facility' )
151
+ );
152
+ _load(
153
+ 'WP_FAIL2BAN_OPENLOG_OPTIONS',
154
+ 'intval',
155
+ true,
156
+ array( 'syslog', 'connection' )
157
+ );
158
+ _load(
159
+ 'WP_FAIL2BAN_SYSLOG_SHORT_TAG',
160
+ 'boolval',
161
+ true,
162
+ array( 'syslog', 'workaround', 'short_tag' )
163
+ );
164
+ _load(
165
+ 'WP_FAIL2BAN_HTTP_HOST',
166
+ 'boolval',
167
+ true,
168
+ array( 'syslog', 'workaround', 'http_host' )
169
+ );
170
+ _load(
171
+ 'WP_FAIL2BAN_TRUNCATE_HOST',
172
+ 'boolval',
173
+ true,
174
+ array( 'syslog', 'workaround', 'truncate_host' )
175
+ );
176
+ _load(
177
+ 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION',
178
+ 'boolval',
179
+ true,
180
+ array( 'block', 'user_enumeration' )
181
+ );
182
+ _load(
183
+ 'WP_FAIL2BAN_BLOCKED_USERS',
184
+ 'strval',
185
+ true,
186
+ array( 'block', 'users' )
187
+ );
188
+ _load(
189
+ 'WP_FAIL2BAN_PROXIES',
190
+ __NAMESPACE__ . '\\validate_ips',
191
+ true,
192
+ array( 'remote-ip', 'proxies' )
193
+ );
194
+ _load(
195
+ 'WP_FAIL2BAN_PLUGIN_LOG_AUTH',
196
+ 'boolval',
197
+ true,
198
+ array(
199
+ 'logging',
200
+ 'plugins',
201
+ 'auth',
202
+ 'enabled'
203
+ )
204
+ );
205
+ _load(
206
+ 'WP_FAIL2BAN_PLUGIN_LOG_COMMENT',
207
+ 'boolval',
208
+ true,
209
+ array(
210
+ 'logging',
211
+ 'plugins',
212
+ 'comment',
213
+ 'enabled'
214
+ )
215
+ );
216
+ _load(
217
+ 'WP_FAIL2BAN_PLUGIN_LOG_PASSWORD',
218
+ 'boolval',
219
+ true,
220
+ array(
221
+ 'logging',
222
+ 'plugins',
223
+ 'password',
224
+ 'enabled'
225
+ )
226
+ );
227
+ _load(
228
+ 'WP_FAIL2BAN_PLUGIN_LOG_REST',
229
+ 'boolval',
230
+ true,
231
+ array(
232
+ 'logging',
233
+ 'plugins',
234
+ 'rest',
235
+ 'enabled'
236
+ )
237
+ );
238
+ _load(
239
+ 'WP_FAIL2BAN_PLUGIN_LOG_SPAM',
240
+ 'boolval',
241
+ true,
242
+ array(
243
+ 'logging',
244
+ 'plugins',
245
+ 'spam',
246
+ 'enabled'
247
+ )
248
+ );
249
+ _load(
250
+ 'WP_FAIL2BAN_PLUGIN_LOG_XMLRPC',
251
+ 'boolval',
252
+ true,
253
+ array(
254
+ 'logging',
255
+ 'plugins',
256
+ 'xmlrpc',
257
+ 'enabled'
258
+ )
259
+ );
260
+ _load(
261
+ 'WP_FAIL2BAN_PLUGIN_AUTH_LOG',
262
+ 'intval',
263
+ false,
264
+ array(
265
+ 'logging',
266
+ 'plugins',
267
+ 'auth',
268
+ 'facility'
269
+ )
270
+ );
271
+ _load(
272
+ 'WP_FAIL2BAN_PLUGIN_COMMENT_LOG',
273
+ 'intval',
274
+ false,
275
+ array(
276
+ 'logging',
277
+ 'plugins',
278
+ 'comment',
279
+ 'facility'
280
+ )
281
+ );
282
+ _load(
283
+ 'WP_FAIL2BAN_PLUGIN_PASSWORD_LOG',
284
+ 'intval',
285
+ false,
286
+ array(
287
+ 'logging',
288
+ 'plugins',
289
+ 'password',
290
+ 'facility'
291
+ )
292
+ );
293
+ _load(
294
+ 'WP_FAIL2BAN_PLUGIN_REST_LOG',
295
+ 'intval',
296
+ false,
297
+ array(
298
+ 'logging',
299
+ 'plugins',
300
+ 'rest',
301
+ 'facility'
302
+ )
303
+ );
304
+ _load(
305
+ 'WP_FAIL2BAN_PLUGIN_SPAM_LOG',
306
+ 'intval',
307
+ false,
308
+ array(
309
+ 'logging',
310
+ 'plugins',
311
+ 'spam',
312
+ 'facility'
313
+ )
314
+ );
315
+ _load(
316
+ 'WP_FAIL2BAN_PLUGIN_XMLRPC_LOG',
317
+ 'intval',
318
+ false,
319
+ array(
320
+ 'logging',
321
+ 'plugins',
322
+ 'xmlrpc',
323
+ 'facility'
324
+ )
325
+ );
326
+ // phpcs:enable
327
+ }
readme.txt CHANGED
@@ -1,13 +1,13 @@
1
  === WP fail2ban ===
2
  Contributors: invisnet
3
  Donate link: https://paypal.me/invisnet/
4
- Author URI: https://charles.lecklider.org/
5
- Plugin URI: https://wp-fail2ban.com/
6
  Tags: fail2ban, login, security, syslog, brute force, protection, classicpress
7
  Requires at least: 4.2
8
  Tested up to: 5.4
9
- Stable tag: 4.3.0-RC3
10
- Requires PHP: 5.6
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
@@ -15,7 +15,7 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
15
 
16
  == Description ==
17
 
18
- [fail2ban](http://www.fail2ban.org/) is one of the simplest and most effective security measures you can implement to prevent brute-force attacks.
19
 
20
  *WP fail2ban* logs all login attempts - including via XML-RPC, whether successful or not, to syslog using LOG_AUTH. For example:
21
 
@@ -26,59 +26,56 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
26
 
27
  = Features =
28
 
29
- * **NEW - Multisite Support**
30
- Version 4.3 introduces [proper support for multisite networks](https://wp-fail2ban.com/features/multisite-networks/?utm_source=readme).
31
 
32
- * **NEW** - Block username logins**
33
- It is sometimes not possible to block user enumeration (for example, if your theme provides Author profiles). Version 4.3 adds support for requiring the use of email addresses for login.
34
 
35
- * **Remote Tools Add-on**
36
- The Remote Tools add-on provides extra features without adding bloat to the core plugin. For more details see the [add-on page](https://wp-fail2ban.com/add-ons/remote-tools/?utm_source=readme).
37
-
38
- * **Support for 3rd-party Plugins**
39
  Version 4.2 introduces a simple API for authors to integrate their plugins with *WPf2b*, with 2 *experimental* add-ons:
40
  * [Contact Form 7](https://wordpress.org/plugins/wp-fail2ban-addon-contact-form-7/)
41
  * [Gravity Forms](https://wordpress.org/plugins/wp-fail2ban-addon-gravity-forms/)
42
 
 
 
43
  * **CloudFlare and Proxy Servers**
44
- *WPf2b* can be configured to work with [CloudFlare and other proxy servers](https://wp-fail2ban.com/features/cloudflare-and-proxy-servers/?utm_source=readme).
45
 
46
  * **Comments**
47
- *WPf2b* can log comments (see [`WP_FAIL2BAN_LOG_COMMENTS`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-log-comments)) and attempted comments (see [`WP_FAIL2BAN_LOG_COMMENTS_EXTRA`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-log-comments-extra)).
48
 
49
  * **Pingbacks**
50
- *WPf2b* logs failed pingbacks, and can log all pingbacks. For an overview see [`WP_FAIL2BAN_LOG_PINGBACKS`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-log-pingbacks).
51
 
52
  * **Spam**
53
- *WPf2b* can log comments marked as spam. See [`WP_FAIL2BAN_LOG_SPAM`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-log-spam).
54
 
55
  * **Block User Enumeration**
56
- *WPf2b* can [block user enumeration](https://wp-fail2ban.com/features/block-user-enumeration/?utm_source=readme).
57
 
58
  * **Work-Arounds for Broken syslogd**
59
- *WPf2b* can be configured to work around most syslogd weirdness. For an overview see [`WP_FAIL2BAN_SYSLOG_SHORT_TAG`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-syslog-short-tag) and [`WP_FAIL2BAN_HTTP_HOST`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-http-host).
60
 
61
  * **Blocking Users**
62
- *WPf2b* can be configured to short-cut the login process when the username matches a regex. For an overview see [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-blocked-users).
63
 
64
  * **`mu-plugins` Support**
65
- *WPf2b* can easily be configured as a must-use plugin - see [Configuration](https://docs.wp-fail2ban.com/en/4.2/configuration.html#mu-plugins-support).
66
 
67
  == Installation ==
68
 
69
  1. Install via the Plugin Directory, or upload to your plugins directory.
70
  1. Activate the plugin through the 'Plugins' menu in WordPress.
71
- 1. Edit `wp-config.php` to suit your needs - see [Configuration](https://docs.wp-fail2ban.com/en/4.2/configuration.html).
72
 
73
  == Changelog ==
74
 
75
- = 4.3.0 "Columbo" =
76
- * Add full multisite support.
77
- * Add separate logging for login attemtps with empty username.
78
- * Improve user enumeration blocking compatibility with the WordPress block editor (Gutenberg).
79
- * Log extra information for events (premium).
80
- * Add new event class for blocked actions (premium).
81
- * Bump the minimum PHP version to 5.6.
82
 
83
  = 4.2.7.1 =
84
  * Fix error when blocking user enumeration via `oembed` (h/t @wordpressfab).
@@ -88,7 +85,7 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
88
  * Fix buttons on Settings tabs.
89
 
90
  = 4.2.6 =
91
- * Add support for [Remote Tools](https://wp-fail2ban.com/add-ons/remote-tools/) add-on.
92
  * Add support for the new ClassicPress security page.
93
  * Improved user enumeration blocking.
94
 
@@ -114,8 +111,8 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
114
  * Fix 5.3 compatibility.
115
 
116
  = 4.2.1 =
117
- * Completed support for [`WP_FAIL2BAN_COMMENT_EXTRA_LOG`](https://docs.wp-fail2ban.com/en/4.2/defines/WP_FAIL2BAN_COMMENT_EXTRA_LOG.html).
118
- * Add support for 3rd-party plugins; see [Developers](https://docs.wp-fail2ban.com/en/4.2/developers.html).
119
  * Add-on for [Contact Form 7](https://wordpress.org/plugins/wp-fail2ban-addon-contact-form-7/) (experimental).
120
  * Add-on for [Gravity Forms](https://wordpress.org/plugins/wp-fail2ban-addon-gravity-forms/) (experimental).
121
  * Change logging for known-user with incorrect password; previously logged as unknown user and matched by `hard` filters (due to limitations in older versions of WordPress), now logged as known user and matched by `soft`.
@@ -127,11 +124,11 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
127
 
128
  = 4.1.0 =
129
  * Add separate logging for REST authentication.
130
- * Fix conflict with earlier versions pre-installed in `mu-plugins`. See [Is *WPf2b* Already Installed?](https://docs.wp-fail2ban.com/en/4.1/installation.html#is-wp-fail2ban-already-installed).
131
 
132
  = 4.0.5 =
133
- * Add [`WP_FAIL2BAN_COMMENT_EXTRA_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_COMMENT_EXTRA_LOG.html).
134
- * Add [`WP_FAIL2BAN_PINGBACK_ERROR_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PINGBACK_ERROR_LOG.html) (future functionality).
135
  * Change `WP_FAIL2BAN_LOG_SPAM` to use `LOG_NOTICE`.
136
  * Change `WP_FAIL2BAN_SPAM_LOG` to `LOG_AUTH`.
137
  * Change `WP_FAIL2BAN_LOG_COMMENTS_EXTRA` events to use `LOG_NOTICE` by default.
@@ -145,9 +142,9 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
145
  = 4.0.1 =
146
  * Add extra features via Freemius. **This is entirely optional.** *WPf2b* works as before, including new features listed here.
147
  * Add settings summary page (Settings -> WP fail2ban).
148
- * Add [`WP_FAIL2BAN_PASSWORD_REQUEST_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PASSWORD_REQUEST_LOG.html).
149
- * Add [`WP_FAIL2BAN_SPAM_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_SPAM_LOG.html).
150
- * Add [`WP_FAIL2BAN_LOG_COMMENTS_EXTRA`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_COMMENTS_EXTRA.html) - enable logging for attempted comments on posts which are:
151
  * not found,
152
  * closed for commenting,
153
  * in the trash,
@@ -159,70 +156,70 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
159
  * Not released.
160
 
161
  = 3.6.0 =
162
- * The [filter files](https://docs.wp-fail2ban.com/en/4.1/filters.html) are now generated from PHPDoc in the code. There were too many times when the filters were out of sync with the code (programmer error) - this should resolve that by bringing the patterns closer to the code that emits them.
163
- * Added [PHPUnit tests](https://docs.wp-fail2ban.com/en/4.1/tests.html). Almost 100% code coverage, with the exception of [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html) which is quite hard to test properly.
164
- * Bugfix for [`wordpress-soft.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-soft-conf).
165
- * Add [`WP_FAIL2BAN_XMLRPC_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_XMLRPC_LOG.html).
166
- * Add [`WP_FAIL2BAN_REMOTE_ADDR`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_REMOTE_ADDR.html).
167
- * [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html) now supports an array of IPs with PHP 7.
168
- * Moved all documentation to [https://docs.wp-fail2ban.com/](https://docs.wp-fail2ban.com/).
169
 
170
  = 3.5.3 =
171
- * Bugfix for [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-hard-conf).
172
 
173
  = 3.5.1 =
174
- * Bugfix for [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html).
175
 
176
  = 3.5.0 =
177
- * Add [`WP_FAIL2BAN_OPENLOG_OPTIONS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_OPENLOG_OPTIONS.html).
178
- * Add [`WP_FAIL2BAN_LOG_COMMENTS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_COMMENTS.html) and [`WP_FAIL2BAN_COMMENT_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_COMMENT_LOG.html).
179
- * Add [`WP_FAIL2BAN_LOG_PASSWORD_REQUEST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_PASSWORD_REQUEST.html).
180
- * Add [`WP_FAIL2BAN_LOG_SPAM`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_SPAM.html).
181
- * Add [`WP_FAIL2BAN_TRUNCATE_HOST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_TRUNCATE_HOST.html).
182
- * [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html) now supports an array of users with PHP 7.
183
 
184
  = 3.0.3 =
185
- * Fix regex in [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-hard-conf).
186
 
187
  = 3.0.2 =
188
  * Prevent double logging in WP 4.5.x for XML-RPC authentication failure
189
 
190
  = 3.0.1 =
191
- * Fix regex in [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-hard-conf).
192
 
193
  = 3.0.0 =
194
- * Add [`WP_FAIL2BAN_SYSLOG_SHORT_TAG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_SYSLOG_SHORT_TAG.html).
195
- * Add [`WP_FAIL2BAN_HTTP_HOST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_HTTP_HOST.html).
196
  * Log XML-RPC authentication failure.
197
  * Add better support for MU deployment.
198
 
199
  = 2.3.2 =
200
- * Bugfix [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html).
201
 
202
  = 2.3.0 =
203
- * Bugfix in *experimental* [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html) code (thanks to KyleCartmell).
204
 
205
  = 2.2.1 =
206
- * Fix stupid mistake with [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html).
207
 
208
  = 2.2.0 =
209
- * Custom authentication log is now called [`WP_FAIL2BAN_AUTH_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_AUTH_LOG.html).
210
- * Add logging for pingbacks; see [`WP_FAIL2BAN_LOG_PINGBACKS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_PINGBACKS.html).
211
- * Custom pingback log is called [`WP_FAIL2BAN_PINGBACK_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PINGBACK_LOG.html).
212
 
213
  = 2.1.1 =
214
  * Minor bugfix.
215
 
216
  = 2.1.0 =
217
- * Add support for blocking user enumeration; see [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html).
218
- * Add support for CIDR notation in [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html).
219
 
220
  = 2.0.1 =
221
- * Bugfix in *experimental* [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html) code.
222
 
223
  = 2.0.0 =
224
- * Add *experimental* support for X-Forwarded-For header; see [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html).
225
- * Add *experimental* support for regex-based login blocking; see [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html).
226
 
227
  = 1.2.1 =
228
  * Update FAQ.
@@ -238,8 +235,8 @@ Write a myriad of WordPress events to syslog for integration with fail2ban.
238
 
239
  == Upgrade Notice ==
240
 
241
- = 4.3.0 =
242
- To take advantage of the new features you will need up update your `fail2ban` filters; existing filters will continue to work as before.
243
 
244
  = 4.2.7.1 =
245
  This is a bugfix release. You do not need to update your filters from 4.1.0.
@@ -293,7 +290,7 @@ You will need up update your `fail2ban` filters.
293
  You will need up update your `fail2ban` filters.
294
 
295
  = 3.5.1 =
296
- Bugfix: disable [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html) in admin area....
297
 
298
  = 3.5.0 =
299
  You will need up update your `fail2ban` filters.
@@ -305,13 +302,13 @@ You will need up update your `fail2ban` filters.
305
  BREAKING CHANGE: The `fail2ban` filters have been split into two files. You will need up update your `fail2ban` configuration.
306
 
307
  = 2.3.0 =
308
- Fix for [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html); if you're not using it you can safely skip this release.
309
 
310
  = 2.2.1 =
311
  Bugfix.
312
 
313
  = 2.2.0 =
314
- BREAKING CHANGE: `WP_FAIL2BAN_LOG` has been renamed to [`WP_FAIL2BAN_AUTH_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_AUTH_LOG.html).
315
 
316
  Pingbacks are getting a lot of attention recently, so *WPf2b* can now log them.
317
  The `wordpress.conf` filter has been updated; you will need to update your `fail2ban` configuration.
@@ -324,4 +321,3 @@ Bugfix in experimental code; still an experimental release.
324
 
325
  = 2.0.0 =
326
  This is an experimental release. If your current version is working and you're not interested in the new features, skip this version - wait for 2.1.0. For those that do want to test this release, note that `wordpress.conf` has changed - you'll need to copy it to `fail2ban/filters.d` again.
327
-
1
  === WP fail2ban ===
2
  Contributors: invisnet
3
  Donate link: https://paypal.me/invisnet/
4
+ Author URI: https://charles.lecklider.org/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8
5
+ Plugin URI: https://wp-fail2ban.com/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8
6
  Tags: fail2ban, login, security, syslog, brute force, protection, classicpress
7
  Requires at least: 4.2
8
  Tested up to: 5.4
9
+ Stable tag: 4.2.8
10
+ Requires PHP: 5.3
11
  License: GPLv2 or later
12
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
13
 
15
 
16
  == Description ==
17
 
18
+ [fail2ban](http://www.fail2ban.org/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) is one of the simplest and most effective security measures you can implement to prevent brute-force attacks.
19
 
20
  *WP fail2ban* logs all login attempts - including via XML-RPC, whether successful or not, to syslog using LOG_AUTH. For example:
21
 
26
 
27
  = Features =
28
 
29
+ * **NEW - Remote Tools Add-on**
30
+ The Remote Tools add-on provides extra features without adding bloat to the core plugin. For more details see the [add-on page](https://wp-fail2ban.com/add-ons/remote-tools/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
31
 
32
+ **NB:** Requires PHP >= 5.6
 
33
 
34
+ * **NEW - Support for 3rd-party Plugins**
 
 
 
35
  Version 4.2 introduces a simple API for authors to integrate their plugins with *WPf2b*, with 2 *experimental* add-ons:
36
  * [Contact Form 7](https://wordpress.org/plugins/wp-fail2ban-addon-contact-form-7/)
37
  * [Gravity Forms](https://wordpress.org/plugins/wp-fail2ban-addon-gravity-forms/)
38
 
39
+ **NB:** Requires PHP >= 5.6
40
+
41
  * **CloudFlare and Proxy Servers**
42
+ *WPf2b* can be configured to work with CloudFlare and other proxy servers. For an overview see [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-proxies).
43
 
44
  * **Comments**
45
+ *WPf2b* can log comments (see [`WP_FAIL2BAN_LOG_COMMENTS`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-log-comments)) and attempted comments (see [`WP_FAIL2BAN_LOG_COMMENTS_EXTRA`](https://docs.wp-fail2ban.com/en/4.2/defines.html#wp-fail2ban-log-comments-extra)).
46
 
47
  * **Pingbacks**
48
+ *WPf2b* logs failed pingbacks, and can log all pingbacks. For an overview see [`WP_FAIL2BAN_LOG_PINGBACKS`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-log-pingbacks).
49
 
50
  * **Spam**
51
+ *WPf2b* can log comments marked as spam. See [`WP_FAIL2BAN_LOG_SPAM`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-log-spam).
52
 
53
  * **Block User Enumeration**
54
+ *WPf2b* can block user enumeration. See [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-block-user-enumeration).
55
 
56
  * **Work-Arounds for Broken syslogd**
57
+ *WPf2b* can be configured to work around most syslogd weirdness. For an overview see [`WP_FAIL2BAN_SYSLOG_SHORT_TAG`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-syslog-short-tag) and [`WP_FAIL2BAN_HTTP_HOST`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-http-host).
58
 
59
  * **Blocking Users**
60
+ *WPf2b* can be configured to short-cut the login process when the username matches a regex. For an overview see [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.2/defines.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wp-fail2ban-blocked-users).
61
 
62
  * **`mu-plugins` Support**
63
+ *WPf2b* can easily be configured as a must-use plugin - see [Configuration](https://docs.wp-fail2ban.com/en/4.2/configuration.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#mu-plugins-support).
64
 
65
  == Installation ==
66
 
67
  1. Install via the Plugin Directory, or upload to your plugins directory.
68
  1. Activate the plugin through the 'Plugins' menu in WordPress.
69
+ 1. Edit `wp-config.php` to suit your needs - see [Configuration](https://docs.wp-fail2ban.com/en/4.2/configuration.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
70
 
71
  == Changelog ==
72
 
73
+ = 4.2.8 =
74
+ * Add link to new [support forum](https://forums.invis.net/c/wp-fail2ban/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
75
+ * Fix user enumeration conflict with Gutenberg (h/t @dinghy).
76
+ * Fix notices wrt admin menu (h/t @marioivangf).
77
+ * Fix harmless XDebug notice (h/t @dinghy).
78
+ * Update Freemius library.
 
79
 
80
  = 4.2.7.1 =
81
  * Fix error when blocking user enumeration via `oembed` (h/t @wordpressfab).
85
  * Fix buttons on Settings tabs.
86
 
87
  = 4.2.6 =
88
+ * Add support for [Remote Tools](https://wp-fail2ban.com/add-ons/remote-tools/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) add-on.
89
  * Add support for the new ClassicPress security page.
90
  * Improved user enumeration blocking.
91
 
111
  * Fix 5.3 compatibility.
112
 
113
  = 4.2.1 =
114
+ * Completed support for [`WP_FAIL2BAN_COMMENT_EXTRA_LOG`](https://docs.wp-fail2ban.com/en/4.2/defines/WP_FAIL2BAN_COMMENT_EXTRA_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
115
+ * Add support for 3rd-party plugins; see [Developers](https://docs.wp-fail2ban.com/en/4.2/developers.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
116
  * Add-on for [Contact Form 7](https://wordpress.org/plugins/wp-fail2ban-addon-contact-form-7/) (experimental).
117
  * Add-on for [Gravity Forms](https://wordpress.org/plugins/wp-fail2ban-addon-gravity-forms/) (experimental).
118
  * Change logging for known-user with incorrect password; previously logged as unknown user and matched by `hard` filters (due to limitations in older versions of WordPress), now logged as known user and matched by `soft`.
124
 
125
  = 4.1.0 =
126
  * Add separate logging for REST authentication.
127
+ * Fix conflict with earlier versions pre-installed in `mu-plugins`. See [Is *WPf2b* Already Installed?](https://docs.wp-fail2ban.com/en/4.1/installation.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#is-wp-fail2ban-already-installed).
128
 
129
  = 4.0.5 =
130
+ * Add [`WP_FAIL2BAN_COMMENT_EXTRA_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_COMMENT_EXTRA_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
131
+ * Add [`WP_FAIL2BAN_PINGBACK_ERROR_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PINGBACK_ERROR_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) (future functionality).
132
  * Change `WP_FAIL2BAN_LOG_SPAM` to use `LOG_NOTICE`.
133
  * Change `WP_FAIL2BAN_SPAM_LOG` to `LOG_AUTH`.
134
  * Change `WP_FAIL2BAN_LOG_COMMENTS_EXTRA` events to use `LOG_NOTICE` by default.
142
  = 4.0.1 =
143
  * Add extra features via Freemius. **This is entirely optional.** *WPf2b* works as before, including new features listed here.
144
  * Add settings summary page (Settings -> WP fail2ban).
145
+ * Add [`WP_FAIL2BAN_PASSWORD_REQUEST_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PASSWORD_REQUEST_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
146
+ * Add [`WP_FAIL2BAN_SPAM_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_SPAM_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
147
+ * Add [`WP_FAIL2BAN_LOG_COMMENTS_EXTRA`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_COMMENTS_EXTRA.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) - enable logging for attempted comments on posts which are:
148
  * not found,
149
  * closed for commenting,
150
  * in the trash,
156
  * Not released.
157
 
158
  = 3.6.0 =
159
+ * The [filter files](https://docs.wp-fail2ban.com/en/4.1/filters.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) are now generated from PHPDoc in the code. There were too many times when the filters were out of sync with the code (programmer error) - this should resolve that by bringing the patterns closer to the code that emits them.
160
+ * Added [PHPUnit tests](https://docs.wp-fail2ban.com/en/4.1/tests.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8). Almost 100% code coverage, with the exception of [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html) which is quite hard to test properly.
161
+ * Bugfix for [`wordpress-soft.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wordpress-soft-conf).
162
+ * Add [`WP_FAIL2BAN_XMLRPC_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_XMLRPC_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
163
+ * Add [`WP_FAIL2BAN_REMOTE_ADDR`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_REMOTE_ADDR.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
164
+ * [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) now supports an array of IPs with PHP 7.
165
+ * Moved all documentation to [https://docs.wp-fail2ban.com/](https://docs.wp-fail2ban.com/?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
166
 
167
  = 3.5.3 =
168
+ * Bugfix for [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8#wordpress-hard-conf).
169
 
170
  = 3.5.1 =
171
+ * Bugfix for [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
172
 
173
  = 3.5.0 =
174
+ * Add [`WP_FAIL2BAN_OPENLOG_OPTIONS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_OPENLOG_OPTIONS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
175
+ * Add [`WP_FAIL2BAN_LOG_COMMENTS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_COMMENTS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) and [`WP_FAIL2BAN_COMMENT_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_COMMENT_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
176
+ * Add [`WP_FAIL2BAN_LOG_PASSWORD_REQUEST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_PASSWORD_REQUEST.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
177
+ * Add [`WP_FAIL2BAN_LOG_SPAM`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_SPAM.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
178
+ * Add [`WP_FAIL2BAN_TRUNCATE_HOST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_TRUNCATE_HOST.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
179
+ * [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) now supports an array of users with PHP 7.
180
 
181
  = 3.0.3 =
182
+ * Fix regex in [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-hard-conf?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
183
 
184
  = 3.0.2 =
185
  * Prevent double logging in WP 4.5.x for XML-RPC authentication failure
186
 
187
  = 3.0.1 =
188
+ * Fix regex in [`wordpress-hard.conf`](https://docs.wp-fail2ban.com/en/4.1/filters.html#wordpress-hard-conf?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
189
 
190
  = 3.0.0 =
191
+ * Add [`WP_FAIL2BAN_SYSLOG_SHORT_TAG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_SYSLOG_SHORT_TAG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
192
+ * Add [`WP_FAIL2BAN_HTTP_HOST`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_HTTP_HOST.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
193
  * Log XML-RPC authentication failure.
194
  * Add better support for MU deployment.
195
 
196
  = 2.3.2 =
197
+ * Bugfix [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
198
 
199
  = 2.3.0 =
200
+ * Bugfix in *experimental* [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) code (thanks to KyleCartmell).
201
 
202
  = 2.2.1 =
203
+ * Fix stupid mistake with [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
204
 
205
  = 2.2.0 =
206
+ * Custom authentication log is now called [`WP_FAIL2BAN_AUTH_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_AUTH_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
207
+ * Add logging for pingbacks; see [`WP_FAIL2BAN_LOG_PINGBACKS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_LOG_PINGBACKS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
208
+ * Custom pingback log is called [`WP_FAIL2BAN_PINGBACK_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PINGBACK_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
209
 
210
  = 2.1.1 =
211
  * Minor bugfix.
212
 
213
  = 2.1.0 =
214
+ * Add support for blocking user enumeration; see [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
215
+ * Add support for CIDR notation in [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
216
 
217
  = 2.0.1 =
218
+ * Bugfix in *experimental* [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) code.
219
 
220
  = 2.0.0 =
221
+ * Add *experimental* support for X-Forwarded-For header; see [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
222
+ * Add *experimental* support for regex-based login blocking; see [`WP_FAIL2BAN_BLOCKED_USERS`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCKED_USERS.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
223
 
224
  = 1.2.1 =
225
  * Update FAQ.
235
 
236
  == Upgrade Notice ==
237
 
238
+ = 4.2.8 =
239
+ This is a bugfix release. You do not need to update your filters from 4.1.0. This is the *last* release that supports PHP 5.3.
240
 
241
  = 4.2.7.1 =
242
  This is a bugfix release. You do not need to update your filters from 4.1.0.
290
  You will need up update your `fail2ban` filters.
291
 
292
  = 3.5.1 =
293
+ Bugfix: disable [`WP_FAIL2BAN_BLOCK_USER_ENUMERATION`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_BLOCK_USER_ENUMERATION.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8) in admin area....
294
 
295
  = 3.5.0 =
296
  You will need up update your `fail2ban` filters.
302
  BREAKING CHANGE: The `fail2ban` filters have been split into two files. You will need up update your `fail2ban` configuration.
303
 
304
  = 2.3.0 =
305
+ Fix for [`WP_FAIL2BAN_PROXIES`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_PROXIES.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8); if you're not using it you can safely skip this release.
306
 
307
  = 2.2.1 =
308
  Bugfix.
309
 
310
  = 2.2.0 =
311
+ BREAKING CHANGE: `WP_FAIL2BAN_LOG` has been renamed to [`WP_FAIL2BAN_AUTH_LOG`](https://docs.wp-fail2ban.com/en/4.1/defines/WP_FAIL2BAN_AUTH_LOG.html?utm_source=wordpress.org&utm_medium=readme&utm_campaign=4.2.8).
312
 
313
  Pingbacks are getting a lot of attention recently, so *WPf2b* can now log them.
314
  The `wordpress.conf` filter has been updated; you will need to update your `fail2ban` configuration.
321
 
322
  = 2.0.0 =
323
  This is an experimental release. If your current version is working and you're not interested in the new features, skip this version - wait for 2.1.0. For those that do want to test this release, note that `wordpress.conf` has changed - you'll need to copy it to `fail2ban/filters.d` again.
 
vendor/freemius/wordpress-sdk/includes/class-freemius.php CHANGED
@@ -12733,7 +12733,9 @@
12733
  return;
12734
  }
12735
 
12736
- if ( empty( $this->get_installs_ids_with_foreign_licenses() ) ) {
 
 
12737
  // Handle user change only when the parent product or one of its add-ons is activated with a foreign license.
12738
  return;
12739
  }
12733
  return;
12734
  }
12735
 
12736
+ $installs_ids_with_foreign_licenses = $this->get_installs_ids_with_foreign_licenses();
12737
+
12738
+ if ( empty( $installs_ids_with_foreign_licenses ) ) {
12739
  // Handle user change only when the parent product or one of its add-ons is activated with a foreign license.
12740
  return;
12741
  }
wp-fail2ban-core.php DELETED
@@ -1,124 +0,0 @@
1
- <?php
2
- /**
3
- * WP fail2ban core
4
- *
5
- * @package wp-fail2ban
6
- * @since 4.3.0
7
- */
8
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
-
10
- if (defined('ABSPATH')) {
11
- include_once_exists(__DIR__.'/premium/core.php');
12
-
13
- /**
14
- * @since 4.3.0
15
- */
16
- if (!function_exists(__NAMESPACE__.'\authenticate')) {
17
- /**
18
- * Catch empty usernames
19
- *
20
- * @see \wp_authenticate()
21
- *
22
- * @since 4.3.0
23
- *
24
- * @param mixed|null $user
25
- * @param string $username
26
- * @param string $password
27
- *
28
- * @return mixed|null
29
- *
30
- * @wp-f2b-soft Empty username
31
- */
32
- function authenticate($user, $username, $password)
33
- {
34
- if (empty($username) && isset($_POST['log'])) {
35
- openlog();
36
- syslog(LOG_NOTICE, 'Empty username');
37
- closelog();
38
-
39
- do_action(__FUNCTION__, $user, $username, $password);
40
- }
41
-
42
- return $user;
43
- }
44
- add_action('authenticate', __NAMESPACE__.'\authenticate', 1, 3);
45
- }
46
-
47
- /**
48
- * @since 4.0.5
49
- */
50
- if (!function_exists(__NAMESPACE__.'\wp_login')) {
51
- /**
52
- * Hook: wp_login
53
- *
54
- * @since 4.1.0 Add REST support
55
- * @since 3.5.0 Refactored for unit testing
56
- * @since 1.0.0
57
- *
58
- * @param string $user_login
59
- * @param mixed $user
60
- */
61
- function wp_login($user_login, $user)
62
- {
63
- openlog();
64
- syslog(LOG_INFO, "Accepted password for {$user_login}");
65
- closelog();
66
-
67
- do_action(__FUNCTION__, $user_login, $user);
68
- }
69
- add_action('wp_login', __NAMESPACE__.'\wp_login', 10, 2);
70
- }
71
-
72
- /**
73
- * @since 4.0.5
74
- */
75
- if (!function_exists(__NAMESPACE__.'\wp_login_failed')) {
76
- /**
77
- * Hook: wp_login_failed
78
- *
79
- * @since 4.2.4 Add message filter
80
- * @since 4.2.0 Change username check
81
- * @since 4.1.0 Add REST support
82
- * @since 3.5.0 Refactored for unit testing
83
- * @since 1.0.0
84
- *
85
- * @param string $username
86
- *
87
- * @wp-f2b-hard Authentication attempt for unknown user .*
88
- * @wp-f2b-hard REST authentication attempt for unknown user .*
89
- * @wp-f2b-hard XML-RPC authentication attempt for unknown user .*
90
- * @wp-f2b-soft Authentication failure for .*
91
- * @wp-f2b-soft REST authentication failure for .*
92
- * @wp-f2b-soft XML-RPC authentication failure for .*
93
- */
94
- function wp_login_failed($username)
95
- {
96
- global $wp_fail2ban, $wp_xmlrpc_server;
97
-
98
- if (defined('REST_REQUEST')) {
99
- $msg = 'REST a';
100
- $filter = '::REST';
101
- } elseif ($wp_xmlrpc_server) {
102
- $msg = 'XML-RPC a';
103
- $filter = '::XML-RPC';
104
- } else {
105
- $msg = 'A';
106
- $filter = '';
107
- }
108
-
109
- $username = trim($username);
110
- $msg .= (wp_cache_get($username, 'useremail') || wp_cache_get(sanitize_user($username), 'userlogins'))
111
- ? "uthentication failure for {$username}"
112
- : "uthentication attempt for unknown user {$username}";
113
- $msg = apply_filters("wp_fail2ban::wp_login_failed{$filter}", $msg);
114
-
115
- openlog();
116
- syslog(LOG_NOTICE, $msg);
117
- closelog();
118
-
119
- do_action(__FUNCTION__, $username);
120
- }
121
- add_action('wp_login_failed', __NAMESPACE__.'\wp_login_failed');
122
- }
123
- }
124
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wp-fail2ban-features.php DELETED
@@ -1,117 +0,0 @@
1
- <?php
2
- /**
3
- * WP fail2ban features
4
- *
5
- * @package wp-fail2ban
6
- * @since 4.0.0
7
- * @php 5.3
8
- */
9
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
-
11
- if (defined('ABSPATH')) {
12
- include_once_exists(__DIR__.'/premium/features.php');
13
-
14
- /**
15
- * Load all enabled features.
16
- *
17
- * @since 4.3.0
18
- */
19
- function plugins_loaded()
20
- {
21
- Config::load();
22
-
23
- /**
24
- * Comments
25
- *
26
- * @since 4.0.0 Refactored
27
- * @since 3.5.0
28
- */
29
- if (defined('WP_FAIL2BAN_LOG_COMMENTS') && true === WP_FAIL2BAN_LOG_COMMENTS) {
30
- require_once __DIR__.'/feature/comments.php';
31
- }
32
-
33
- /**
34
- * Password
35
- *
36
- * @since 4.0.0 Refactored
37
- * @since 3.5.0
38
- */
39
- if (defined('WP_FAIL2BAN_LOG_PASSWORD_REQUEST') && true === WP_FAIL2BAN_LOG_PASSWORD_REQUEST) {
40
- require_once __DIR__.'/feature/password.php';
41
- }
42
-
43
- /**
44
- * Spam
45
- *
46
- * @since 4.0.0 Refactored
47
- * @since 3.5.0
48
- */
49
- if (defined('WP_FAIL2BAN_LOG_SPAM') && true === WP_FAIL2BAN_LOG_SPAM) {
50
- require_once __DIR__.'/feature/spam.php';
51
- }
52
-
53
- /**
54
- * User enumeration
55
- *
56
- * @since 4.0.0 Refactored
57
- * @since 2.1.0
58
- */
59
- if (defined('WP_FAIL2BAN_BLOCK_USER_ENUMERATION') && true === WP_FAIL2BAN_BLOCK_USER_ENUMERATION) {
60
- require_once __DIR__.'/feature/user-enum.php';
61
- }
62
-
63
- /**
64
- * Users
65
- *
66
- * @since 4.3.0 Better test
67
- * @since 4.0.0 Refactored
68
- * @since 2.0.0
69
- */
70
- if ( (defined('WP_FAIL2BAN_BLOCKED_USERS') && WP_FAIL2BAN_BLOCKED_USERS) ||
71
- (defined('WP_FAIL2BAN_BLOCK_USERNAME_LOGIN') && WP_FAIL2BAN_BLOCK_USERNAME_LOGIN) )
72
- {
73
- require_once __DIR__.'/feature/user.php';
74
- }
75
- }
76
- /**
77
- * Load nice and early.
78
- *
79
- * @since 4.3.0
80
- */
81
- add_action('plugins_loaded', __NAMESPACE__.'\plugins_loaded');
82
-
83
- /**
84
- * Things we need a current user for.
85
- *
86
- * @since 4.3.0
87
- */
88
- function init()
89
- {
90
- /**
91
- * @since 4.3.0 Check for logged in
92
- * @since 4.2.5 Check for admin
93
- */
94
- if (!is_user_logged_in()) {
95
- /**
96
- * XML-RPC
97
- *
98
- * @since 4.0.0 Refactored
99
- * @since 3.0.0
100
- */
101
- if (defined('XMLRPC_REQUEST') && true === XMLRPC_REQUEST) {
102
- require_once __DIR__.'/feature/xmlrpc.php';
103
- }
104
- }
105
- }
106
- add_action('init', __NAMESPACE__.'\init');
107
-
108
- /**
109
- * Load plugin hooks.
110
- *
111
- * Called from `plugins_loaded`
112
- *
113
- * @since 4.3.0
114
- */
115
- require __DIR__.'/feature/plugins.php';
116
- }
117
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wp-fail2ban-main.php CHANGED
@@ -1,31 +1,297 @@
1
  <?php
 
2
  /**
3
- * WP fail2ban main file
4
- *
5
- * @package wp-fail2ban
6
- * @since 4.0.0
7
  */
8
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
9
 
10
- if (defined('ABSPATH')) {
11
- require_once __DIR__.'/lib/defaults.php';
12
- include_once_exists(__DIR__.'/lib/constants.php');
13
- include_once_exists(__DIR__.'/lib/convert-data.php');
14
- require_once __DIR__.'/lib/activation.php';
15
- require_once __DIR__.'/lib/loader.php';
16
- require_once __DIR__.'/feature/lib.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- include_once_exists(__DIR__.'/premium/main.php');
 
 
19
 
 
20
  /**
21
- * @since 4.3.0 Relocate.
22
- * @since 4.2.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  */
24
- if (defined('WP_ADMIN') && WP_ADMIN) {
25
- require_once __DIR__.'/admin/admin.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
 
 
 
27
 
28
- require_once __DIR__.'/wp-fail2ban-core.php';
29
- require_once __DIR__.'/wp-fail2ban-features.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
+ * WP fail2ban main file
5
+ *
6
+ * @since 4.0.0
7
+ * @package wp-fail2ban
8
  */
9
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
 
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+ require_once __DIR__ . '/lib/constants.php';
15
+ require_once __DIR__ . '/lib/loader.php';
16
+ require_once __DIR__ . '/lib/defaults.php';
17
+ register_activation_hook( WP_FAIL2BAN_FILE, function () {
18
+ foreach ( get_mu_plugins() as $plugin => $data ) {
19
+
20
+ if ( 0 === strpos( $data['Name'], 'WP fail2ban' ) ) {
21
+ $wp_f2b_ver = substr( WP_FAIL2BAN_VER, 0, strrpos( WP_FAIL2BAN_VER, '.' ) );
22
+ $wpf2b = 'WP fail2ban';
23
+ $error_msg = sprintf( __( '<h1>Cannot activate %s</h1>' ), $wpf2b );
24
+ $mu_file = WPMU_PLUGIN_DIR . '/' . $plugin;
25
+
26
+ if ( is_link( $mu_file ) ) {
27
+
28
+ if ( false === ($link = readlink( $mu_file )) || false === ($path = realpath( $mu_file )) ) {
29
+ $h3 = __( 'A broken symbolic link was found in <tt>mu-plugins</tt>:' );
30
+ $error_msg .= <<<__ERROR__
31
+ <h3>{$h3}</h3>
32
+ <p><tt>{$mu_file}</tt></p>
33
+ __ERROR__;
34
+ } elseif ( WP_FAIL2BAN_FILE == $path ) {
35
+ // OK, we're linking to ourself
36
+ } else {
37
+ $mu_file = str_replace( '/', '/<wbr>', $mu_file );
38
+ $mu_file = substr( $mu_file, strlen( WPMU_PLUGIN_DIR ) - 1 );
39
+ $h3 = __( 'A conflicting symbolic link was found in <tt>mu-plugins</tt>:' );
40
+ $error_msg .= <<<__ERROR__
41
+ <h3>{$h3}</h3>
42
+ <style>
43
+ table { text-align: center; }
44
+ td { width: 50%; }
45
+ th { font-size: 200%; }
46
+ td, th { font-family: monospace; }
47
+ span.tt { font-weight: bold; }
48
+ </style>
49
+ <table>
50
+ <tr>
51
+ <td>{$mu_file}</td>
52
+ <th>&DoubleRightArrow;</th>
53
+ <td>{$link}</td>
54
+ </tr>
55
+ <tr>
56
+ <td colspan="3"><span class="tt">&equiv;</span> <span>{$path}</span></td>
57
+ </tr>
58
+ <tr>
59
+ <td colspan="3"></td>
60
+ </tr>
61
+ </table>
62
+ __ERROR__;
63
+ }
64
+
65
+ } else {
66
+ $mu_file = str_replace( '/', '/<wbr>', $mu_file );
67
+ $mu_file = substr( $mu_file, strlen( WPMU_PLUGIN_DIR ) - 1 );
68
+ $h3 = __( 'A conflicting file was found in <tt>mu-plugins</tt>:' );
69
+ $error_msg .= <<<__ERROR__
70
+ <h3>{$h3}</h3>
71
+ <p><tt>{$mu_file}</tt></p>
72
+ __ERROR__;
73
+ }
74
+
75
+ $error_msg .= sprintf( __( '<p>Please see the <a href="%s" target="_blank">documentation</a> for how to configure %s for <tt>mu-plugins</tt>.</p>' ), "https://docs.wp-fail2ban.com/en/{$wp_f2b_ver}/configuration.html#mu-plugins-support", $wpf2b );
76
+ $error_msg .= sprintf( __( '<p>Click <a href="%s">here</a> to return to the plugins page.</p>' ), admin_url( 'plugins.php' ) );
77
+ deactivate_plugins( plugin_basename( WP_FAIL2BAN_FILE ) );
78
+ wp_die( $error_msg );
79
+ }
80
+
81
+ }
82
+ } );
83
+ /**
84
+ * @since 4.2.8
85
+ */
86
+ if ( !function_exists( __NAMESPACE__ . '\\release_notes_message' ) ) {
87
+ /**
88
+ * CTA for release notes
89
+ *
90
+ * @since 4.2.8
91
+ *
92
+ * @param string $link Link to release notes page or tab
93
+ */
94
+ function release_notes_message( $link )
95
+ {
96
+
97
+ if ( !defined( 'PHPUNIT_COMPOSER_INSTALL' ) ) {
98
+ $msg = sprintf( ' - please check the <a href="%s">release notes</a>.', $link );
99
+ add_action( 'init', function () use( $msg ) {
100
+ if ( current_user_can( 'manage_options' ) ) {
101
+
102
+ if ( isset( $_GET['wp-fail2ban-notice'] ) || false === ($notice = get_site_option( 'wp-fail2ban-notice' )) || !isset( $notice['4.2.8'] ) || false === $notice['4.2.8'] ) {
103
+ wf_fs()->add_sticky_admin_message(
104
+ $msg,
105
+ 'wpf2b-4.2.8',
106
+ 'Important news',
107
+ 'info'
108
+ );
109
+ update_site_option( 'wp-fail2ban-notice', array(
110
+ '4.2.8' => true,
111
+ ) );
112
+ }
113
+
114
+ }
115
+ } );
116
+ }
117
+
118
+ }
119
+
120
+ }
121
+ require __DIR__ . '/feature/lib.php';
122
+ /**
123
+ * @since 4.2.5
124
+ */
125
+
126
+ if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
127
+ /**
128
+ * @since 4.2.0
129
+ */
130
+ global $wp_fail2ban ;
131
+ $wp_fail2ban['plugins'] = array();
132
+ require __DIR__ . '/feature/plugins.php';
133
+
134
+ if ( is_admin() ) {
135
+ $page = ( wf_fs()->is_free_plan() ? 'wp-fail2ban' : 'wpf2b-settings&tab=about' );
136
+ release_notes_message( admin_url( 'admin.php?page=' . $page ) );
137
+ require 'admin/admin.php';
138
+ }
139
+
140
+ } elseif ( is_admin() ) {
141
+ release_notes_message( admin_url( 'admin.php?page=wp-fail2ban' ) );
142
+ require __DIR__ . '/admin/lib/about.php';
143
+ add_action( 'admin_menu', function () {
144
+ add_menu_page(
145
+ 'WP fail2ban',
146
+ 'WP fail2ban',
147
+ 'manage_options',
148
+ 'wp-fail2ban',
149
+ __NAMESPACE__ . '\\about',
150
+ 'dashicons-analytics'
151
+ );
152
+ } );
153
+ }
154
+
155
+ /**
156
+ * @since 4.0.5
157
+ */
158
+
159
+ if ( !function_exists( __NAMESPACE__ . '\\wp_login' ) ) {
160
+ /**
161
+ * Hook: wp_login
162
+ *
163
+ * @since 4.1.0 Add REST support
164
+ * @since 3.5.0 Refactored for unit testing
165
+ * @since 1.0.0
166
+ *
167
+ * @param string $user_login
168
+ * @param mixed $user
169
+ */
170
+ function wp_login( $user_login, $user )
171
+ {
172
+ global $wp_xmlrpc_server ;
173
+ openlog();
174
+ syslog( LOG_INFO, "Accepted password for {$user_login}" );
175
+ closelog();
176
+ // @codeCoverageIgnoreEnd
177
+ }
178
+
179
+ add_action(
180
+ 'wp_login',
181
+ __NAMESPACE__ . '\\wp_login',
182
+ 10,
183
+ 2
184
+ );
185
+ }
186
 
187
+ /**
188
+ * @since 4.0.5
189
+ */
190
 
191
+ if ( !function_exists( __NAMESPACE__ . '\\wp_login_failed' ) ) {
192
  /**
193
+ * Hook: wp_login_failed
194
+ *
195
+ * @since 4.2.4 Add message filter
196
+ * @since 4.2.0 Change username check
197
+ * @since 4.1.0 Add REST support
198
+ * @since 3.5.0 Refactored for unit testing
199
+ * @since 1.0.0
200
+ *
201
+ * @param string $username
202
+ *
203
+ * @wp-f2b-hard Authentication attempt for unknown user .*
204
+ * @wp-f2b-hard REST authentication attempt for unknown user .*
205
+ * @wp-f2b-hard XML-RPC authentication attempt for unknown user .*
206
+ * @wp-f2b-soft Authentication failure for .*
207
+ * @wp-f2b-soft REST authentication failure for .*
208
+ * @wp-f2b-soft XML-RPC authentication failure for .*
209
  */
210
+ function wp_login_failed( $username )
211
+ {
212
+ global $wp_xmlrpc_server ;
213
+
214
+ if ( defined( 'REST_REQUEST' ) ) {
215
+ $msg = 'REST a';
216
+ $filter = '::REST';
217
+ } elseif ( $wp_xmlrpc_server ) {
218
+ $msg = 'XML-RPC a';
219
+ $filter = '::XML-RPC';
220
+ } else {
221
+ $msg = 'A';
222
+ $filter = '';
223
+ }
224
+
225
+ $username = trim( $username );
226
+ $msg .= ( wp_cache_get( $username, 'useremail' ) || wp_cache_get( sanitize_user( $username ), 'userlogins' ) ? "uthentication failure for {$username}" : "uthentication attempt for unknown user {$username}" );
227
+ $msg = apply_filters( "wp_fail2ban::wp_login_failed{$filter}", $msg );
228
+ openlog();
229
+ syslog( LOG_NOTICE, $msg );
230
+ closelog();
231
+ // @codeCoverageIgnoreEnd
232
  }
233
+
234
+ add_action( 'wp_login_failed', __NAMESPACE__ . '\\wp_login_failed' );
235
+ }
236
 
237
+ /**
238
+ * @since 4.2.5
239
+ */
240
+
241
+ if ( !is_admin() ) {
242
+ /**
243
+ * User enumeration
244
+ *
245
+ * @since 4.0.0 Refactored
246
+ * @since 2.1.0
247
+ */
248
+ if ( defined( 'WP_FAIL2BAN_BLOCK_USER_ENUMERATION' ) && true === WP_FAIL2BAN_BLOCK_USER_ENUMERATION ) {
249
+ require_once __DIR__ . '/feature/user-enum.php';
250
+ }
251
+ /**
252
+ * XML-RPC
253
+ *
254
+ * @since 4.0.0 Refactored
255
+ * @since 3.0.0
256
+ */
257
+ if ( defined( 'XMLRPC_REQUEST' ) && true === XMLRPC_REQUEST ) {
258
+ require_once __DIR__ . '/feature/xmlrpc.php';
259
+ }
260
  }
261
 
262
+ /**
263
+ * Comments
264
+ *
265
+ * @since 4.0.0 Refactored
266
+ * @since 3.5.0
267
+ */
268
+ if ( defined( 'WP_FAIL2BAN_LOG_COMMENTS' ) && true === WP_FAIL2BAN_LOG_COMMENTS ) {
269
+ require_once __DIR__ . '/feature/comments.php';
270
+ }
271
+ /**
272
+ * Password
273
+ *
274
+ * @since 4.0.0 Refactored
275
+ * @since 3.5.0
276
+ */
277
+ if ( defined( 'WP_FAIL2BAN_LOG_PASSWORD_REQUEST' ) && true === WP_FAIL2BAN_LOG_PASSWORD_REQUEST ) {
278
+ require_once __DIR__ . '/feature/password.php';
279
+ }
280
+ /**
281
+ * Spam
282
+ *
283
+ * @since 4.0.0 Refactored
284
+ * @since 3.5.0
285
+ */
286
+ if ( defined( 'WP_FAIL2BAN_LOG_SPAM' ) && true === WP_FAIL2BAN_LOG_SPAM ) {
287
+ require_once __DIR__ . '/feature/spam.php';
288
+ }
289
+ /**
290
+ * Users
291
+ *
292
+ * @since 4.0.0 Refactored
293
+ * @since 2.0.0
294
+ */
295
+ if ( defined( 'WP_FAIL2BAN_BLOCKED_USERS' ) && '' < WP_FAIL2BAN_BLOCKED_USERS ) {
296
+ require_once __DIR__ . '/feature/user.php';
297
+ }
wp-fail2ban-premium.php DELETED
@@ -1,94 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * WP fail2ban premium
5
- *
6
- * @package wp-fail2ban
7
- * @since 4.3.0
8
- */
9
- namespace org\lecklider\charles\wordpress\wp_fail2ban;
10
-
11
-
12
- if ( defined( 'ABSPATH' ) ) {
13
- /**
14
- * Freemius integration
15
- *
16
- * @since 4.0.0
17
- */
18
-
19
- if ( function_exists( __NAMESPACE__ . '\\wf_fs' ) ) {
20
- // @codeCoverageIgnoreStart
21
- wf_fs()->set_basename( true, WP_FAIL2BAN_FILE );
22
- return;
23
- } else {
24
- /**
25
- * Create a helper function for easy SDK access.
26
- */
27
- function wf_fs()
28
- {
29
- global $wf_fs ;
30
-
31
- if ( !isset( $wf_fs ) ) {
32
- // Activate multisite network integration.
33
- if ( !defined( 'WP_FS__PRODUCT_3072_MULTISITE' ) ) {
34
- define( 'WP_FS__PRODUCT_3072_MULTISITE', true );
35
- }
36
- // Include Freemius SDK.
37
- require_once __DIR__ . '/vendor/freemius/wordpress-sdk/start.php';
38
- $wf_fs = fs_dynamic_init( array(
39
- 'id' => '3072',
40
- 'slug' => 'wp-fail2ban',
41
- 'type' => 'plugin',
42
- 'public_key' => 'pk_146d2c2a5bee3b157e43501ef8682',
43
- 'is_premium' => false,
44
- 'has_addons' => true,
45
- 'has_paid_plans' => true,
46
- 'trial' => array(
47
- 'days' => 14,
48
- 'is_require_payment' => false,
49
- ),
50
- 'menu' => array(
51
- 'slug' => 'wp-fail2ban-menu',
52
- 'support' => true,
53
- 'network' => true,
54
- ),
55
- 'is_live' => true,
56
- ) );
57
- }
58
-
59
- return $wf_fs;
60
- }
61
-
62
- // Init Freemius.
63
- wf_fs();
64
- // Set currency to GBP
65
- wf_fs()->add_filter( 'default_currency', function () {
66
- return 'gbp';
67
- } );
68
- // Set custom icon
69
- wf_fs()->add_filter( 'plugin_icon', function () {
70
- return __DIR__ . '/assets/icon.svg';
71
- } );
72
- // Set forum URL
73
- wf_fs()->add_filter( 'support_forum_url', function () {
74
- if ( wf_fs()->is_trial() ) {
75
- /** Trial forum: Invite-only */
76
- return 'https://forums.invis.net/c/wp-fail2ban/support-trial/';
77
- }
78
- if ( wf_fs()->is_free_plan() ) {
79
- /** Free forum: available to all */
80
- return 'https://forums.invis.net/c/wp-fail2ban/support-free/';
81
- }
82
- if ( wf_fs()->is_paying() ) {
83
- /** Paying forum: Invite-only */
84
- return 'https://forums.invis.net/c/wp-fail2ban/support-premium/';
85
- }
86
- /** Just in case... */
87
- return 'https://forums.invis.net/c/wp-fail2ban/';
88
- } );
89
- // Signal that SDK was initiated.
90
- do_action( 'wf_fs_loaded' );
91
- }
92
-
93
- // @codeCoverageIgnoreEnd
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wp-fail2ban.php CHANGED
@@ -1,21 +1,20 @@
1
  <?php
 
2
  /*
3
  * Plugin Name: WP fail2ban
4
  * Plugin URI: https://wp-fail2ban.com/
5
  * Description: Write a myriad of WordPress events to syslog for integration with fail2ban.
6
  * Text Domain: wp-fail2ban
7
- * Version: 4.3.0-RC3
8
  * Author: Charles Lecklider
9
  * Author URI: https://charles.lecklider.org/
10
  * License: GPLv2
11
  * SPDX-License-Identifier: GPL-2.0
12
- * Requires PHP: 5.6
13
- * Network: true
14
  *
15
- */
16
-
17
  /*
18
- * Copyright 2012-20 Charles Lecklider (email : wordpress@charles.lecklider.org)
19
  *
20
  * This program is free software; you can redistribute it and/or modify
21
  * it under the terms of the GNU General Public License, version 2, as
@@ -30,51 +29,97 @@
30
  * along with this program; if not, write to the Free Software
31
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32
  */
33
-
34
  /**
35
  * WP fail2ban
36
  *
37
- * @package wp-fail2ban
38
  */
39
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
40
 
41
- if (defined('ABSPATH')) {
 
 
 
 
42
 
 
43
  /**
44
- * Helper - include_once file if it exists
45
- *
46
- * Avoids warning with XDebug
47
  *
48
- * @since 4.3.0
49
- *
50
- * @param string $file File to include_once
51
  */
52
- function include_once_exists($file)
53
- {
54
- if (is_file($file)) {
55
- require_once $file;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
-
59
-
60
  /**
61
- * @since 4.0.5
 
 
62
  */
63
- if (!defined('WP_FAIL2BAN_VER')) {
64
- define('WP_FAIL2BAN_VER', '4.3.0-RC3');
65
- }
66
- if (!defined('WP_FAIL2BAN_DIR')) {
67
- define('WP_FAIL2BAN_DIR', __DIR__);
68
- }
69
- if (!defined('WP_FAIL2BAN_FILE')) {
70
- define('WP_FAIL2BAN_FILE', __FILE__);
71
- }
72
- if (!defined('WP_FAIL2BAN_NS')) {
73
- define('WP_FAIL2BAN_NS', __NAMESPACE__);
74
- }
75
-
76
-
77
- include_once_exists(__DIR__.'/wp-fail2ban-premium.php');
78
  require_once 'wp-fail2ban-main.php';
79
  }
80
-
1
  <?php
2
+
3
  /*
4
  * Plugin Name: WP fail2ban
5
  * Plugin URI: https://wp-fail2ban.com/
6
  * Description: Write a myriad of WordPress events to syslog for integration with fail2ban.
7
  * Text Domain: wp-fail2ban
8
+ * Version: 4.2.8
9
  * Author: Charles Lecklider
10
  * Author URI: https://charles.lecklider.org/
11
  * License: GPLv2
12
  * SPDX-License-Identifier: GPL-2.0
13
+ * Requires PHP: 5.3
 
14
  *
15
+ */
 
16
  /*
17
+ * Copyright 2012-19 Charles Lecklider (email : wordpress@charles.lecklider.org)
18
  *
19
  * This program is free software; you can redistribute it and/or modify
20
  * it under the terms of the GNU General Public License, version 2, as
29
  * along with this program; if not, write to the Free Software
30
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31
  */
 
32
  /**
33
  * WP fail2ban
34
  *
35
+ * @package wp-fail2ban
36
  */
37
  namespace org\lecklider\charles\wordpress\wp_fail2ban;
38
 
39
+ /**
40
+ * @since 4.0.5
41
+ */
42
+ define( 'WP_FAIL2BAN_VER', '4.2.8' );
43
+ define( 'WP_FAIL2BAN_FILE', __FILE__ );
44
 
45
+ if ( defined( 'ABSPATH' ) ) {
46
  /**
47
+ * Freemius integration
 
 
48
  *
49
+ * @since 4.0.0
 
 
50
  */
51
+
52
+ if ( function_exists( __NAMESPACE__ . '\\wf_fs' ) ) {
53
+ // @codeCoverageIgnoreStart
54
+ wf_fs()->set_basename( false, __FILE__ );
55
+ return;
56
+ } else {
57
+ /**
58
+ * Create a helper function for easy SDK access.
59
+ */
60
+ function wf_fs()
61
+ {
62
+ global $wf_fs ;
63
+
64
+ if ( !isset( $wf_fs ) ) {
65
+ // Include Freemius SDK.
66
+ require_once dirname( __FILE__ ) . '/vendor/freemius/wordpress-sdk/start.php';
67
+ $wf_fs = fs_dynamic_init( array(
68
+ 'id' => '3072',
69
+ 'slug' => 'wp-fail2ban',
70
+ 'type' => 'plugin',
71
+ 'public_key' => 'pk_146d2c2a5bee3b157e43501ef8682',
72
+ 'is_premium' => false,
73
+ 'has_addons' => true,
74
+ 'has_paid_plans' => true,
75
+ 'trial' => array(
76
+ 'days' => 14,
77
+ 'is_require_payment' => false,
78
+ ),
79
+ 'menu' => array(
80
+ 'slug' => 'wp-fail2ban',
81
+ 'first-path' => 'admin.php?page=wp-fail2ban',
82
+ 'support' => true,
83
+ ),
84
+ 'is_live' => true,
85
+ ) );
86
+ }
87
+
88
+ return $wf_fs;
89
  }
90
+
91
+ // Init Freemius.
92
+ wf_fs();
93
+ // Set currency to GBP
94
+ wf_fs()->add_filter( 'default_currency', function () {
95
+ return 'gbp';
96
+ } );
97
+ // Set forum URL
98
+ wf_fs()->add_filter( 'support_forum_url', function () {
99
+ if ( wf_fs()->is_trial() ) {
100
+ /** Trial forum: Invite-only */
101
+ return 'https://forums.invis.net/c/wp-fail2ban-premium/support-trial/';
102
+ }
103
+ if ( wf_fs()->is_free_plan() ) {
104
+ /** Free forum: available to all */
105
+ return 'https://forums.invis.net/c/wp-fail2ban/support-free/';
106
+ }
107
+ if ( wf_fs()->is_paying() ) {
108
+ /** Paying forum: Invite-only */
109
+ return 'https://forums.invis.net/c/wp-fail2ban-premium/support-premium/';
110
+ }
111
+ /** Just in case... */
112
+ return 'https://forums.invis.net/c/wp-fail2ban/';
113
+ } );
114
+ // Signal that SDK was initiated.
115
+ do_action( 'wf_fs_loaded' );
116
  }
117
+
118
+ // @codeCoverageIgnoreEnd
119
  /**
120
+ * Freemius insists on mangling the formatting of the main plugin file
121
+ *
122
+ * @since 4.0.0 Refactored
123
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  require_once 'wp-fail2ban-main.php';
125
  }