PluginProbe
Loginizer / 2.0.8
Loginizer v2.0.8
2.1.0 2.0.9 2.0.8 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 All 74 releases
loginizer / main / settings / security.php

security.php in Loginizer 2.0.8, at main/settings/security.php

1,029 lines 37.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if(!defined('ABSPATH')){
4 die('Hacking Attempt!');
5 }
6
7 // Loginizer - Security Settings Page
8 function loginizer_page_security(){
9
10 global $loginizer, $lz_error, $lz_env, $wpdb;
11
12 if(!current_user_can('manage_options')){
13 wp_die('Sorry, but you do not have permissions to change settings.');
14 }
15
16 if(!loginizer_is_premium() && count($_POST) > 0){
17 $lz_error['not_in_free'] = __('This feature is not available in the Free version.', 'loginizer').' <a href="'.LOGINIZER_PRICING_URL.'" target="_blank" style="text-decoration:none; color:green;"><b>'.esc_html__('Upgrade to Pro', 'loginizer').'</b></a>';
18 return loginizer_page_security_T();
19 }
20
21 /* Make sure post was from this page */
22 if(count($_POST) > 0){
23 check_admin_referer('loginizer-options');
24 }
25
26 if(isset($_POST['save_lz'])){
27
28 $option['login_slug'] = lz_optpost('login_slug');
29 $option['rename_login_secret'] = (int) lz_optpost('rename_login_secret');
30 $option['hide_wp_admin'] = !empty($_POST['hide_wp_admin']);
31 $option['login_redirect_url'] = lz_optpost('login_redirect_url');
32 $option['xmlrpc_slug'] = lz_optpost('xmlrpc_slug');
33 $option['xmlrpc_disable'] = (int) lz_optpost('xmlrpc_disable');
34 $option['pingbacks_disable'] = (int) lz_optpost('pingbacks_disable');
35
36 // Login Slug Valid ?
37 if(!empty($option['login_slug'])){
38 if(strlen($option['login_slug']) <= 4 || strlen($option['login_slug']) > 50){
39 $lz_error['login_slug'] = __('The Login slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
40 }
41 }
42
43 // login slug and admin slug cannot be the same
44 $_loginizer_wp_admin = get_option('loginizer_wp_admin');
45 if(!empty($_loginizer_wp_admin['admin_slug']) && $_loginizer_wp_admin['admin_slug'] == $option['login_slug']){
46 $lz_error['lz_same_slug'] = __('The wp-login.php and wp-admin slugs cannot be the same. Choose unique names for login and admin slugs', 'loginizer');
47 return loginizer_page_security_T();
48 }
49
50 // XML-RPC Slug Valid ?
51 if(!empty($option['xmlrpc_slug'])){
52 if(strlen($option['xmlrpc_slug']) <= 4 || strlen($option['xmlrpc_slug']) > 50){
53 $lz_error['xmlrpc_slug'] = __('The XML-RPC slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
54 }
55 }
56
57 // Is there an error ?
58 if(!empty($lz_error)){
59 return loginizer_page_security_T();
60 }
61
62 // Save the options
63 update_option('loginizer_security', $option);
64
65 // Mark as saved
66 $GLOBALS['lz_saved'] = true;
67
68 }
69
70 // Reset the username
71 if(isset($_POST['save_lz_admin'])){
72
73 // Get the new username
74 $current_username = lz_optpost('current_username');
75 $new_username = lz_optpost('new_username');
76
77 if(empty($current_username)){
78 $lz_error['current_username_empty'] = __('Current username is required', 'loginizer');
79 return loginizer_page_security_T();
80 }
81
82 if(empty($new_username)){
83 $lz_error['new_username_empty'] = __('New username is required', 'loginizer');
84 return loginizer_page_security_T();
85 }
86
87 // Is the starting of the username having 'admin' ?
88 if(@strtolower(substr($new_username, 0, 5)) == 'admin'){
89 $lz_error['user_exists'] = __('The username begins with <b>admin</b>. Please change it !', 'loginizer');
90 return loginizer_page_security_T();
91 }
92
93 // Lets check if there is such a user
94 $found = get_user_by('login', $new_username);
95
96 // Found one !
97 if(!empty($found->ID)){
98 $lz_error['user_exists'] = __('The new username is already assigned to another user', 'loginizer');
99 return loginizer_page_security_T();
100 }
101
102 $old_user = get_user_by('login', $current_username);
103
104 if(empty($old_user->ID)){
105 $lz_error['current_username_invalid'] = __('No user found with the current username provided', 'loginizer');
106 return loginizer_page_security_T();
107 }
108
109 if(empty($old_user->caps['administrator'])){
110 $lz_error['user_not_admin'] = __('The user is not an administrator. Only administrator user\'s username can be changed.', 'loginizer');
111 return loginizer_page_security_T();
112 }
113
114 $is_super_admin = 0;
115 if(is_multisite() && is_super_admin($old_user->ID)){
116 $is_super_admin = 1;
117 }
118
119 // Update the username
120 $update_data = array('user_login' => $new_username);
121 $where_data = array('ID' => $old_user->ID);
122
123 $format = array('%s');
124 $where_format = array('%d');
125
126 $wpdb->update($wpdb->prefix.'users', $update_data, $where_data, $format, $where_format);
127
128 // Update the super admins list for multisite
129 if(!empty($is_super_admin)){
130
131 $super_admins = get_site_option('site_admins');
132
133 foreach($super_admins as $sk => $sv){
134 // Remove the existing username from super admins list
135 if($sv == $current_username){
136 unset($super_admins[$sk]);
137 }
138 }
139
140 // Add the new username
141 $super_admins[] = $new_username;
142
143 update_site_option( 'site_admins', $super_admins );
144
145 }
146
147 // Mark as saved
148 $GLOBALS['lz_saved'] = true;
149
150 }
151
152 // Change the wp-admin slug
153 if(isset($_POST['save_lz_wp_admin'])){
154
155 // Get the new username
156 $option['admin_slug'] = lz_optpost('admin_slug');
157 $option['restrict_wp_admin'] = (int) lz_optpost('restrict_wp_admin');
158 $option['wp_admin_msg'] = @stripslashes($_POST['wp_admin_msg']);
159 $lz_wp_admin_docs = (int) lz_optpost('lz_wp_admin_docs');
160
161 // login slug and admin slug cannot be the same
162 $_loginizer_security = get_option('loginizer_security');
163 if(!empty($_loginizer_security['login_slug']) && $_loginizer_security['login_slug'] == $option['admin_slug']){
164 $lz_error['lz_same_slug'] = __('The wp-login.php and wp-admin slugs cannot be the same. Choose unique names for login and admin slugs', 'loginizer');
165 return loginizer_page_security_T();
166 }
167
168 // Did you agree to this ?
169 if(!empty($option['admin_slug']) && empty($lz_wp_admin_docs)){
170 $lz_error['lz_wp_admin_docs'] = __('You have not confirmed that you have read the guide and configured .htaccess. Please read the guide, configure .htaccess and then save these settings and check this checkbox', 'loginizer');
171 return loginizer_page_security_T();
172 }
173
174 // Length
175 if(!empty($option['admin_slug']) && (strlen($option['admin_slug']) <= 4 || strlen($option['admin_slug']) > 50)){
176 $lz_error['admin_slug'] = __('The new Admin slug length must be greater than <b>4</b> chars and upto <b>50</b> chars long', 'loginizer');
177 return loginizer_page_security_T();
178 }
179
180 // Only regular characters
181 if(preg_match('/[^\w\d\-_]/is', $option['admin_slug'])){
182 $lz_error['admin_slug_chars'] = __('Special characters are not allowed', 'loginizer');
183 return loginizer_page_security_T();
184 }
185
186 // Update the option
187 update_option('loginizer_wp_admin', $option);
188
189 // Mark as saved
190 $GLOBALS['lz_saved'] = true;
191
192 }
193
194
195 // Save blacklisted usernames
196 if(isset($_POST['save_lz_bl_users'])){
197
198 $usernames = isset($_POST['lz_bl_users']) && is_array($_POST['lz_bl_users']) ? $_POST['lz_bl_users'] : array();
199
200 // Process the usernames i.e. remove blanks
201 foreach($usernames as $k => $v){
202 $v = trim($v);
203
204 // Unset blank values
205 if(empty($v)){
206 unset($usernames[$k]);
207 }
208
209 // Disallow these special characters to avoid XSS or any other security vulnerability
210 if(preg_match('/[\<\>\"\']/', $v)){
211 unset($usernames[$k]);
212 }
213 }
214
215 // Update the blacklist
216 update_option('loginizer_username_blacklist', array_values($usernames));
217
218 // Mark as saved
219 $GLOBALS['lz_saved'] = true;
220
221 }
222
223
224 // Save blacklisted domains
225 if(isset($_POST['save_lz_bl_domains'])){
226
227 $domains = isset($_POST['lz_bl_domains']) && is_array($_POST['lz_bl_domains']) ? $_POST['lz_bl_domains'] : array();
228
229 // Process the domains i.e. remove blanks
230 foreach($domains as $k => $v){
231 $v = trim($v);
232
233 // Unset blank values
234 if(empty($v)){
235 unset($domains[$k]);
236 }
237
238 // Disallow these special characters to avoid XSS or any other security vulnerability
239 if(preg_match('/[\<\>\"\']/', $v)){
240 unset($domains[$k]);
241 }
242 }
243
244 // Update the blacklist
245 update_option('loginizer_domains_blacklist', array_values($domains));
246
247 // Mark as saved
248 $GLOBALS['lz_saved'] = true;
249
250 }
251
252
253 if(isset($_POST['save_lz_csrf_protection'])){
254 update_option('loginizer_csrf_protection', empty(lz_optpost('enable_csrf_protection')) ? false : true);
255
256 delete_transient('loginizer_csrf_mod_rewrite');
257 $GLOBALS['lz_saved'] = true;
258 }
259
260 if(isset($_POST['save_lz_limit_session'])){
261 $limit_session = map_deep($_POST['limit_session'], 'sanitize_text_field');
262
263 if(empty($limit_session)){
264 delete_option('loginizer_limit_session');
265 } else {
266 update_option('loginizer_limit_session', $limit_session);
267 }
268
269 $GLOBALS['lz_saved'] = true;
270 }
271
272 // Call theme
273 loginizer_page_security_T();
274
275 }
276
277 // Loginizer - Security Settings Page Theme
278 function loginizer_page_security_T(){
279
280 global $loginizer, $lz_error, $lz_env;
281
282 // Universal header
283 loginizer_page_header('Security Settings');
284
285 loginizer_feature_available('Security Settings');
286
287 // Saved ?
288 if(!empty($GLOBALS['lz_saved'])){
289 echo '<div id="message" class="updated"><p>'. __('The settings were saved successfully', 'loginizer'). '</p></div><br />';
290 }
291
292 // Any errors ?
293 if(!empty($lz_error)){
294 lz_report_error($lz_error);echo '<br />';
295 }
296
297 $current_admin = get_user_by('id', 1);
298
299 ?>
300
301 <style>
302 input[type="text"], textarea, select {
303 width: 70%;
304 }
305
306 .form-table label{
307 font-weight:bold;
308 }
309
310 .exp{
311 font-size:12px;
312 }
313 </style>
314
315 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
316
317 <div id="" class="postbox">
318
319 <div class="postbox-header">
320 <h2 class="hndle ui-sortable-handle">
321 <span><?php echo __('Rename Login Page', 'loginizer'); ?></span>
322 </h2>
323 </div>
324
325 <div class="inside">
326
327 <?php wp_nonce_field('loginizer-options'); ?>
328 <table class="form-table">
329 <tr>
330 <td scope="row" valign="top" colspan="2">
331 <i><?php echo __('You can rename your Login page from','loginizer'). ' <b> '. $loginizer['login_basename'].' </b> '.__(' to anything of your choice e.g. mylogin. This would make it very difficult for automated attack bots to know where to login !','loginizer'); ?></i>
332 </td>
333 </tr>
334 <tr>
335 <td scope="row" valign="top" style="width:40% !important">
336 <label><?php echo __('New Login Slug', 'loginizer'); ?></label><br>
337 <span class="exp"><?php echo __('Set blank to reset to the original login URL', 'loginizer'); ?></span>
338 </td>
339 <td>
340 <input type="text" size="50" value="<?php echo (!empty($loginizer['login_slug']) ? lz_POSTval('login_slug', $loginizer['login_slug']) : ''); ?>" name="login_slug" />
341 </td>
342 </tr>
343
344 <?php
345
346 if(!defined('SITEPAD')){
347
348 ?>
349 <tr>
350 <td scope="row" valign="top" style="width:200px !important">
351 <label><?php echo __('Access Secretly Only', 'loginizer'); ?></label><br>
352 <span class="exp"><?php echo sprintf(__('If set, then all Login URL\'s will still point to %s and users will have to access the New Login Slug by typing it in the browser.', 'loginizer'), esc_html($loginizer['login_basename'])); ?></span>
353 </td>
354 <td>
355 <input type="checkbox" value="1" name="rename_login_secret" <?php echo lz_POSTchecked('rename_login_secret', (empty($loginizer['rename_login_secret']) ? false : true)); ?> />
356 </td>
357 </tr>
358 <tr>
359 <td scope="row" valign="top" style="width:200px !important">
360 <label><?php echo __('Hide WP Admin', 'loginizer'); ?></label><br>
361 <span class="exp"><?php echo __('If the user is not logged in they wont be able to access wp-admin url.', 'loginizer'); ?></span>
362 </td>
363 <td>
364 <input type="checkbox" value="1" name="hide_wp_admin" <?php echo lz_POSTchecked('hide_wp_admin', (empty($loginizer['hide_wp_admin']) ? false : true)); ?> />
365 </td>
366 </tr>
367 <tr>
368 <td scope="row" valign="top" style="width:200px !important">
369 <label><?php echo __('Redirect URL', 'loginizer'); ?></label><br>
370 <span class="exp"><?php echo __('Which page should be shown when someone tries to access wp-admin when it is hidden.', 'loginizer'); ?></span>
371 <span class="exp"><?php echo __('Default: HomePage.', 'loginizer'); ?></span>
372 </td>
373 <td>
374 <?php echo esc_url(home_url('/')); ?>&nbsp;<input type="text" style="width:20%;" name="login_redirect_url" value="<?php echo (!empty($loginizer['login_redirect_url']) ? lz_POSTval('login_redirect_url', $loginizer['login_redirect_url']) : ''); ?>"/>
375 </td>
376 </tr>
377
378 <?php
379
380 }
381
382 ?>
383 </table><br />
384 <center><input name="save_lz" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
385
386 </div>
387 </div>
388
389 <?php
390
391 if(!defined('SITEPAD')){
392
393 ?>
394
395 <div id="" class="postbox">
396
397 <div class="postbox-header">
398 <h2 class="hndle ui-sortable-handle">
399 <span><?php echo __('XML-RPC Settings', 'loginizer'); ?></span>
400 </h2>
401 </div>
402
403 <div class="inside">
404
405 <?php wp_nonce_field('loginizer-options'); ?>
406 <table class="form-table">
407 <tr>
408 <td scope="row" valign="top" colspan="2">
409 <i><?php echo __('WordPress\'s XML-RPC feature allows external services to access and modify content on the site. Services like the Jetpack plugin, the WordPress mobile app, pingbacks, etc make use of the XML-RPC feature. If this site does not use a service that requires XML-RPC, please <b>disable</b> the XML-RPC feature as it prevents attackers from using the feature to attack the site. If your service can use a custom XML-RPC URL, you can also <b>rename</b> the XML-RPC page to a <b>custom slug</b>.', 'loginizer'); ?></i>
410 </td>
411 </tr>
412 <tr>
413 <td scope="row" valign="top" style="width:40% !important">
414 <label><?php echo __('Disable XML-RPC', 'loginizer'); ?></label>
415 </td>
416 <td>
417 <input type="checkbox" value="1" name="xmlrpc_disable" <?php echo lz_POSTchecked('xmlrpc_disable', (empty($loginizer['xmlrpc_disable']) ? false : true)); ?> />
418 </td>
419 </tr>
420 <tr>
421 <td scope="row" valign="top" style="width:40% !important">
422 <label><?php echo __('Disable Pingbacks', 'loginizer'); ?></label>
423 </td>
424 <td>
425 <input type="checkbox" value="1" name="pingbacks_disable" <?php echo lz_POSTchecked('pingbacks_disable', (empty($loginizer['pingbacks_disable']) ? false : true)); ?> />
426 </td>
427 </tr>
428 <tr>
429 <td scope="row" valign="top">
430 <label><?php echo __('New XML-RPC Slug', 'loginizer'); ?></label><br>
431 <span class="exp"><?php echo __('Set blank to reset to the original XML-RPC URL', 'loginizer'); ?></span>
432 </td>
433 <td>
434 <input type="text" size="50" value="<?php echo (!empty($loginizer['xmlrpc_slug']) ? lz_optpost('xmlrpc_slug', $loginizer['xmlrpc_slug']) : ''); ?>" name="xmlrpc_slug" />
435 </td>
436 </tr>
437 </table><br />
438 <center><input name="save_lz" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
439
440 </div>
441 </div>
442
443 <?php
444
445 }
446
447 ?>
448
449 </form>
450
451 <?php
452
453 if(!defined('SITEPAD')){
454
455 ?>
456
457 <script type="text/javascript">
458
459 function lz_update_htaccess_admin(e){
460
461 var admin_name = jQuery(e).val();
462
463 if(admin_name.length == 0){
464 admin_name = 'wp-admin';
465 }
466
467 var textarea = jQuery('.lz-htaccess-textarea');
468
469 if(textarea.length == 0) {
470 return;
471 }
472
473 var htaccess = textarea.val();
474 htaccess = htaccess.replace(
475 /RewriteRule \^\(?([^\(\s]+)(?=\(-lzs|\()/g,
476 (match, current_slug) => match.replace(current_slug, admin_name)
477 );
478 textarea.val(htaccess);
479
480 }
481
482
483 function dirname(path) {
484 return path.replace(/\\/g, '/').replace(/\/[^/]*\/?$/, '');
485 }
486
487 function lz_test_wp_admin(){
488
489 var data = new Object();
490 data["action"] = "loginizer_wp_admin";
491 data["nonce"] = "<?php echo wp_create_nonce('loginizer_admin_ajax');?>";
492
493 var new_ajaxurl = dirname(dirname(ajaxurl))+'/'+jQuery('#lz_admin_slug').val()+'/admin-ajax.php';
494
495 // AJAX and on success function
496 jQuery.post(new_ajaxurl, data, function(response){
497
498 if(response['result'] == 1){
499 alert("<?php echo __('Everything seems to be good. You can proceed to save the settings !', 'loginizer'); ?>");
500 }
501
502 // Throw an error for failures
503 }).fail(function() {
504 alert("<?php echo __('There was an error connecting to WordPress with the new Admin Slug. Did you configure everything properly ?', 'loginizer'); ?>");
505 });
506 //jQuery.ajax('<input type="text" size="30" value="" name="lz_bl_users[]" class="lz_bl_users" />');
507 return false;
508 };
509
510 </script>
511
512 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
513 <div id="" class="postbox">
514
515 <div class="postbox-header">
516 <h2 class="hndle ui-sortable-handle">
517 <span><?php echo __('Rename wp-admin access', 'loginizer'); ?></span>
518 </h2>
519 </div>
520
521 <div class="inside">
522
523 <?php wp_nonce_field('loginizer-options'); ?>
524 <table class="form-table">
525 <?php
526 if(preg_match('/(apache|litespeed|lsws)/is', $_SERVER["SERVER_SOFTWARE"])){
527 // Supported. Do nothing
528 }else{
529 echo '<tr>
530 <td scope="row" valign="top" colspan="2">
531 <div style="color:#a94442; background-color:#f2dede; border-color:#ebccd1; padding:15px; border:1px solid transparent; border-radius:4px;">'.__('Rename wp-admin access feature is supported only on Apache and Litespeed', 'loginizer').'</div>
532 </td>
533 </tr>';
534 }
535
536 if(defined('LOGINIZER_PREMIUM') && !empty($loginizer['enable_csrf_protection']) && empty($loginizer['admin_slug'])){
537
538 echo '<div style="color: #856404; background-color: #fff3cd; border-color: #ffeeba; padding: 15px; font-size:1rem; font-weight:400;">'.esc_html__('Note: Be careful while changing the Admin name as your CSRF Protection is on', 'loginizer').'</div>';
539
540 }
541 ?>
542 <tr>
543 <td scope="row" valign="top" colspan="2">
544 <i><?php echo __('You can rename your WordPress Admin access URL <b>wp-admin</b> to anything of your choice e.g. my-admin. This will require you to change .htaccess, so please follow','loginizer'); ?> <a href="<?php echo LOGINIZER_DOCS;?>Renaming_the_WP-Admin_Area" target="_blank"><?php echo __('our guide','loginizer').'</a> '.__('on how to do so !','loginizer'); ?></i>
545 </td>
546 </tr>
547 <tr>
548 <td scope="row" valign="top" style="width:40% !important">
549 <label><?php echo __('New wp-admin Slug', 'loginizer'); ?></label><br>
550 <span class="exp"><?php echo __('Set blank to reset to the original wp-admin URL', 'loginizer'); ?></span>
551 </td>
552 <td>
553 <input type="text" size="50" value="<?php echo (!empty($loginizer['admin_slug']) ? lz_optpost('admin_slug', $loginizer['admin_slug']) : ''); ?>" name="admin_slug" id="lz_admin_slug" onchange="lz_update_htaccess_admin(this)"/>
554 </td>
555 </tr>
556 <tr>
557 <td scope="row" valign="top" style="width:200px !important">
558 <label><?php echo __('Disable wp-admin access', 'loginizer'); ?></label><br>
559 <span class="exp"><?php echo __('If set, then only the new admin slug will work and access to the Old Admin Slug i.e. wp-admin will be disabled. If anyone accesses wp-admin, a warning will be shown.<br><label>NOTE: Please use this option cautiously !</label>', 'loginizer'); ?></span>
560 </td>
561 <td>
562 <input type="checkbox" id="lz_restrict_wp_admin" onchange="lz_wp_admin_msg_toggle()" value="1" name="restrict_wp_admin" <?php echo lz_POSTchecked('restrict_wp_admin', (empty($loginizer['restrict_wp_admin']) ? false : true)); ?> />
563 </td>
564 </tr>
565 <tr id="lz_wp_admin_msg_row" style="display:none">
566 <td scope="row" valign="top">
567 <label><?php echo __('WP-Admin Error Message', 'loginizer'); ?></label><br>
568 <span class="exp"><?php echo __('Error message to show if someone accesses wp-admin', 'loginizer'); ?></span> Default : <?php echo (!empty($loginizer['wp_admin_d_msg']) ? $loginizer['wp_admin_d_msg'] : ''); ?>
569 </td>
570 <td>
571 <input type="text" size="50" value="<?php echo lz_htmlizer(!empty($_POST['wp_admin_msg']) ? stripslashes($_POST['wp_admin_msg']) : (!empty($loginizer['wp_admin_msg']) ? $loginizer['wp_admin_msg'] : '')); ?>" name="wp_admin_msg" id="lz_wp_admin_msg" />
572 </td>
573 </tr>
574
575 <?php
576 loginizer_htaccess_rules();
577 ?>
578 <tr>
579 <td scope="row" valign="top" style="width:200px !important">
580 <label><?php echo __('I have setup .htaccess', 'loginizer'); ?></label><br>
581 <span class="exp"><?php echo sprintf(__('You need to confirm that you have configured .htaccess as per %sour guide%s so that we can safely enable this feature', 'loginizer'), '<a href="'.LOGINIZER_DOCS.'Renaming_the_WP-Admin_Area" target="_blank">', '</a>'); ?></span>
582 </td>
583 <td>
584 <input type="checkbox" value="1" name="lz_wp_admin_docs" />
585 <input type="button" onclick="lz_test_wp_admin()" class="button" style="background: #5cb85c; color:white; border:#5cb85c" value="<?php echo __('Test New WP-Admin Slug', 'loginizer'); ?>" />
586 </td>
587 </tr>
588 </table><br />
589 <center><input name="save_lz_wp_admin" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
590
591 </div>
592 </div>
593 </form>
594
595 <script type="text/javascript">
596 function lz_csrf_htaccess_update(e){
597 event.preventDefault();
598
599 var tb = jQuery(e).closest('table'),
600 csrf_enabled = tb.find('[name="enable_csrf_protection"]'),
601 admin_name = tb.find('#lz_admin_slug');
602
603 var data = new Object();
604
605 // Setting admin name if anything is set
606 if(admin_name && admin_name.val()){
607 data['admin_name'] = admin_name.val();
608 }
609
610 if(csrf_enabled){
611 data['csrf'] = true;
612 } else {
613 data['csrf'] = false;
614 }
615
616 data['action'] = 'loginizer_update_csrf_mod';
617 data['nonce'] = '<?php echo wp_create_nonce('loginizer_admin_ajax');?>';
618
619 var new_ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'
620
621 // AJAX and on success function
622 jQuery.post(new_ajaxurl, data, function(response){
623
624 if(response['success'] == true){
625 alert("<?php esc_html_e('.htaccess has been updated !', 'loginizer'); ?>");
626 }
627
628 // Throw an error for failures
629 }).fail(function() {
630 alert("<?php esc_html_e('Was unable to update the .htaccess file so please update it manually', 'loginizer'); ?>");
631 });
632
633 return false;
634
635 }
636
637 function lz_show_rewrite_rule(e){
638 event.preventDefault();
639 jQuery(e).closest('td').find('textarea').toggle();
640 }
641
642
643 </script>
644
645 <!-- Begin CSRF Protection -->
646 <form action="" method="post" loginizer-premium-only="1">
647 <div id="" class="postbox">
648
649 <div class="postbox-header">
650 <h2 class="hndle ui-sortable-handle">
651 <span><?php esc_html_e('CSRF Protection', 'loginizer'); ?></span>
652 </h2>
653 </div>
654
655 <div class="inside">
656
657 <?php wp_nonce_field('loginizer-options'); ?>
658 <table class="form-table">
659 <tr>
660 <td scope="row" valign="top" colspan="2">
661 <i><?php esc_html_e('This prevents CSRF attacks by adding a session string to admin URLs, making them nearly impossible for attackers to predict.', 'loginizer'); ?></i>
662 </td>
663 </tr>
664 <tr>
665 <td scope="row" valign="top" style="width:400px !important">
666 <label><?php esc_html_e('Enable CSRF Protection', 'loginizer'); ?></label><br>
667 <span class="exp"><?php esc_html_e('If enabled, it will update the URL of wp-admin with a random session string in the URL making it hard to predict the URL.', 'loginizer'); ?></span>
668 </td>
669 <td valign="top">
670 <input type="checkbox" value="1" name="enable_csrf_protection" <?php echo lz_POSTchecked('enable_csrf_protection', (empty($loginizer['enable_csrf_protection']) ? false : true)); ?> />
671 </td>
672 </tr>
673 <?php
674 loginizer_htaccess_rules(true);
675 ?>
676 </table><br />
677 <div style="text-align: center;"><input name="save_lz_csrf_protection" class="button button-primary action" value="<?php esc_html_e('Save Settings', 'loginizer'); ?>" type="submit" />
678 </div>
679 </div>
680 </div>
681 </form>
682 <!-- End CSRF Protection -->
683
684
685 <script type="text/javascript">
686
687 function lz_wp_admin_msg_toggle(){
688 var ele = jQuery('#lz_restrict_wp_admin')[0];
689 if(ele.checked){
690 jQuery('#lz_wp_admin_msg_row').show();
691 }else{
692 jQuery('#lz_wp_admin_msg_row').hide();
693 }
694 };
695
696 lz_wp_admin_msg_toggle();
697
698 </script>
699
700
701 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
702 <div id="" class="postbox">
703
704 <div class="postbox-header">
705 <h2 class="hndle ui-sortable-handle">
706 <span><?php echo __('Change Admin Username', 'loginizer'); ?></span>
707 </h2>
708 </div>
709
710 <div class="inside">
711
712 <?php wp_nonce_field('loginizer-options'); ?>
713 <table class="form-table">
714 <tr>
715 <td scope="row" valign="top" colspan="2">
716 <i><?php echo __('You can change the Admin Username from here to anything of your choice e.g. iamtheboss. This would make it very difficult for automated attack bots to know what is the admin username !', 'loginizer'); ?></i>
717 </td>
718 </tr>
719 <tr>
720 <td scope="row" valign="top" style="width:40% !important">
721 <label for="current_username"><?php echo __('Current Username', 'loginizer'); ?></label><br>
722 <span class="exp"><?php echo __('The current username you want to change', 'loginizer'); ?></span>
723 </td>
724 <td>
725 <input type="text" size="50" value="<?php echo lz_optpost('current_username', (!empty($current_admin->user_login) ? $current_admin->user_login : '')); ?>" name="current_username" id="current_username" />
726 </td>
727 </tr>
728 <tr>
729 <td scope="row" valign="top" style="width:40% !important">
730 <label for="new_username"><?php echo __('New Username', 'loginizer'); ?></label><br>
731 <span class="exp"><?php echo __('The new username you want to set', 'loginizer'); ?></span>
732 </td>
733 <td>
734 <input type="text" size="50" value="<?php echo lz_optpost('new_username', ''); ?>" name="new_username" id="new_username" />
735 </td>
736 </tr>
737 </table><br />
738 <i><?php echo __('Note: Username can be changed only for administrator users.', 'loginizer'); ?></i>
739 <center><input name="save_lz_admin" class="button button-primary action" value="<?php echo __('Set the Username', 'loginizer'); ?>" type="submit" /></center>
740
741 </div>
742 </div>
743 </form>
744
745 <script type="text/javascript">
746 function add_lz_bl_users(){
747 jQuery("#lz_bl_users").append('<input type="text" size="30" value="" name="lz_bl_users[]" class="lz_bl_users" />');
748 return false;
749 };
750 </script>
751
752 <style>
753 .lz_bl_users, .lz_bl_domains{
754 margin-bottom:20px;
755 }
756 </style>
757
758 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
759 <div id="" class="postbox">
760
761 <div class="postbox-header">
762 <h2 class="hndle ui-sortable-handle">
763 <span><?php echo __('Username Auto Blacklist', 'loginizer'); ?></span>
764 </h2>
765 </div>
766
767 <div class="inside">
768
769 <?php wp_nonce_field('loginizer-options'); ?>
770 <table class="form-table">
771 <tr>
772 <td scope="row" valign="top" colspan="2">
773 <i><?php echo __('Attackers generally use common usernames like <b>admin, administrator, or variations of your domain name / business name</b>. You can specify such username here and Loginizer will auto-blacklist the IP Address(s) of clients who try to use such username(s).', 'loginizer'); ?></i>
774 </td>
775 </tr>
776 <tr>
777 <td scope="row" valign="top" style="width:40% !important; vertical-align:top !important;">
778 <label><?php echo __('Username(s)', 'loginizer'); ?></label><br>
779 <span class="exp"><?php echo __('You can use - <b>*</b> (Star)- as a wild card as well. Blank fields will be ignored', 'loginizer'); ?></span>
780 </td>
781 <td>
782 <div id="lz_bl_users">
783 <?php
784
785 $usernames = isset($_POST['lz_bl_users']) && is_array($_POST['lz_bl_users']) ? $_POST['lz_bl_users'] : (!empty($loginizer['username_blacklist']) ? $loginizer['username_blacklist'] : []);
786
787 if(empty($usernames)){
788 $usernames = array();
789 $usernames[] = '';
790 }
791
792 foreach($usernames as $_user){
793
794 // Disallow these special characters to avoid XSS or any other security vulnerability
795 if(preg_match('/[\<\>\"\']/', $_user)){
796 continue;
797 }
798
799 echo '<input type="text" size="30" value="'.$_user.'" name="lz_bl_users[]" class="lz_bl_users" />';
800 }
801
802 ?>
803 </div>
804 <br />
805 <input class="button" type="button" value="<?php echo __('Add New Username', 'loginizer'); ?>" onclick="return add_lz_bl_users();" style="float:right" />
806 </td>
807 </tr>
808 </table><br />
809 <center><input name="save_lz_bl_users" class="button button-primary action" value="<?php echo __('Save Username(s)', 'loginizer'); ?>" type="submit" /></center>
810
811 </div>
812 </div>
813 </form>
814
815 <script type="text/javascript">
816 function add_lz_bl_domains(){
817 jQuery("#lz_bl_domains").append('<input type="text" size="30" value="" name="lz_bl_domains[]" class="lz_bl_domains" />');
818 return false;
819 };
820 </script>
821
822
823 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
824 <div id="" class="postbox">
825
826 <div class="postbox-header">
827 <h2 class="hndle ui-sortable-handle">
828 <span><?php echo __('New Registration Domain Blacklist', 'loginizer'); ?></span>
829 </h2>
830 </div>
831
832 <div class="inside">
833
834 <?php wp_nonce_field('loginizer-options'); ?>
835 <table class="form-table">
836 <tr>
837 <td scope="row" valign="top" colspan="2">
838 <i>If you would like to ban new registrations from a particular domain, you can use this utility to do so.</i>
839 </td>
840 </tr>
841 <tr>
842 <td scope="row" valign="top" style="width:40% !important; vertical-align:top !important;">
843 <label><?php echo __('Domain(s)', 'loginizer'); ?></label><br>
844 <span class="exp"><?php echo __('You can use - <b>*</b> (Star)- as a wild card as well. Blank fields will be ignored', 'loginizer'); ?></span>
845 </td>
846 <td>
847 <div id="lz_bl_domains">
848 <?php
849
850 $domains = isset($_POST['lz_bl_domains']) && is_array($_POST['lz_bl_domains']) ? $_POST['lz_bl_domains'] : (!empty($loginizer['domains_blacklist']) ? $loginizer['domains_blacklist'] : []);
851
852 if(empty($domains)){
853 $domains = array();
854 $domains[] = '';
855 }
856
857 foreach($domains as $_domain){
858
859 // Disallow these special characters to avoid XSS or any other security vulnerability
860 if(preg_match('/[\<\>\"\']/', $_domain)){
861 continue;
862 }
863
864 echo '<input type="text" size="30" value="'.$_domain.'" name="lz_bl_domains[]" class="lz_bl_domains" />';
865 }
866
867 ?>
868 </div>
869 <br />
870 <input class="button" type="button" value="<?php echo __('Add New Domain', 'loginizer'); ?>" onclick="return add_lz_bl_domains();" style="float:right" />
871 </td>
872 </tr>
873 </table><br />
874 <center><input name="save_lz_bl_domains" class="button button-primary action" value="<?php echo __('Save Domains(s)', 'loginizer'); ?>" type="submit" /></center>
875
876 </div>
877 </div>
878 </form>
879
880 <form action="" method="post" enctype="multipart/form-data" loginizer-premium-only="1">
881 <div id="" class="postbox">
882
883 <div class="postbox-header">
884 <h2 class="hndle ui-sortable-handle">
885 <span><?php echo __('Limit Concurrent Sessions', 'loginizer'); ?>
886 </h2>
887 </div>
888
889 <div class="inside">
890
891 <?php wp_nonce_field('loginizer-options'); ?>
892 <table class="form-table">
893 <tr>
894 <td scope="row" valign="top" colspan="2">
895 <i><?php echo __('This feature will help limit the number of devices your user can login to concurrently', 'loginizer'); ?></i>
896 </td>
897 </tr>
898 <tr>
899 <td scope="row" valign="top" style="width:300px !important">
900 <label><?php echo __('Enable', 'loginizer'); ?></label><br>
901 <span class="exp"><?php echo __('Enabling it will start limiting number of devices the user can login on concurrently', 'loginizer'); ?></span>
902 </td>
903 <td>
904 <input type="checkbox" value="1" name="limit_session[enable]" <?php echo (!empty($_POST['limit_session']['enable']) || (!empty($loginizer['limit_session']['enable']))) ? 'checked' : false; ?> />
905 </td>
906 </tr>
907 <tr>
908 <td scope="row" valign="top" style="width:300px !important">
909 <label><?php echo __('Limit Type', 'loginizer'); ?></label><br>
910 </td>
911 <td>
912 <input type="radio" value="block" name="limit_session[type]" <?php echo ((!empty($_POST['limit_session']['type']) && $_POST['limit_session']['type'] == 'block') || (!empty($loginizer['limit_session']['type']) && $loginizer['limit_session']['type'] == 'block' ) ? 'checked' : false); ?> />
913 <span class="exp"><?php echo '<strong>'.__('Block', 'loginizer') . ' : </strong>' . __('Blocks all the login attempts if limit is reached', 'loginizer'); ?></span><br/>
914 <input type="radio" value="destroy" name="limit_session[type]" <?php echo ((!empty($_POST['limit_session']['type']) && $_POST['limit_session']['type'] == 'destroy') || (!empty($loginizer['limit_session']['type']) && $loginizer['limit_session']['type'] == 'destroy' ) ? 'checked' : false); ?> />
915 <span class="exp"><?php echo '<strong>'.__('Destroy', 'loginizer') . ' : </strong>' . __('Revokes all the sessions on successful login', 'loginizer'); ?></span>
916 </td>
917 </tr>
918 <tr>
919 <td scope="row" valign="top" style="width:40% !important">
920 <label><?php echo __('Max Session Count', 'loginizer'); ?></label><br>
921 <span class="exp"><?php echo __('Set Maximum number of sessions can be created', 'loginizer'); ?></span>
922 </td>
923 <td>
924 <input type="number" min="1" max="10" size="20" value="<?php echo (!empty($_POST['limit_session']['count']) ? esc_attr($_POST['limit_session']['count']) : (!empty($loginizer['limit_session']['count']) ? esc_attr($loginizer['limit_session']['count']) : 1)); ?>" name="limit_session[count]" />
925 </td>
926 </tr>
927 <tr>
928 <tr>
929 <td scope="row" valign="top">
930 <label><?php echo __('Exclude Roles', 'loginizer'); ?></label><br>
931 <span class="exp"><?php echo __('Excluded roles won\'t face session limit checks', 'loginizer'); ?></span>
932 </td>
933 <td>
934 <div style="max-height:120px;; overflow-y:auto;">
935 <?php
936 global $wp_roles;
937
938 foreach($wp_roles->roles as $key => $role){
939 $checked = '';
940
941 if(!empty($_POST['limit_session']['roles']) && in_array($key, $_POST['limit_session']['roles'])
942 || !empty($loginizer['limit_session']['roles']) && in_array($key, $loginizer['limit_session']['roles'])){
943 $checked = 'checked';
944 }
945
946
947 echo '<input type="checkbox" value="'.esc_attr($key).'" name="limit_session[roles][]" '.esc_attr($checked).'/>'. esc_html($role['name']) . '<br/>';
948 }
949 ?>
950 </div>
951 </td>
952 </tr>
953 </table><br/>
954 <center><input name="save_lz_limit_session" class="button button-primary action" value="<?php echo __('Save Settings', 'loginizer'); ?>" type="submit" /></center>
955
956 </div>
957 </div>
958 </form>
959
960 <?php
961
962 }
963
964 loginizer_page_footer();
965
966 }
967
968 // .htaccess UI options for wp-admin and CSRF
969 function loginizer_htaccess_rules($is_csrf = false){
970 global $loginizer;
971
972 $admin_slug = 'wp-admin';
973
974 if(!empty($loginizer['admin_slug'])){
975 $admin_slug = $loginizer['admin_slug'];
976 }
977
978 // getting sub directory if any
979 $home_root = parse_url(home_url());
980
981 if(isset($home_root['path'])){
982 $home_root = trailingslashit($home_root['path']);
983 } else {
984 $home_root = '/';
985 }
986
987 // Selecting admin slug
988 $admin_slug = 'wp-admin';
989
990 if(!empty($loginizer['admin_slug'])){
991 $admin_slug = $loginizer['admin_slug'];
992 }
993
994 // Setting the rule
995 $rule = '# BEGIN Loginizer' . "\n";
996 $rule .= '<IfModule mod_rewrite.c>' . "\n";
997 $rule .= 'RewriteEngine On' . "\n";
998 $rule .= 'RewriteBase ' . $home_root . "\n\n";
999 $rule .= 'RewriteRule ^(' . preg_quote($admin_slug, '/') . '(-lzs.{20})?)$ $1/ [R=301,L]' . "\n";
1000 $rule .= 'RewriteRule ^' . $admin_slug . '(-lzs.{20})?(/?)(.*) wp-admin/$3 [L]' . "\n";
1001 $rule .= '</IfModule>' . "\n";
1002 $rule .= '# END Loginizer' . "\n";
1003
1004 if(is_writable(ABSPATH . '/.htaccess')){
1005 echo '<tr>
1006 <td scope="row" valign="top" style="width:400px !important">
1007 <label>'. esc_html__('Update .htaccess', 'loginizer').'</label><br>
1008 <span class="exp">'. (!empty($is_csrf) ? esc_html__('Rewrites rule for CSRF session URL', 'loginizer') : esc_html__('Rewrites rule to change wp-admin and if you have a Multisite then check', 'loginizer') . ' <a href="'.LOGINIZER_DOCS.'Renaming_the_WP-Admin_Area" target="_blank">our guide</a>') . '</span>
1009 </td>
1010 <td valign="top">
1011 <button class="button" style="background: #5cb85c; color:white; border:#5cb85c;" onclick="lz_csrf_htaccess_update(this)">Update .htaccess</button><a onClick="lz_show_rewrite_rule(this)" href="#" style="margin-left:5px; line-height: 2; font-weight:500;">Show Rewrite Rule</a><br/><br/>
1012
1013 <textarea rows="8" readonly style="display:none;" class="lz-htaccess-textarea">' . trim($rule) . '</textarea>
1014 </td>
1015 </tr>';
1016
1017 } else {
1018 echo '<tr>
1019 <td scope="row" valign="top" style="width:400px !important">
1020 <label>'. esc_html__('Manually Update .htaccess', 'loginizer') . '</label><br>
1021 <span class="exp">' . esc_html__('You can manually update your .htaccess by adding the given code at the top of your .htaccess file', 'loginizer'). '</span>
1022 </td>
1023 <td valign="top">
1024 <textarea rows="8" readonly class="lz-htaccess-textarea">' . trim($rule) . '</textarea>
1025 </td>
1026 </tr>';
1027 }
1028
1029 }