Version Description
- Premium Feature: Password Auditing. Audit the strength of your admin and user-level passwords against our GPU based auditing cluster. Easily alert users to weak passwords or force a password change.
- Feature: Activity email summary. See options page to enable a weekly, bi-weekly or monthly activity summary.
- Feature: Activity summary dashboard widget.
- Fix: Fixed bug on plugin activation where the configuration table was being queried before it was created.
- Improvement: Added .htaccess to wfcache directory.
- Improvement: Switched to using wp_remote_post for Wordfence cloud API calls to improved SSL support and a more standards based approach.
Download this release
Release Info
Developer | mmaunder |
Plugin | Wordfence Security – Firewall & Malware Scan |
Version | 5.3.9 |
Comparing to | |
See all releases |
Code changes from version 5.3.8 to 5.3.9
- css/activity-report-widget.css +90 -0
- css/main.css +60 -31
- js/admin.js +1864 -1592
- lib/email_passwdChanged.php +23 -0
- lib/email_pleaseChangePasswd.php +23 -0
- lib/menu_countryBlocking.php +3 -3
- lib/menu_options.php +47 -2
- lib/menu_passwd.php +186 -0
- lib/wfAPI.php +69 -148
- lib/wfActivityReport.php +462 -0
- lib/wfCache.php +23 -1
- lib/wfConfig.php +43 -11
- lib/wfCrypt.php +46 -0
- lib/wfDirectoryIterator.php +74 -0
- lib/wfHelperString.php +22 -0
- lib/wfLog.php +3 -0
- lib/wfScanEngine.php +4 -0
- lib/wfSchema.php +7 -0
- lib/wfUpdateCheck.php +133 -0
- lib/wfView.php +127 -0
- lib/wordfenceClass.php +349 -95
- lib/wordfenceConstants.php +1 -1
- readme.txt +10 -1
- views/reports/activity-report-email-inline.php +330 -0
- views/reports/activity-report-email.php +465 -0
- views/reports/activity-report.php +195 -0
- wordfence.php +2 -2
css/activity-report-widget.css
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#wordfence_activity_report_widget .inside h1,
|
2 |
+
#wordfence_activity_report_widget .inside h2,
|
3 |
+
#wordfence_activity_report_widget .inside h3,
|
4 |
+
#wordfence_activity_report_widget .inside h4 {
|
5 |
+
margin: 20px 0 4px;
|
6 |
+
color: #222 !important;
|
7 |
+
}
|
8 |
+
|
9 |
+
#wordfence_activity_report_widget .inside h1 {
|
10 |
+
float: right;
|
11 |
+
text-align: right;
|
12 |
+
font-size: 30px;
|
13 |
+
color: #444444 !important;
|
14 |
+
line-height: 1.1;
|
15 |
+
}
|
16 |
+
|
17 |
+
#wordfence_activity_report_widget .inside h2 {
|
18 |
+
font-size: 20px;
|
19 |
+
}
|
20 |
+
|
21 |
+
#wordfence_activity_report_widget .inside h4 {
|
22 |
+
font-size: 16px;
|
23 |
+
color: #666666 !important;
|
24 |
+
}
|
25 |
+
|
26 |
+
#wordfence_activity_report_widget .inside code {
|
27 |
+
background-color: transparent;
|
28 |
+
}
|
29 |
+
|
30 |
+
#wordfence_activity_report_widget table.wf-table {
|
31 |
+
width: 100%;
|
32 |
+
max-width: 100%;
|
33 |
+
border-collapse: collapse;
|
34 |
+
}
|
35 |
+
|
36 |
+
#wordfence_activity_report_widget table.wf-table th,
|
37 |
+
#wordfence_activity_report_widget table.wf-table td {
|
38 |
+
text-align: left;
|
39 |
+
padding: 6px 4px;
|
40 |
+
border: 1px solid #cccccc;
|
41 |
+
}
|
42 |
+
|
43 |
+
#wordfence_activity_report_widget table.wf-table thead th,
|
44 |
+
#wordfence_activity_report_widget table.wf-table thead td {
|
45 |
+
background-color: #222;
|
46 |
+
color: #FFFFFF;
|
47 |
+
font-weight: bold;
|
48 |
+
border-color: #474747;
|
49 |
+
}
|
50 |
+
|
51 |
+
#wordfence_activity_report_widget table.wf-table tbody tr.even td {
|
52 |
+
background-color: #eeeeee;
|
53 |
+
}
|
54 |
+
|
55 |
+
#wordfence_activity_report_widget .loginFailValidUsername {
|
56 |
+
color: #00c000;
|
57 |
+
font-weight: bold;
|
58 |
+
}
|
59 |
+
|
60 |
+
#wordfence_activity_report_widget .loginFailInvalidUsername {
|
61 |
+
color: #e74a2a;
|
62 |
+
font-weight: bold;
|
63 |
+
}
|
64 |
+
|
65 |
+
#wordfence_activity_report_widget .display-file-table-cell {
|
66 |
+
overflow: hidden;
|
67 |
+
}
|
68 |
+
|
69 |
+
#wordfence_activity_report_widget .display-file {
|
70 |
+
margin: 0px;
|
71 |
+
display: block;
|
72 |
+
font-size: 12px;
|
73 |
+
width: 100%;
|
74 |
+
overflow: auto;
|
75 |
+
white-space: nowrap;
|
76 |
+
}
|
77 |
+
|
78 |
+
#wordfence_activity_report_widget .recently-modified-files {
|
79 |
+
table-layout: fixed;
|
80 |
+
}
|
81 |
+
|
82 |
+
#wordfence_activity_report_widget .recently-modified-files th:nth-child(1),
|
83 |
+
#wordfence_activity_report_widget .recently-modified-files td:nth-child(1) {
|
84 |
+
width: 30%;
|
85 |
+
}
|
86 |
+
|
87 |
+
#wordfence_activity_report_widget .recently-modified-files th:nth-child(2),
|
88 |
+
#wordfence_activity_report_widget .recently-modified-files td:nth-child(2) {
|
89 |
+
width: 70%;
|
90 |
+
}
|
css/main.css
CHANGED
@@ -142,8 +142,8 @@ div.wordfenceScanButton input.button-wf-grey {
|
|
142 |
}
|
143 |
table.wfSummaryParent { font-family: sans-serif; font-size: 14px; color: #000; z-index: 9;}
|
144 |
table.wfSummaryParent td { vertical-align: top; padding: 0; margin: 0; }
|
145 |
-
table.wfSummaryParent table.wfSummaryChild th { font-weight: bold; text-align: right; font-family: Georgia, serif; color: #000; padding: 5px 10px 5px 0; border-top: 1px solid #CCC; }
|
146 |
-
table.wfSummaryParent table.wfSummaryChild td { font-weight: normal; text-align: left; padding: 5px 0 5px 0; border-top: 1px solid #CCC; }
|
147 |
table.wfSummaryParent table.wfSC1 td { width: 300px; padding: 0px 25px 10px 0; }
|
148 |
table.wfSummaryParent table.wfSC2 th { width: 80px; }
|
149 |
table.wfSummaryParent table.wfSC2 td { width: 100px; }
|
@@ -155,8 +155,8 @@ div.wfIssue table.wfIssue td { padding: 2px; margin: 0; border-width: 0px; text-
|
|
155 |
div.wfIssue table.wfIssue th { padding: 2px; margin: 0; font-weight: bold; text-align: left; color: #777; }
|
156 |
div.wfIssue h2 { margin: 0px 0 5px 0; padding: 0; }
|
157 |
div.wfIssue table.wfIssueLinks td { border-width: 0px; text-align: left; padding-right: 10px; }
|
158 |
-
.wfIssueOptions {
|
159 |
-
border-top: 1px solid #CCC;
|
160 |
padding: 10px;
|
161 |
}
|
162 |
.wfIssueOptions a {
|
@@ -241,11 +241,11 @@ h3.wfConfigHeading {
|
|
241 |
width: 800px;
|
242 |
}
|
243 |
.consoleHeadText {
|
244 |
-
font-size: 18px;
|
245 |
-
font-family: Georgia, serif;
|
246 |
-
font-style: italic;
|
247 |
-
color: #555;
|
248 |
-
font-weight: bold;
|
249 |
-webkit-font-smoothing: antialiased;
|
250 |
|
251 |
}
|
@@ -253,7 +253,7 @@ h3.wfConfigHeading {
|
|
253 |
.consoleInner { height: 116px; overflow: auto; z-index: 1; }
|
254 |
.bevelDiv1 { border: 1px solid #EFEFEF; }
|
255 |
.bevelDiv2 { border: 1px solid #AAA; }
|
256 |
-
.bevelDiv3 { border: 1px solid #555;
|
257 |
background-color: #FFFFE0; /* #FFFFF0; /* #FFEBCD; #FFFACD; */
|
258 |
color: #000; padding: 5px; font-family: Arial; -webkit-font-smoothing: none; }
|
259 |
|
@@ -276,9 +276,9 @@ h3.wfConfigHeading {
|
|
276 |
clear: both;
|
277 |
visibility: hidden;
|
278 |
}
|
279 |
-
.wfSummaryFinal {
|
280 |
-webkit-font-smoothing: antialiased;
|
281 |
-
font-weight: bold;
|
282 |
color: #555;
|
283 |
}
|
284 |
input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
@@ -287,16 +287,16 @@ input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
|
287 |
}
|
288 |
#wordfenceWorking {
|
289 |
padding: 2px 8px 2px 24px;
|
290 |
-
z-index: 100000;
|
291 |
-
position: fixed;
|
292 |
-
right: 2px;
|
293 |
-
bottom: 2px;
|
294 |
-
border: 1px solid #000;
|
295 |
-
background-color: #F00;
|
296 |
-
color: #FFF;
|
297 |
-
font-size: 12px;
|
298 |
-
font-weight: bold;
|
299 |
-
font-family: Arial;
|
300 |
text-align: center;
|
301 |
background-image: url('../images/icons/ajaxRed16.gif');
|
302 |
background-position: 2px 2px;
|
@@ -322,10 +322,10 @@ input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
|
322 |
width: 1px;
|
323 |
}
|
324 |
.wfPaidOnlyNotice {
|
325 |
-
width: 500px;
|
326 |
-
background-color: #FFFFE0;
|
327 |
-
border: 1px solid #000;
|
328 |
-
padding: 10px;
|
329 |
margin: 20px;
|
330 |
}
|
331 |
.wfFalconNotice {
|
@@ -415,10 +415,10 @@ input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
|
415 |
border: 2px solid #999999 !important ; border-radius: 19px !important ;
|
416 |
position: absolute !important ; top: 0 !important ; bottom: 0 !important ; right: 46px !important ;
|
417 |
-moz-transition: all 0.3s ease-in 0s !important ; -webkit-transition: all 0.3s ease-in 0s !important ;
|
418 |
-
-o-transition: all 0.3s ease-in 0s !important ; transition: all 0.3s ease-in 0s !important ;
|
419 |
-
background-image: -moz-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
420 |
-
background-image: -webkit-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
421 |
-
background-image: -o-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
422 |
background-image: linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
423 |
box-shadow: 0 1px 1px white inset !important ;
|
424 |
}
|
@@ -426,9 +426,38 @@ input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
|
426 |
margin-left: 0 !important ;
|
427 |
}
|
428 |
.wfOnOffSwitch-checkbox:checked + .wfOnOffSwitch-label .wfOnOffSwitch-switch {
|
429 |
-
right: 0px !important ;
|
430 |
}
|
431 |
#wordfenceConfigWarning {
|
432 |
clear: left;
|
433 |
margin-top: 5px;
|
434 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
}
|
143 |
table.wfSummaryParent { font-family: sans-serif; font-size: 14px; color: #000; z-index: 9;}
|
144 |
table.wfSummaryParent td { vertical-align: top; padding: 0; margin: 0; }
|
145 |
+
table.wfSummaryParent table.wfSummaryChild th { font-weight: bold; text-align: right; font-family: Georgia, serif; color: #000; padding: 5px 10px 5px 0; border-top: 1px solid #CCC; }
|
146 |
+
table.wfSummaryParent table.wfSummaryChild td { font-weight: normal; text-align: left; padding: 5px 0 5px 0; border-top: 1px solid #CCC; }
|
147 |
table.wfSummaryParent table.wfSC1 td { width: 300px; padding: 0px 25px 10px 0; }
|
148 |
table.wfSummaryParent table.wfSC2 th { width: 80px; }
|
149 |
table.wfSummaryParent table.wfSC2 td { width: 100px; }
|
155 |
div.wfIssue table.wfIssue th { padding: 2px; margin: 0; font-weight: bold; text-align: left; color: #777; }
|
156 |
div.wfIssue h2 { margin: 0px 0 5px 0; padding: 0; }
|
157 |
div.wfIssue table.wfIssueLinks td { border-width: 0px; text-align: left; padding-right: 10px; }
|
158 |
+
.wfIssueOptions {
|
159 |
+
border-top: 1px solid #CCC;
|
160 |
padding: 10px;
|
161 |
}
|
162 |
.wfIssueOptions a {
|
241 |
width: 800px;
|
242 |
}
|
243 |
.consoleHeadText {
|
244 |
+
font-size: 18px;
|
245 |
+
font-family: Georgia, serif;
|
246 |
+
font-style: italic;
|
247 |
+
color: #555;
|
248 |
+
font-weight: bold;
|
249 |
-webkit-font-smoothing: antialiased;
|
250 |
|
251 |
}
|
253 |
.consoleInner { height: 116px; overflow: auto; z-index: 1; }
|
254 |
.bevelDiv1 { border: 1px solid #EFEFEF; }
|
255 |
.bevelDiv2 { border: 1px solid #AAA; }
|
256 |
+
.bevelDiv3 { border: 1px solid #555;
|
257 |
background-color: #FFFFE0; /* #FFFFF0; /* #FFEBCD; #FFFACD; */
|
258 |
color: #000; padding: 5px; font-family: Arial; -webkit-font-smoothing: none; }
|
259 |
|
276 |
clear: both;
|
277 |
visibility: hidden;
|
278 |
}
|
279 |
+
.wfSummaryFinal {
|
280 |
-webkit-font-smoothing: antialiased;
|
281 |
+
font-weight: bold;
|
282 |
color: #555;
|
283 |
}
|
284 |
input.wfStartScanButton { width: 160px; text-align: left; padding-left: 20px; }
|
287 |
}
|
288 |
#wordfenceWorking {
|
289 |
padding: 2px 8px 2px 24px;
|
290 |
+
z-index: 100000;
|
291 |
+
position: fixed;
|
292 |
+
right: 2px;
|
293 |
+
bottom: 2px;
|
294 |
+
border: 1px solid #000;
|
295 |
+
background-color: #F00;
|
296 |
+
color: #FFF;
|
297 |
+
font-size: 12px;
|
298 |
+
font-weight: bold;
|
299 |
+
font-family: Arial;
|
300 |
text-align: center;
|
301 |
background-image: url('../images/icons/ajaxRed16.gif');
|
302 |
background-position: 2px 2px;
|
322 |
width: 1px;
|
323 |
}
|
324 |
.wfPaidOnlyNotice {
|
325 |
+
width: 500px;
|
326 |
+
background-color: #FFFFE0;
|
327 |
+
border: 1px solid #000;
|
328 |
+
padding: 10px;
|
329 |
margin: 20px;
|
330 |
}
|
331 |
.wfFalconNotice {
|
415 |
border: 2px solid #999999 !important ; border-radius: 19px !important ;
|
416 |
position: absolute !important ; top: 0 !important ; bottom: 0 !important ; right: 46px !important ;
|
417 |
-moz-transition: all 0.3s ease-in 0s !important ; -webkit-transition: all 0.3s ease-in 0s !important ;
|
418 |
+
-o-transition: all 0.3s ease-in 0s !important ; transition: all 0.3s ease-in 0s !important ;
|
419 |
+
background-image: -moz-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
420 |
+
background-image: -webkit-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
421 |
+
background-image: -o-linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
422 |
background-image: linear-gradient(center top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0) 80%) !important ;
|
423 |
box-shadow: 0 1px 1px white inset !important ;
|
424 |
}
|
426 |
margin-left: 0 !important ;
|
427 |
}
|
428 |
.wfOnOffSwitch-checkbox:checked + .wfOnOffSwitch-label .wfOnOffSwitch-switch {
|
429 |
+
right: 0px !important ;
|
430 |
}
|
431 |
#wordfenceConfigWarning {
|
432 |
clear: left;
|
433 |
margin-top: 5px;
|
434 |
}
|
435 |
+
|
436 |
+
table.wf-table {
|
437 |
+
width: 100%;
|
438 |
+
max-width: 100%;
|
439 |
+
border-collapse: collapse;
|
440 |
+
}
|
441 |
+
table.wf-table th,
|
442 |
+
table.wf-table td {
|
443 |
+
padding: 6px 4px;
|
444 |
+
border: 1px solid #ccc;
|
445 |
+
}
|
446 |
+
table.wf-table thead th,
|
447 |
+
table.wf-table thead td {
|
448 |
+
background-color: #222;
|
449 |
+
color: #fff;
|
450 |
+
font-weight: bold;
|
451 |
+
border-color: #474747;
|
452 |
+
text-align: left;
|
453 |
+
}
|
454 |
+
table.wf-table tbody tr td {
|
455 |
+
background-color: #fff;
|
456 |
+
}
|
457 |
+
table.wf-table tbody tr.even td,
|
458 |
+
table.wf-table tbody tr:nth-child(2n) td {
|
459 |
+
background-color: #eee;
|
460 |
+
}
|
461 |
+
table.wf-table tbody tr:hover td {
|
462 |
+
background-color: #fffbd8;
|
463 |
+
}
|
js/admin.js
CHANGED
@@ -1,1641 +1,1913 @@
|
|
1 |
-
|
2 |
-
window['wordfenceAdmin'] =
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
});
|
92 |
});
|
93 |
});
|
94 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
});
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
}
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
this.
|
124 |
-
}
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
self
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
});
|
213 |
-
});
|
214 |
-
},
|
215 |
-
tourRedir: function(menuItem){
|
216 |
-
window.location.href = 'admin.php?page=' + menuItem;
|
217 |
-
},
|
218 |
-
updateConfig: function(key, val, cb){
|
219 |
-
this.ajax('wordfence_updateConfig', { key: key, val: val }, function(){ cb(); });
|
220 |
-
},
|
221 |
-
tourFinish: function(){
|
222 |
-
this.ajax('wordfence_tourClosed', {}, function(res){});
|
223 |
-
},
|
224 |
-
downgradeLicense: function(){
|
225 |
-
this.colorbox('400px', "Confirm Downgrade", "Are you sure you want to downgrade your Wordfence Premium License? This will disable all Premium features and return you to the free version of Wordfence. <a href=\"https://www.wordfence.com/manage-wordfence-api-keys/\" target=\"_blank\">Click here to renew your paid membership</a> or click the button below to confirm you want to downgrade.<br /><br /><input type=\"button\" value=\"Downgrade and disable Premium features\" onclick=\"WFAD.downgradeLicenseConfirm();\" /><br />");
|
226 |
-
},
|
227 |
-
downgradeLicenseConfirm: function(){
|
228 |
-
jQuery.colorbox.close();
|
229 |
-
this.ajax('wordfence_downgradeLicense', {}, function(res){ location.reload(true); });
|
230 |
-
},
|
231 |
-
tour: function(contentID, elemID, edge, align, buttonLabel, buttonCallback){
|
232 |
-
var self = this;
|
233 |
-
if(this.currentPointer){
|
234 |
-
this.currentPointer.pointer('destroy');
|
235 |
-
this.currentPointer = false;
|
236 |
-
}
|
237 |
-
var options = {
|
238 |
-
buttons: function(event, t){
|
239 |
-
var buttonElem = jQuery('<div id="wfTourButCont"><a id="pointer-close" style="margin-left:5px" class="button-secondary">End the Tour</a></div><div><a id="wfRateLink" href="http://wordpress.org/extend/plugins/wordfence/" target="_blank" style="font-size: 10px; font-family: Verdana;">Help spread the word by rating us 5★ on WordPress.org</a></div>');
|
240 |
-
buttonElem.find('#pointer-close').bind('click.pointer', function (evtObj) {
|
241 |
-
var evtSourceElem = evtObj.srcElement ? evtObj.srcElement : evtObj.target;
|
242 |
-
if(evtSourceElem.id == 'wfRateLink'){
|
243 |
-
return true;
|
244 |
-
}
|
245 |
-
self.tourFinish();
|
246 |
-
t.element.pointer('close');
|
247 |
-
return false;
|
248 |
-
});
|
249 |
-
return buttonElem;
|
250 |
-
},
|
251 |
-
close: function(){},
|
252 |
-
content: jQuery('#' + contentID).tmpl().html(),
|
253 |
-
pointerWidth: 400,
|
254 |
-
position: {
|
255 |
-
edge: edge,
|
256 |
-
align: align
|
257 |
-
}
|
258 |
-
};
|
259 |
-
this.currentPointer = jQuery('#' + elemID).pointer(options).pointer('open');
|
260 |
-
if(buttonLabel && buttonCallback){
|
261 |
-
jQuery('#pointer-close').after('<a id="pointer-primary" class="button-primary">' + buttonLabel + '</a>');
|
262 |
-
jQuery('#pointer-primary').click(buttonCallback);
|
263 |
-
}
|
264 |
-
},
|
265 |
-
startTourAgain: function(){
|
266 |
-
var self = this;
|
267 |
-
this.ajax('wordfence_startTourAgain', {}, function(res){
|
268 |
-
self.tourClosed = false;
|
269 |
-
self.scanTourStart();
|
270 |
-
});
|
271 |
-
},
|
272 |
-
showLoading: function(){
|
273 |
-
this.loadingCount++;
|
274 |
-
if(this.loadingCount == 1){
|
275 |
-
jQuery('<div id="wordfenceWorking">Wordfence is working...</div>').appendTo('body');
|
276 |
-
}
|
277 |
-
},
|
278 |
-
removeLoading: function(){
|
279 |
-
this.loadingCount--;
|
280 |
-
if(this.loadingCount == 0){
|
281 |
-
jQuery('#wordfenceWorking').remove();
|
282 |
-
}
|
283 |
-
},
|
284 |
-
startActivityLogUpdates: function(){
|
285 |
-
var self = this;
|
286 |
-
setInterval(function(){
|
287 |
-
self.updateActivityLog();
|
288 |
-
}, parseInt(WordfenceAdminVars.actUpdateInterval));
|
289 |
-
},
|
290 |
-
updateActivityLog: function(){
|
291 |
-
if(this.activityLogUpdatePending){
|
292 |
-
return;
|
293 |
-
}
|
294 |
-
this.activityLogUpdatePending = true;
|
295 |
-
var self = this;
|
296 |
-
this.ajax('wordfence_activityLogUpdate', {
|
297 |
-
lastctime: this.lastALogCtime
|
298 |
-
}, function(res){ self.doneUpdateActivityLog(res); }, function(){ self.activityLogUpdatePending = false; }, true);
|
299 |
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
this.processActQueue(res.currentScanID);
|
308 |
-
}
|
309 |
-
}
|
310 |
-
this.activityLogUpdatePending = false;
|
311 |
-
},
|
312 |
-
processActQueue: function(currentScanID){
|
313 |
-
if(this.activityQueue.length > 0){
|
314 |
-
this.addActItem(this.activityQueue.shift());
|
315 |
-
this.totalActAdded++;
|
316 |
-
if(this.totalActAdded > this.maxActivityLogItems){
|
317 |
-
jQuery('#consoleActivity div:first').remove();
|
318 |
-
this.totalActAdded--;
|
319 |
-
}
|
320 |
-
var timeTillNextUpdate = this.actNextUpdateAt - (new Date()).getTime();
|
321 |
-
var maxRate = 50 / 1000; //Rate per millisecond
|
322 |
-
var bulkTotal = 0;
|
323 |
-
while(this.activityQueue.length > 0 && this.activityQueue.length / timeTillNextUpdate > maxRate ){
|
324 |
-
var item = this.activityQueue.shift();
|
325 |
-
if(item){
|
326 |
-
bulkTotal++;
|
327 |
-
this.addActItem(item);
|
328 |
}
|
329 |
-
}
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
jQuery('#wfStartingScan').addClass('wfSummaryOK').html('Done.');
|
360 |
-
} else if(this.debugOn || item.level < 4){
|
361 |
-
|
362 |
-
var html = '<div class="wfActivityLine';
|
363 |
-
if(this.debugOn){
|
364 |
-
html += ' wf' + item.type;
|
365 |
-
}
|
366 |
-
html += '">[' + item.date + '] ' + item.msg + '</div>';
|
367 |
-
jQuery('#consoleActivity').append(html);
|
368 |
-
if(/Scan complete\./i.test(item.msg)){
|
369 |
-
this.loadIssues();
|
370 |
-
}
|
371 |
-
}
|
372 |
-
},
|
373 |
-
processSummaryLine: function(item){
|
374 |
-
var msg, summaryUpdated;
|
375 |
-
if(item.msg.indexOf('SUM_START:') != -1){
|
376 |
-
msg = item.msg.replace('SUM_START:', '');
|
377 |
-
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
|
378 |
-
summaryUpdated = true;
|
379 |
-
} else if(item.msg.indexOf('SUM_ENDBAD') != -1){
|
380 |
-
msg = item.msg.replace('SUM_ENDBAD:', '');
|
381 |
-
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryBad').html('Problems found.');
|
382 |
-
summaryUpdated = true;
|
383 |
-
} else if(item.msg.indexOf('SUM_ENDFAILED') != -1){
|
384 |
-
msg = item.msg.replace('SUM_ENDFAILED:', '');
|
385 |
-
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryBad').html('Failed.');
|
386 |
-
summaryUpdated = true;
|
387 |
-
} else if(item.msg.indexOf('SUM_ENDOK') != -1){
|
388 |
-
msg = item.msg.replace('SUM_ENDOK:', '');
|
389 |
-
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryOK').html('Secure.');
|
390 |
-
summaryUpdated = true;
|
391 |
-
} else if(item.msg.indexOf('SUM_ENDSUCCESS') != -1){
|
392 |
-
msg = item.msg.replace('SUM_ENDSUCCESS:', '');
|
393 |
-
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryOK').html('Success.');
|
394 |
-
summaryUpdated = true;
|
395 |
-
} else if(item.msg.indexOf('SUM_ENDERR') != -1){
|
396 |
-
msg = item.msg.replace('SUM_ENDERR:', '');
|
397 |
-
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryErr').html('An error occurred.');
|
398 |
-
summaryUpdated = true;
|
399 |
-
} else if(item.msg.indexOf('SUM_DISABLED:') != -1){
|
400 |
-
msg = item.msg.replace('SUM_DISABLED:', '');
|
401 |
-
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult">Disabled [<a href="admin.php?page=WordfenceSecOpt">Visit Options to Enable</a>]</div><div class="wfClear"></div>');
|
402 |
-
summaryUpdated = true;
|
403 |
-
} else if(item.msg.indexOf('SUM_PAIDONLY:') != -1){
|
404 |
-
msg = item.msg.replace('SUM_PAIDONLY:', '');
|
405 |
-
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Paid Members Only</a></div><div class="wfClear"></div>');
|
406 |
-
summaryUpdated = true;
|
407 |
-
} else if(item.msg.indexOf('SUM_FINAL:') != -1){
|
408 |
-
msg = item.msg.replace('SUM_FINAL:', '');
|
409 |
-
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg wfSummaryFinal">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
|
410 |
-
} else if(item.msg.indexOf('SUM_PREP:') != -1){
|
411 |
-
msg = item.msg.replace('SUM_PREP:', '');
|
412 |
-
jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult" id="wfStartingScan"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
|
413 |
-
} else if(item.msg.indexOf('SUM_KILLED:') != -1){
|
414 |
-
msg = item.msg.replace('SUM_KILLED:', '');
|
415 |
-
jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
|
416 |
-
}
|
417 |
-
},
|
418 |
-
processActQueueItem: function(){
|
419 |
-
var item = this.activityQueue.shift();
|
420 |
-
if(item){
|
421 |
-
jQuery('#consoleActivity').append('<div class="wfActivityLine wf' + item.type + '">[' + item.date + '] ' + item.msg + '</div>');
|
422 |
-
this.totalActAdded++;
|
423 |
-
if(this.totalActAdded > this.maxActivityLogItems){
|
424 |
-
jQuery('#consoleActivity div:first').remove();
|
425 |
-
this.totalActAdded--;
|
426 |
-
}
|
427 |
-
if(item.msg == 'Scan complete.'){
|
428 |
-
this.loadIssues();
|
429 |
-
}
|
430 |
-
}
|
431 |
-
},
|
432 |
-
updateTicker: function(forceUpdate){
|
433 |
-
if( (! forceUpdate) && this.tickerUpdatePending){
|
434 |
-
return;
|
435 |
-
}
|
436 |
-
this.tickerUpdatePending = true;
|
437 |
-
var self = this;
|
438 |
-
var alsoGet = '';
|
439 |
-
var otherParams = '';
|
440 |
-
if(this.mode == 'activity' && /^(?:404|hit|human|ruser|gCrawler|crawler|loginLogout)$/.test(this.activityMode)){
|
441 |
-
alsoGet = 'logList_' + this.activityMode;
|
442 |
-
otherParams = this.newestActivityTime;
|
443 |
-
} else if(this.mode == 'perfStats'){
|
444 |
-
alsoGet = 'perfStats';
|
445 |
-
otherParams = this.newestActivityTime;
|
446 |
-
}
|
447 |
-
this.ajax('wordfence_ticker', {
|
448 |
-
alsoGet: alsoGet,
|
449 |
-
otherParams: otherParams
|
450 |
-
}, function(res){ self.handleTickerReturn(res); }, function(){ self.tickerUpdatePending = false; }, true);
|
451 |
-
},
|
452 |
-
handleTickerReturn: function(res){
|
453 |
-
this.tickerUpdatePending = false;
|
454 |
-
var newMsg = "";
|
455 |
-
var oldMsg = jQuery('#wfLiveStatus').text();
|
456 |
-
if( res.msg ){
|
457 |
-
newMsg = res.msg;
|
458 |
-
} else {
|
459 |
-
newMsg = "Idle";
|
460 |
-
}
|
461 |
-
if(newMsg && newMsg != oldMsg){
|
462 |
-
jQuery('#wfLiveStatus').hide().html(newMsg).fadeIn(200);
|
463 |
-
}
|
464 |
-
var haveEvents, newElem;
|
465 |
-
if(this.mode == 'activity'){
|
466 |
-
if(res.alsoGet != 'logList_' + this.activityMode){ return; } //user switched panels since ajax request started
|
467 |
-
if(res.events.length > 0){
|
468 |
-
this.newestActivityTime = res.events[0]['ctime'];
|
469 |
-
}
|
470 |
-
haveEvents = false;
|
471 |
-
if(jQuery('#wfActivity_' + this.activityMode + ' .wfActEvent').length > 0){
|
472 |
-
haveEvents = true;
|
473 |
-
}
|
474 |
-
if(res.events.length > 0){
|
475 |
-
if(! haveEvents){
|
476 |
-
jQuery('#wfActivity_' + this.activityMode).empty();
|
477 |
-
}
|
478 |
-
for(i = res.events.length - 1; i >= 0; i--){
|
479 |
-
var elemID = '#wfActEvent_' + res.events[i].id;
|
480 |
-
if(jQuery(elemID).length < 1){
|
481 |
-
res.events[i]['activityMode'] = this.activityMode;
|
482 |
-
if(this.activityMode == 'loginLogout'){
|
483 |
-
newElem = jQuery('#wfLoginLogoutEventTmpl').tmpl(res.events[i]);
|
484 |
-
} else {
|
485 |
-
newElem = jQuery('#wfHitsEventTmpl').tmpl(res.events[i]);
|
486 |
}
|
487 |
-
|
488 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
489 |
}
|
|
|
|
|
|
|
490 |
}
|
491 |
-
|
492 |
-
|
493 |
-
if(
|
494 |
-
|
|
|
495 |
}
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
haveEvents = false;
|
503 |
-
if(jQuery('#wfPerfStats .wfPerfEvent').length > 0){
|
504 |
-
haveEvents = true;
|
505 |
-
}
|
506 |
-
if(res.events.length > 0){
|
507 |
-
if(! haveEvents){
|
508 |
-
jQuery('#wfPerfStats').empty();
|
509 |
-
}
|
510 |
-
var curLength = parseInt(jQuery('#wfPerfStats').css('width'));
|
511 |
-
if(res.longestLine > curLength){
|
512 |
-
jQuery('#wfPerfStats').css('width', (res.longestLine + 200) + 'px');
|
513 |
-
}
|
514 |
-
this.newestActivityTime = res.events[0]['ctime'];
|
515 |
-
for(var i = res.events.length - 1; i >= 0; i--){
|
516 |
-
res.events[i]['scale'] = this.performanceScale;
|
517 |
-
res.events[i]['min'] = this.performanceMinWidth;
|
518 |
-
newElem = jQuery('#wfPerfStatTmpl').tmpl(res.events[i]);
|
519 |
-
jQuery(newElem).find('.wfTimeAgo').data('wfctime', res.events[i].ctime);
|
520 |
-
newElem.prependTo('#wfPerfStats').fadeIn();
|
521 |
-
}
|
522 |
-
} else {
|
523 |
-
if(! haveEvents){
|
524 |
-
jQuery('#wfPerfStats').html('<p>No events to report yet.</p>');
|
525 |
}
|
526 |
-
|
527 |
-
|
528 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
529 |
});
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
}
|
550 |
-
this.ajax('wordfence_reverseLookup', {
|
551 |
-
ips: uniqueIPs.join(',')
|
552 |
-
},
|
553 |
-
function(res){
|
554 |
-
if(res.ok){
|
555 |
-
jQuery('.wfReverseLookup').each(function(idx, elem){
|
556 |
-
var txt = jQuery(elem).text();
|
557 |
-
for(var ip in res.ips){
|
558 |
-
if(txt == ip){
|
559 |
-
if(res.ips[ip]){
|
560 |
-
jQuery(elem).html('<strong>Hostname:</strong> ' + res.ips[ip]);
|
561 |
-
} else {
|
562 |
-
jQuery(elem).html('');
|
563 |
-
}
|
564 |
-
}
|
565 |
-
}
|
566 |
-
});
|
567 |
}
|
568 |
-
}
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
},
|
580 |
-
startScan: function(){
|
581 |
-
var scanReqAnimation = setInterval(function(){
|
582 |
-
var str = jQuery('#wfStartScanButton1').prop('value');
|
583 |
-
var ch = str.charAt(str.length - 1);
|
584 |
-
if(ch == '/'){ ch = '-'; }
|
585 |
-
else if(ch == '-'){ ch = '\\'; }
|
586 |
-
else if(ch == '\\'){ ch = '|'; }
|
587 |
-
else if(ch == '|'){ ch = '/'; }
|
588 |
-
else {ch = '/'; }
|
589 |
-
jQuery('#wfStartScanButton1,#wfStartScanButton2').prop('value', "Requesting a New Scan " + ch);
|
590 |
-
}, 100);
|
591 |
-
setTimeout(function(res){
|
592 |
-
clearInterval(scanReqAnimation);
|
593 |
-
jQuery('#wfStartScanButton1,#wfStartScanButton2').prop('value', "Start a Wordfence Scan");
|
594 |
-
}, 3000);
|
595 |
-
this.ajax('wordfence_scan', {}, function(res){ } );
|
596 |
-
},
|
597 |
-
loadIssues: function(callback){
|
598 |
-
if(this.mode != 'scan'){
|
599 |
-
return;
|
600 |
-
}
|
601 |
-
var self = this;
|
602 |
-
this.ajax('wordfence_loadIssues', { }, function(res){
|
603 |
-
self.displayIssues(res, callback);
|
604 |
-
});
|
605 |
-
},
|
606 |
-
sev2num: function(str){
|
607 |
-
if(/wfProbSev1/.test(str)){
|
608 |
-
return 1;
|
609 |
-
} else if(/wfProbSev2/.test(str)){
|
610 |
-
return 2;
|
611 |
-
} else {
|
612 |
-
return 0;
|
613 |
-
}
|
614 |
-
},
|
615 |
-
displayIssues: function(res, callback){
|
616 |
-
var self = this;
|
617 |
-
try {
|
618 |
-
res.summary['lastScanCompleted'] = res['lastScanCompleted'];
|
619 |
-
} catch(err){
|
620 |
-
res.summary['lastScanCompleted'] = 'Never';
|
621 |
-
}
|
622 |
-
jQuery('.wfIssuesContainer').hide();
|
623 |
-
for(var issueStatus in res.issuesLists){
|
624 |
-
var containerID = 'wfIssues_dataTable_' + issueStatus;
|
625 |
-
var tableID = 'wfIssuesTable_' + issueStatus;
|
626 |
-
if(jQuery('#' + containerID).length < 1){
|
627 |
-
//Invalid issue status
|
628 |
-
continue;
|
629 |
-
}
|
630 |
-
if(res.issuesLists[issueStatus].length < 1){
|
631 |
-
if(issueStatus == 'new'){
|
632 |
-
if(res.lastScanCompleted == 'ok'){
|
633 |
-
jQuery('#' + containerID).html('<p style="font-size: 20px; color: #0A0;">Congratulations! No security problems were detected by Wordfence.</p>');
|
634 |
-
} else if(res['lastScanCompleted']){
|
635 |
-
//jQuery('#' + containerID).html('<p style="font-size: 12px; color: #A00;">The latest scan failed: ' + res.lastScanCompleted + '</p>');
|
636 |
} else {
|
637 |
-
|
638 |
}
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
}
|
667 |
-
}
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
var tmplName = 'issueTmpl_' + obj.aData.type;
|
675 |
-
return jQuery('#' + tmplName).tmpl(obj.aData).html();
|
676 |
-
}
|
677 |
-
}
|
678 |
-
]
|
679 |
-
});
|
680 |
-
}
|
681 |
-
if(callback){
|
682 |
-
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500, function(){ callback(); });
|
683 |
-
} else {
|
684 |
-
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500);
|
685 |
-
}
|
686 |
-
return true;
|
687 |
-
},
|
688 |
-
ajax: function(action, data, cb, cbErr, noLoading){
|
689 |
-
if(typeof(data) == 'string'){
|
690 |
-
if(data.length > 0){
|
691 |
-
data += '&';
|
692 |
-
}
|
693 |
-
data += 'action=' + action + '&nonce=' + this.nonce;
|
694 |
-
} else if(typeof(data) == 'object'){
|
695 |
-
data['action'] = action;
|
696 |
-
data['nonce'] = this.nonce;
|
697 |
-
}
|
698 |
-
if(! cbErr){
|
699 |
-
cbErr = function(){};
|
700 |
-
}
|
701 |
-
var self = this;
|
702 |
-
if(! noLoading){
|
703 |
-
this.showLoading();
|
704 |
-
}
|
705 |
-
jQuery.ajax({
|
706 |
-
type: 'POST',
|
707 |
-
url: WordfenceAdminVars.ajaxURL,
|
708 |
-
dataType: "json",
|
709 |
-
data: data,
|
710 |
-
success: function(json){
|
711 |
-
if(! noLoading){
|
712 |
-
self.removeLoading();
|
713 |
-
}
|
714 |
-
if(json && json.nonce){
|
715 |
-
self.nonce = json.nonce;
|
716 |
-
}
|
717 |
-
if(json && json.errorMsg){
|
718 |
-
self.colorbox('400px', 'An error occurred', json.errorMsg);
|
719 |
-
}
|
720 |
-
cb(json);
|
721 |
-
},
|
722 |
-
error: function(){
|
723 |
-
if(! noLoading){
|
724 |
-
self.removeLoading();
|
725 |
-
}
|
726 |
-
cbErr();
|
727 |
-
}
|
728 |
-
});
|
729 |
-
},
|
730 |
-
colorbox: function(width, heading, body){
|
731 |
-
this.colorboxQueue.push([width, heading, body]);
|
732 |
-
this.colorboxServiceQueue();
|
733 |
-
},
|
734 |
-
colorboxServiceQueue: function(){
|
735 |
-
if(this.colorboxIsOpen){ return; }
|
736 |
-
if(this.colorboxQueue.length < 1){ return; }
|
737 |
-
var elem = this.colorboxQueue.shift();
|
738 |
-
this.colorboxOpen(elem[0], elem[1], elem[2]);
|
739 |
-
},
|
740 |
-
colorboxOpen: function(width, heading, body){
|
741 |
-
this.colorboxIsOpen = true;
|
742 |
-
jQuery.colorbox({ width: width, html: "<h3>" + heading + "</h3><p>" + body + "</p>"});
|
743 |
-
},
|
744 |
-
scanRunningMsg: function(){ this.colorbox('400px', "A scan is running", "A scan is currently in progress. Please wait until it finishes before starting another scan."); },
|
745 |
-
errorMsg: function(msg){ this.colorbox('400px', "An error occurred:", msg); },
|
746 |
-
bulkOperation: function(op){
|
747 |
-
var self = this;
|
748 |
-
if(op == 'del' || op == 'repair'){
|
749 |
-
var ids = jQuery('input.wf' + op + 'Checkbox:checked').map(function(){ return jQuery(this).val(); }).get();
|
750 |
-
if(ids.length < 1){
|
751 |
-
this.colorbox('400px', "No files were selected", "You need to select files to perform a bulk operation. There is a checkbox in each issue that lets you select that file. You can then select a bulk operation and hit the button to perform that bulk operation.");
|
752 |
-
return;
|
753 |
-
}
|
754 |
-
if(op == 'del'){
|
755 |
-
this.colorbox('400px', "Are you sure you want to delete?", "Are you sure you want to delete a total of " + ids.length + " files? Do not delete files on your system unless you're ABSOLUTELY sure you know what you're doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files.<br /><br /><input type=\"button\" value=\"Delete Files\" onclick=\"WFAD.bulkOperationConfirmed('" + op + "');\" /> <input type=\"button\" value=\"Cancel\" onclick=\"jQuery.colorbox.close();\" /><br />");
|
756 |
-
} else if(op == 'repair'){
|
757 |
-
this.colorbox('400px', "Are you sure you want to repair?", "Are you sure you want to repair a total of " + ids.length + " files? Do not repair files on your system unless you're sure you have reviewed the differences between the original file and your version of the file in the files you are repairing. If you repair a file that has been customized for your system by a developer or your hosting provider it may leave your system unusable. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files.<br /><br /><input type=\"button\" value=\"Repair Files\" onclick=\"WFAD.bulkOperationConfirmed('" + op + "');\" /> <input type=\"button\" value=\"Cancel\" onclick=\"jQuery.colorbox.close();\" /><br />");
|
758 |
-
}
|
759 |
-
} else {
|
760 |
-
return;
|
761 |
-
}
|
762 |
-
},
|
763 |
-
bulkOperationConfirmed: function(op){
|
764 |
-
jQuery.colorbox.close();
|
765 |
-
var self = this;
|
766 |
-
this.ajax('wordfence_bulkOperation', {
|
767 |
-
op: op,
|
768 |
-
ids: jQuery('input.wf' + op + 'Checkbox:checked').map(function(){ return jQuery(this).val(); }).get()
|
769 |
-
}, function(res){ self.doneBulkOperation(res); });
|
770 |
-
},
|
771 |
-
doneBulkOperation: function(res){
|
772 |
-
var self = this;
|
773 |
-
if(res.ok){
|
774 |
-
this.loadIssues(function(){ self.colorbox('400px', res.bulkHeading, res.bulkBody); });
|
775 |
-
} else {
|
776 |
-
this.loadIssues(function(){});
|
777 |
-
}
|
778 |
-
},
|
779 |
-
deleteFile: function(issueID){
|
780 |
-
var self = this;
|
781 |
-
this.ajax('wordfence_deleteFile', {
|
782 |
-
issueID: issueID
|
783 |
-
}, function(res){ self.doneDeleteFile(res); });
|
784 |
-
},
|
785 |
-
doneDeleteFile: function(res){
|
786 |
-
var cb = false;
|
787 |
-
var self = this;
|
788 |
-
if(res.ok){
|
789 |
-
this.loadIssues(function(){ self.colorbox('400px', "Success deleting file", "The file " + res.file + " was successfully deleted."); });
|
790 |
-
} else if(res.cerrorMsg){
|
791 |
-
this.loadIssues(function(){ self.colorbox('400px', 'An error occurred', res.cerrorMsg); });
|
792 |
-
}
|
793 |
-
},
|
794 |
-
restoreFile: function(issueID){
|
795 |
-
var self = this;
|
796 |
-
this.ajax('wordfence_restoreFile', {
|
797 |
-
issueID: issueID
|
798 |
-
}, function(res){ self.doneRestoreFile(res); });
|
799 |
-
},
|
800 |
-
doneRestoreFile: function(res){
|
801 |
-
var self = this;
|
802 |
-
if(res.ok){
|
803 |
-
this.loadIssues(function(){ self.colorbox("400px", "File restored OK", "The file " + res.file + " was restored succesfully."); });
|
804 |
-
} else if(res.cerrorMsg){
|
805 |
-
this.loadIssues(function(){ self.colorbox('400px', 'An error occurred', res.cerrorMsg); });
|
806 |
-
}
|
807 |
-
},
|
808 |
-
deleteIssue: function(id){
|
809 |
-
var self = this;
|
810 |
-
this.ajax('wordfence_deleteIssue', { id: id }, function(res){
|
811 |
-
self.loadIssues();
|
812 |
-
});
|
813 |
-
},
|
814 |
-
updateIssueStatus: function(id, st){
|
815 |
-
var self = this;
|
816 |
-
this.ajax('wordfence_updateIssueStatus', { id: id, 'status': st }, function(res){
|
817 |
-
if(res.ok){
|
818 |
-
self.loadIssues();
|
819 |
-
}
|
820 |
-
});
|
821 |
-
},
|
822 |
-
updateAllIssues: function(op){ // deleteIgnored, deleteNew, ignoreAllNew
|
823 |
-
var head = "Please confirm";
|
824 |
-
var body;
|
825 |
-
if(op == 'deleteIgnored'){
|
826 |
-
body = "You have chosen to remove all ignored issues. Once these issues are removed they will be re-scanned by Wordfence and if they have not been fixed, they will appear in the 'new issues' list. Are you sure you want to do this?";
|
827 |
-
} else if(op == 'deleteNew'){
|
828 |
-
body = "You have chosen to mark all new issues as fixed. If you have not really fixed these issues, they will reappear in the new issues list on the next scan. If you have not fixed them and want them excluded from scans you should choose to 'ignore' them instead. Are you sure you want to mark all new issues as fixed?";
|
829 |
-
} else if(op == 'ignoreAllNew'){
|
830 |
-
body = "You have chosen to ignore all new issues. That means they will be excluded from future scans. You should only do this if you're sure all new issues are not a problem. Are you sure you want to ignore all new issues?";
|
831 |
-
} else {
|
832 |
-
return;
|
833 |
-
}
|
834 |
-
this.colorbox('450px', head, body + '<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" /> <input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmUpdateAllIssues(\'' + op + '\');" /><br />');
|
835 |
-
},
|
836 |
-
confirmUpdateAllIssues: function(op){
|
837 |
-
var self = this;
|
838 |
-
this.ajax('wordfence_updateAllIssues', { op: op }, function(res){ self.loadIssues(); });
|
839 |
-
},
|
840 |
-
es: function(val){
|
841 |
-
if(val){
|
842 |
-
return val;
|
843 |
-
} else {
|
844 |
-
return "";
|
845 |
-
}
|
846 |
-
},
|
847 |
-
noQuotes: function(str){
|
848 |
-
return str.replace(/"/g,'"').replace(/\'/g, '‘');
|
849 |
-
},
|
850 |
-
commify: function(num){
|
851 |
-
return ("" + num).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
|
852 |
-
},
|
853 |
-
switchToLiveTab: function(elem){
|
854 |
-
jQuery('.wfTab1').removeClass('selected');
|
855 |
-
jQuery(elem).addClass('selected');
|
856 |
-
jQuery('.wfDataPanel').hide();
|
857 |
-
var self = this;
|
858 |
-
jQuery('#wfActivity').fadeIn(function(){ self.completeLiveTabSwitch(); });
|
859 |
-
},
|
860 |
-
completeLiveTabSwitch: function(){
|
861 |
-
this.ajax('wordfence_loadActivityLog', {}, function(res){
|
862 |
-
var html = '<a href="#" class="wfALogMailLink" onclick="WFAD.emailActivityLog(); return false;"></a><a href="#" class="wfALogReloadLink" onclick="WFAD.reloadActivityData(); return false;"></a>';
|
863 |
-
if(res.events && res.events.length > 0){
|
864 |
-
jQuery('#wfActivity').empty();
|
865 |
-
for(var i = 0; i < res.events.length; i++){
|
866 |
-
var timeTaken = '0.0000';
|
867 |
-
if(res.events[i + 1]){
|
868 |
-
timeTaken = (res.events[i].ctime - res.events[i + 1].ctime).toFixed(4);
|
869 |
-
}
|
870 |
-
var red = "";
|
871 |
-
if(res.events[i].type == 'error'){
|
872 |
-
red = ' class="wfWarn" ';
|
873 |
-
}
|
874 |
-
html += '<div ' + red + 'class="wfALogEntry"><span ' + red + 'class="wfALogTime">[' + res.events[i].type + ' : ' + timeTaken + ' : ' + res.events[i].timeAgo + ' ago]</span> ' + res.events[i].msg + "</div>";
|
875 |
-
}
|
876 |
-
jQuery('#wfActivity').html(html);
|
877 |
-
} else {
|
878 |
-
jQuery('#wfActivity').html("<p> No activity to report yet. Please complete your first scan.</p>");
|
879 |
-
}
|
880 |
-
});
|
881 |
-
},
|
882 |
-
emailActivityLog: function(){
|
883 |
-
this.colorbox('400px', 'Email Wordfence Activity Log', "Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team. It also contains your PHP configuration from the phpinfo() function for diagnostic data.<br /><br /><input type='text' value='support@wordfence.com' size='20' id='wfALogRecip' /><input type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" /><input type='button' value='Cancel' onclick='jQuery.colorbox.close();' /><br /><br />");
|
884 |
-
},
|
885 |
-
completeEmailActivityLog: function(){
|
886 |
-
jQuery.colorbox.close();
|
887 |
-
var email = jQuery('#wfALogRecip').val();
|
888 |
-
if(! /^[^@]+@[^@]+$/.test(email)){
|
889 |
-
alert("Please enter a valid email address.");
|
890 |
-
return;
|
891 |
-
}
|
892 |
-
var self = this;
|
893 |
-
this.ajax('wordfence_sendActivityLog', { email: jQuery('#wfALogRecip').val() }, function(res){
|
894 |
-
if(res.ok){
|
895 |
-
self.colorbox('400px', 'Activity Log Sent', "Your Wordfence activity log was sent to " + email + "<br /><br /><input type='button' value='Close' onclick='jQuery.colorbox.close();' /><br /><br />");
|
896 |
-
}
|
897 |
-
});
|
898 |
-
},
|
899 |
-
reloadActivityData: function(){
|
900 |
-
jQuery('#wfActivity').html('<div class="wfLoadingWhite32"></div>'); // <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
|
901 |
-
this.completeLiveTabSwitch();
|
902 |
-
},
|
903 |
-
switchToSummaryTab: function(elem){
|
904 |
-
jQuery('.wfTab1').removeClass('selected');
|
905 |
-
jQuery(elem).addClass('selected');
|
906 |
-
jQuery('.wfDataPanel').hide();
|
907 |
-
jQuery('#wfSummaryTables').fadeIn();
|
908 |
-
},
|
909 |
-
switchIssuesTab: function(elem, type){
|
910 |
-
jQuery('.wfTab2').removeClass('selected');
|
911 |
-
jQuery('.wfIssuesContainer').hide();
|
912 |
-
jQuery(elem).addClass('selected');
|
913 |
-
this.visibleIssuesPanel = type;
|
914 |
-
jQuery('#wfIssues_' + type).fadeIn();
|
915 |
-
},
|
916 |
-
switchTab: function(tabElement, tabClass, contentClass, selectedContentID, callback){
|
917 |
-
jQuery('.' + tabClass).removeClass('selected');
|
918 |
-
jQuery(tabElement).addClass('selected');
|
919 |
-
jQuery('.' + contentClass).hide().html('<div class="wfLoadingWhite32"></div>');
|
920 |
-
var func = function(){};
|
921 |
-
if(callback){
|
922 |
-
func = function(){ callback(); };
|
923 |
-
}
|
924 |
-
jQuery('#' + selectedContentID).fadeIn(func);
|
925 |
-
},
|
926 |
-
activityTabChanged: function(){
|
927 |
-
var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_','');
|
928 |
-
if(! mode){ return; }
|
929 |
-
this.activityMode = mode;
|
930 |
-
this.reloadActivities();
|
931 |
-
},
|
932 |
-
reloadActivities: function(){
|
933 |
-
jQuery('#wfActivity_' + this.activityMode).html('<div class="wfLoadingWhite32"></div>');
|
934 |
-
this.newestActivityTime = 0;
|
935 |
-
this.updateTicker(true);
|
936 |
-
},
|
937 |
-
staticTabChanged: function(){
|
938 |
-
var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_','');
|
939 |
-
if(! mode){ return; }
|
940 |
-
this.activityMode = mode;
|
941 |
-
|
942 |
-
var self = this;
|
943 |
-
this.ajax('wordfence_loadStaticPanel', {
|
944 |
-
mode: this.activityMode
|
945 |
-
}, function(res){
|
946 |
-
self.completeLoadStaticPanel(res);
|
947 |
-
});
|
948 |
-
},
|
949 |
-
completeLoadStaticPanel: function(res){
|
950 |
-
var contentElem = '#wfActivity_' + this.activityMode;
|
951 |
-
jQuery(contentElem).empty();
|
952 |
-
if(res.results && res.results.length > 0){
|
953 |
-
var tmpl;
|
954 |
-
if(this.activityMode == 'topScanners' || this.activityMode == 'topLeechers'){
|
955 |
-
tmpl = '#wfLeechersTmpl';
|
956 |
-
} else if(this.activityMode == 'blockedIPs'){
|
957 |
-
tmpl = '#wfBlockedIPsTmpl';
|
958 |
-
} else if(this.activityMode == 'lockedOutIPs'){
|
959 |
-
tmpl = '#wfLockedOutIPsTmpl';
|
960 |
-
} else if(this.activityMode == 'throttledIPs'){
|
961 |
-
tmpl = '#wfThrottledIPsTmpl';
|
962 |
-
} else { return; }
|
963 |
-
var i, j, chunk = 1000;
|
964 |
-
var bigArray = res.results.slice(0);
|
965 |
-
res.results = false;
|
966 |
-
for(i = 0, j = bigArray.length; i < j; i += chunk){
|
967 |
-
res.results = bigArray.slice(i, i + chunk);
|
968 |
-
jQuery(tmpl).tmpl(res).appendTo(contentElem);
|
969 |
-
}
|
970 |
-
this.reverseLookupIPs();
|
971 |
-
} else {
|
972 |
-
if(this.activityMode == 'topScanners' || this.activityMode == 'topLeechers'){
|
973 |
-
jQuery(contentElem).html("No site hits have been logged yet. Check back soon.");
|
974 |
-
} else if(this.activityMode == 'blockedIPs'){
|
975 |
-
jQuery(contentElem).html("No IP addresses have been blocked yet. If you manually block an IP address or if Wordfence automatically blocks one, it will appear here.");
|
976 |
-
} else if(this.activityMode == 'lockedOutIPs'){
|
977 |
-
jQuery(contentElem).html("No IP addresses have been locked out from signing in or using the password recovery system.");
|
978 |
-
} else if(this.activityMode == 'throttledIPs'){
|
979 |
-
jQuery(contentElem).html("No IP addresses have been throttled yet. If an IP address accesses the site too quickly and breaks one of the Wordfence rules, it will appear here.");
|
980 |
-
} else { return; }
|
981 |
-
}
|
982 |
-
},
|
983 |
-
ucfirst: function(str){
|
984 |
-
str = "" + str;
|
985 |
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
986 |
-
},
|
987 |
-
makeIPTrafLink: function(IP){
|
988 |
-
return WordfenceAdminVars.siteBaseURL + '?_wfsf=IPTraf&nonce=' + this.nonce + '&IP=' + encodeURIComponent(IP);
|
989 |
-
},
|
990 |
-
makeDiffLink: function(dat){
|
991 |
-
return WordfenceAdminVars.siteBaseURL + '?_wfsf=diff&nonce=' + this.nonce +
|
992 |
-
'&file=' + encodeURIComponent(this.es(dat['file'])) +
|
993 |
-
'&cType=' + encodeURIComponent(this.es(dat['cType'])) +
|
994 |
-
'&cKey=' + encodeURIComponent(this.es(dat['cKey'])) +
|
995 |
-
'&cName=' + encodeURIComponent(this.es(dat['cName'])) +
|
996 |
-
'&cVersion=' + encodeURIComponent(this.es(dat['cVersion']));
|
997 |
-
},
|
998 |
-
makeViewFileLink: function(file){
|
999 |
-
return WordfenceAdminVars.siteBaseURL + '?_wfsf=view&nonce=' + this.nonce + '&file=' + encodeURIComponent(file);
|
1000 |
-
},
|
1001 |
-
makeTimeAgo: function(t){
|
1002 |
-
var months = Math.floor(t / (86400 * 30));
|
1003 |
-
var days = Math.floor(t / 86400);
|
1004 |
-
var hours = Math.floor(t / 3600);
|
1005 |
-
var minutes = Math.floor(t / 60);
|
1006 |
-
if(months > 0){
|
1007 |
-
days -= months * 30;
|
1008 |
-
return this.pluralize(months, 'month', days, 'day');
|
1009 |
-
} else if(days > 0){
|
1010 |
-
hours -= days * 24;
|
1011 |
-
return this.pluralize(days, 'day', hours, 'hour');
|
1012 |
-
} else if(hours > 0) {
|
1013 |
-
minutes -= hours * 60;
|
1014 |
-
return this.pluralize(hours, 'hour', minutes, 'min');
|
1015 |
-
} else if(minutes > 0) {
|
1016 |
-
//t -= minutes * 60;
|
1017 |
-
return this.pluralize(minutes, 'minute');
|
1018 |
-
} else {
|
1019 |
-
return Math.round(t) + " seconds";
|
1020 |
-
}
|
1021 |
-
},
|
1022 |
-
pluralize: function(m1, t1, m2, t2){
|
1023 |
-
if(m1 != 1) {
|
1024 |
-
t1 = t1 + 's';
|
1025 |
-
}
|
1026 |
-
if(m2 != 1) {
|
1027 |
-
t2 = t2 + 's';
|
1028 |
-
}
|
1029 |
-
if(m1 && m2){
|
1030 |
-
return m1 + ' ' + t1 + ' ' + m2 + ' ' + t2;
|
1031 |
-
} else {
|
1032 |
-
return m1 + ' ' + t1;
|
1033 |
-
}
|
1034 |
-
},
|
1035 |
-
calcRangeTotal: function(){
|
1036 |
-
var range = jQuery('#ipRange').val();
|
1037 |
-
if(! range){ return; }
|
1038 |
-
range = range.replace(/ /g, '');
|
1039 |
-
if(range && /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s*\-\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(range)){
|
1040 |
-
var ips = range.split('-');
|
1041 |
-
var total = this.inet_aton(ips[1]) - this.inet_aton(ips[0]) + 1;
|
1042 |
-
if(total < 1){
|
1043 |
-
jQuery('#wfShowRangeTotal').html("<span style=\"color: #F00;\">Invalid. Starting IP is greater than ending IP.</span>");
|
1044 |
-
return;
|
1045 |
-
}
|
1046 |
-
jQuery('#wfShowRangeTotal').html("<span style=\"color: #0A0;\">Valid: " + total + " addresses in range.</span>");
|
1047 |
-
} else {
|
1048 |
-
jQuery('#wfShowRangeTotal').empty();
|
1049 |
-
}
|
1050 |
-
},
|
1051 |
-
loadBlockRanges: function(){
|
1052 |
-
var self = this;
|
1053 |
-
this.ajax('wordfence_loadBlockRanges', {}, function(res){ self.completeLoadBlockRanges(res); });
|
1054 |
-
|
1055 |
-
},
|
1056 |
-
completeLoadBlockRanges: function(res){
|
1057 |
-
jQuery('#currentBlocks').empty();
|
1058 |
-
if(res.results && res.results.length > 0){
|
1059 |
-
jQuery('#wfBlockedRangesTmpl').tmpl(res).prependTo('#currentBlocks');
|
1060 |
-
} else {
|
1061 |
-
jQuery('#currentBlocks').html("You have not blocked any IP ranges or other patterns yet.");
|
1062 |
-
}
|
1063 |
-
},
|
1064 |
-
whois: function(val){
|
1065 |
-
val = val.replace(' ','');
|
1066 |
-
if( ! /\w+/.test(val)){
|
1067 |
-
this.colorbox('300px', "Enter a valid IP or domain", "Please enter a valid IP address or domain name for your whois lookup.");
|
1068 |
-
return;
|
1069 |
-
}
|
1070 |
-
var self = this;
|
1071 |
-
jQuery('#whoisbutton').attr('disabled', 'disabled');
|
1072 |
-
jQuery('#whoisbutton').attr('value', 'Loading...');
|
1073 |
-
this.ajax('wordfence_whois', {
|
1074 |
-
val: val
|
1075 |
-
}, function(res){
|
1076 |
-
jQuery('#whoisbutton').removeAttr('disabled');
|
1077 |
-
jQuery('#whoisbutton').attr('value', 'Look up IP or Domain');
|
1078 |
-
if(res.ok){
|
1079 |
-
self.completeWhois(res);
|
1080 |
-
}
|
1081 |
-
});
|
1082 |
-
},
|
1083 |
-
completeWhois: function(res){
|
1084 |
-
if(res.ok && res.result && res.result.rawdata && res.result.rawdata.length > 0){
|
1085 |
-
var rawhtml = "";
|
1086 |
-
for(var i = 0; i < res.result.rawdata.length; i++){
|
1087 |
-
res.result.rawdata[i] = jQuery('<div />').text(res.result.rawdata[i]).html();
|
1088 |
-
res.result.rawdata[i] = res.result.rawdata[i].replace(/([^\s\t\r\n:;]+@[^\s\t\r\n:;\.]+\.[^\s\t\r\n:;]+)/, "<a href=\"mailto:$1\">$1<\/a>");
|
1089 |
-
res.result.rawdata[i] = res.result.rawdata[i].replace(/(https?:\/\/[^\/]+[^\s\r\n\t]+)/, "<a target=\"_blank\" href=\"$1\">$1<\/a>");
|
1090 |
-
var redStyle = "";
|
1091 |
-
if(this.getQueryParam('wfnetworkblock')){
|
1092 |
-
redStyle = " style=\"color: #F00;\"";
|
1093 |
}
|
1094 |
var self = this;
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1101 |
}
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
jQuery('#wfrawhtml').html(rawhtml);
|
1107 |
-
} else {
|
1108 |
-
jQuery('#wfrawhtml').html('<span style="color: #F00;">Sorry, but no data for that IP or domain was found.</span>');
|
1109 |
-
}
|
1110 |
-
},
|
1111 |
-
blockIPUARange: function(ipRange, uaRange, referer, reason){
|
1112 |
-
if(! /\w+/.test(reason)){
|
1113 |
-
this.colorbox('300px', "Please specify a reason", "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping.");
|
1114 |
-
return;
|
1115 |
-
}
|
1116 |
-
ipRange = ipRange.replace(/ /g, '');
|
1117 |
-
if(ipRange){
|
1118 |
-
if(! /^\d+\.\d+\.\d+\.\d+\-\d+\.\d+\.\d+\.\d+$/.test(ipRange)){
|
1119 |
-
this.colorbox('300px', 'Specify a valid IP range', "Please specify a valid IP address range in the form of \"1.2.3.4 - 1.2.3.5\" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash.");
|
1120 |
-
return;
|
1121 |
-
}
|
1122 |
-
}
|
1123 |
-
if( ! (/\w+/.test(ipRange) || /\w+/.test(uaRange) || /\w+/.test(referer)) ){
|
1124 |
-
this.colorbox('300px', 'Specify an IP range or Browser pattern', "Please specify either an IP address range or a web browser pattern to match.");
|
1125 |
-
return;
|
1126 |
-
}
|
1127 |
-
var self = this;
|
1128 |
-
this.ajax('wordfence_blockIPUARange', {
|
1129 |
-
ipRange: ipRange,
|
1130 |
-
uaRange: uaRange,
|
1131 |
-
referer: referer,
|
1132 |
-
reason: reason
|
1133 |
-
}, function(res){
|
1134 |
-
if(res.ok){
|
1135 |
-
self.loadBlockRanges();
|
1136 |
-
return;
|
1137 |
}
|
1138 |
-
}
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
}, function(res){
|
1145 |
-
self.loadBlockRanges();
|
1146 |
-
});
|
1147 |
-
},
|
1148 |
-
blockIP: function(IP, reason){
|
1149 |
-
var self = this;
|
1150 |
-
this.ajax('wordfence_blockIP', {
|
1151 |
-
IP: IP,
|
1152 |
-
reason: reason
|
1153 |
-
}, function(res){
|
1154 |
-
if(res.errorMsg){
|
1155 |
-
return;
|
1156 |
} else {
|
1157 |
-
self.reloadActivities();
|
1158 |
-
}
|
1159 |
-
});
|
1160 |
-
},
|
1161 |
-
blockIPTwo: function(IP, reason, perm){
|
1162 |
-
var self = this;
|
1163 |
-
this.ajax('wordfence_blockIP', {
|
1164 |
-
IP: IP,
|
1165 |
-
reason: reason,
|
1166 |
-
perm: (perm ? '1' : '0')
|
1167 |
-
}, function(res){
|
1168 |
-
if(res.errorMsg){
|
1169 |
return;
|
1170 |
-
} else {
|
1171 |
-
self.staticTabChanged();
|
1172 |
}
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
unblockIP: function(IP){
|
1182 |
-
var self = this;
|
1183 |
-
this.ajax('wordfence_unblockIP', {
|
1184 |
-
IP: IP
|
1185 |
-
}, function(res){
|
1186 |
-
self.reloadActivities();
|
1187 |
-
});
|
1188 |
-
},
|
1189 |
-
unblockIPTwo: function(IP){
|
1190 |
-
var self = this;
|
1191 |
-
this.ajax('wordfence_unblockIP', {
|
1192 |
-
IP: IP
|
1193 |
-
}, function(res){
|
1194 |
-
self.staticTabChanged();
|
1195 |
});
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
return 'wfElemGen' + this.elementGeneratorIter++;
|
1205 |
-
},
|
1206 |
-
pulse: function(sel){
|
1207 |
-
jQuery(sel).fadeIn(function(){
|
1208 |
-
setTimeout(function(){ jQuery(sel).fadeOut(); }, 2000);
|
1209 |
-
});
|
1210 |
-
},
|
1211 |
-
getCacheStats: function(){
|
1212 |
-
var self = this;
|
1213 |
-
this.ajax('wordfence_getCacheStats', {}, function(res){
|
1214 |
-
if(res.ok){
|
1215 |
-
self.colorbox('400px', res.heading, res.body);
|
1216 |
-
}
|
1217 |
-
});
|
1218 |
-
},
|
1219 |
-
clearPageCache: function(){
|
1220 |
-
var self = this;
|
1221 |
-
this.ajax('wordfence_clearPageCache', {}, function(res){
|
1222 |
-
if(res.ok){
|
1223 |
-
self.colorbox('400px', res.heading, res.body);
|
1224 |
-
}
|
1225 |
-
});
|
1226 |
-
},
|
1227 |
-
switchToFalcon: function(){
|
1228 |
-
var self = this;
|
1229 |
-
this.ajax('wordfence_checkFalconHtaccess', {
|
1230 |
-
}, function(res){
|
1231 |
-
if(res.ok){
|
1232 |
-
self.colorbox('400px', "Enabling Falcon Engine", 'First read this <a href="http://www.wordfence.com/introduction-to-wordfence-falcon-engine/" target="_blank">Introduction to Falcon Engine</a>. Falcon modifies your website configuration file which is called your .htaccess file. To enable Falcon we ask that you make a backup of this file. This is a safety precaution in case for some reason Falcon is not compatible with your site.<br /><br /><a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wfNextBut\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a><br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" disabled="disabled" onclick="WFAD.confirmSwitchToFalcon(0);" />');
|
1233 |
-
} else if(res.nginx){
|
1234 |
-
self.colorbox('400px', "Enabling Falcon Engine", 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. To use Falcon you will need to manually modify your nginx.conf configuration file and reload your Nginx server for the changes to take effect. You can find the <a href="http://www.wordfence.com/blog/2014/05/nginx-wordfence-falcon-engine-php-fpm-fastcgi-fast-cgi/" target="_blank">rules you need to make these changes to nginx.conf on this page on wordfence.com</a>. Once you have made these changes, compressed cached files will be served to your visitors directly from Nginx making your site extremely fast. When you have made the changes and reloaded your Nginx server, you can click the button below to enable Falcon.<br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" onclick="WFAD.confirmSwitchToFalcon(1);" />');
|
1235 |
-
} else if(res.err){
|
1236 |
-
self.colorbox('400px', "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err + "<br /><br />Advanced users: If you would like to manually enable Falcon yourself by editing your .htaccess, you can add the rules below to the beginning of your .htaccess file. Then click the button below to enable Falcon. Don't do this unless you understand website configuration.<br /><textarea style='width: 300px; height:100px;' readonly>" + jQuery('<div/>').text(res.code).html() + "</textarea><br /><input type='button' value='Enable Falcon after manually editing .htaccess' onclick='WFAD.confirmSwitchToFalcon(1);' />");
|
1237 |
-
}
|
1238 |
-
});
|
1239 |
-
},
|
1240 |
-
confirmSwitchToFalcon: function(noEditHtaccess){
|
1241 |
-
jQuery.colorbox.close();
|
1242 |
-
var cacheType = 'falcon';
|
1243 |
-
var self = this;
|
1244 |
-
this.ajax('wordfence_saveCacheConfig', {
|
1245 |
-
cacheType: cacheType,
|
1246 |
-
noEditHtaccess: noEditHtaccess
|
1247 |
-
}, function(res){
|
1248 |
-
if(res.ok){
|
1249 |
-
self.colorbox('400px', res.heading, res.body);
|
1250 |
}
|
1251 |
-
}
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
}, function(res){
|
1263 |
-
if(res.ok){
|
1264 |
-
self.colorbox('400px', res.heading, res.body);
|
1265 |
}
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
}, function(res){
|
1276 |
-
if(res.updateErr){
|
1277 |
-
self.colorbox('400px', "You need to manually update your .htaccess", res.updateErr + "<br />Your option was updated but you need to change the Wordfence code in your .htaccess to the following:<br /><textarea style='width: 300px; height: 120px;'>" + jQuery('<div/>').text(res.code).html() + '</textarea>');
|
1278 |
}
|
1279 |
-
|
1280 |
-
|
1281 |
-
},
|
1282 |
-
saveConfig: function(){
|
1283 |
-
var qstr = jQuery('#wfConfigForm').serialize();
|
1284 |
-
var self = this;
|
1285 |
-
jQuery('.wfSavedMsg').hide();
|
1286 |
-
jQuery('.wfAjax24').show();
|
1287 |
-
this.ajax('wordfence_saveConfig', qstr, function(res){
|
1288 |
-
jQuery('.wfAjax24').hide();
|
1289 |
-
if(res.ok){
|
1290 |
-
if(res['paidKeyMsg']){
|
1291 |
-
self.colorbox('400px', "Congratulations! You have been upgraded to Premium Scanning.", "You have upgraded to a Premium API key. Once this page reloads, you can choose which premium scanning options you would like to enable and then click save. Click the button below to reload this page now.<br /><br /><center><input type='button' name='wfReload' value='Reload page and enable Premium options' onclick='window.location.reload(true);' /></center>");
|
1292 |
return;
|
1293 |
-
}
|
1294 |
-
|
|
|
|
|
|
|
|
|
|
|
1295 |
return;
|
1296 |
-
} else {
|
1297 |
-
self.pulse('.wfSavedMsg');
|
1298 |
}
|
1299 |
-
} else if(res.errorMsg){
|
1300 |
-
return;
|
1301 |
-
} else {
|
1302 |
-
self.colorbox('400px', 'An error occurred', 'We encountered an error trying to save your changes.');
|
1303 |
-
}
|
1304 |
-
});
|
1305 |
-
},
|
1306 |
-
changeSecurityLevel: function(){
|
1307 |
-
var level = jQuery('#securityLevel').val();
|
1308 |
-
for(var k in WFSLevels[level].checkboxes){
|
1309 |
-
if(k != 'liveTraf_ignorePublishers'){
|
1310 |
-
jQuery('#' + k).prop("checked", WFSLevels[level].checkboxes[k]);
|
1311 |
-
}
|
1312 |
-
}
|
1313 |
-
for(var k in WFSLevels[level].otherParams){
|
1314 |
-
if(! /^(?:apiKey|securityLevel|alertEmails|liveTraf_ignoreUsers|liveTraf_ignoreIPs|liveTraf_ignoreUA|liveTraf_hitsMaxSize|maxMem|maxExecutionTime|actUpdateInterval)$/.test(k)){
|
1315 |
-
jQuery('#' + k).val(WFSLevels[level].otherParams[k]);
|
1316 |
-
}
|
1317 |
-
}
|
1318 |
-
},
|
1319 |
-
clearAllBlocked: function(op){
|
1320 |
-
if(op == 'blocked'){
|
1321 |
-
body = "Are you sure you want to clear all blocked IP addresses and allow visitors from those addresses to access the site again?";
|
1322 |
-
} else if(op == 'locked'){
|
1323 |
-
body = "Are you sure you want to clear all locked IP addresses and allow visitors from those addresses to sign in again?";
|
1324 |
-
} else {
|
1325 |
-
return;
|
1326 |
-
}
|
1327 |
-
this.colorbox('450px', "Please confirm", body +
|
1328 |
-
'<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" /> ' +
|
1329 |
-
'<input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmClearAllBlocked(\'' + op + '\');"><br />');
|
1330 |
-
},
|
1331 |
-
confirmClearAllBlocked: function(op){
|
1332 |
-
var self = this;
|
1333 |
-
this.ajax('wordfence_clearAllBlocked', { op: op }, function(res){
|
1334 |
-
self.staticTabChanged();
|
1335 |
-
});
|
1336 |
-
},
|
1337 |
-
setOwnCountry: function(code){
|
1338 |
-
this.ownCountry = (code + "").toUpperCase();
|
1339 |
-
},
|
1340 |
-
loadBlockedCountries: function(str){
|
1341 |
-
var codes = str.split(',');
|
1342 |
-
for(var i = 0; i < codes.length; i++){
|
1343 |
-
jQuery('#wfCountryCheckbox_' + codes[i]).prop('checked', true);
|
1344 |
-
}
|
1345 |
-
},
|
1346 |
-
saveCountryBlocking: function(){
|
1347 |
-
var action = jQuery('#wfBlockAction').val();
|
1348 |
-
var redirURL = jQuery('#wfRedirURL').val();
|
1349 |
-
var bypassRedirURL = jQuery('#wfBypassRedirURL').val();
|
1350 |
-
var bypassRedirDest = jQuery('#wfBypassRedirDest').val();
|
1351 |
-
var bypassViewURL = jQuery('#wfBypassViewURL').val();
|
1352 |
-
|
1353 |
-
if(action == 'redir' && (! /^https?:\/\/[^\/]+/i.test(redirURL))){
|
1354 |
-
this.colorbox('400px', "Please enter a URL for redirection", "You have chosen to redirect blocked countries to a specific page. You need to enter a URL in the text box provided that starts with http:// or https://");
|
1355 |
-
return;
|
1356 |
-
}
|
1357 |
-
if( bypassRedirURL || bypassRedirDest ){
|
1358 |
-
if(! (bypassRedirURL && bypassRedirDest)){
|
1359 |
-
this.colorbox('400px', "Missing data from form", "If you want to set up a URL that will bypass country blocking, you must enter a URL that a visitor can hit and the destination they will be redirected to. You have only entered one of these components. Please enter both.");
|
1360 |
-
return;
|
1361 |
-
}
|
1362 |
-
if(bypassRedirURL == bypassRedirDest){
|
1363 |
-
this.colorbox('400px', "URLs are the same", "The URL that a user hits to bypass country blocking and the URL they are redirected to are the same. This would cause a circular redirect. Please fix this.");
|
1364 |
-
return;
|
1365 |
-
}
|
1366 |
-
}
|
1367 |
-
if(bypassRedirURL && (! /^(?:\/|http:\/\/)/.test(bypassRedirURL))){ this.invalidCountryURLMsg(bypassRedirURL); return; }
|
1368 |
-
if(bypassRedirDest && (! /^(?:\/|http:\/\/)/.test(bypassRedirDest))){ this.invalidCountryURLMsg(bypassRedirDest); return; }
|
1369 |
-
if(bypassViewURL && (! /^(?:\/|http:\/\/)/.test(bypassViewURL))){ this.invalidCountryURLMsg(bypassViewURL); return; }
|
1370 |
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1380 |
}
|
1381 |
-
}
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
confirmSaveCountryBlocking: function(){
|
1396 |
-
var action = jQuery('#wfBlockAction').val();
|
1397 |
-
var redirURL = jQuery('#wfRedirURL').val();
|
1398 |
-
var loggedInBlocked = jQuery('#wfLoggedInBlocked').is(':checked') ? '1' : '0';
|
1399 |
-
var loginFormBlocked = jQuery('#wfLoginFormBlocked').is(':checked') ? '1' : '0';
|
1400 |
-
var restOfSiteBlocked = jQuery('#wfRestOfSiteBlocked').is(':checked') ? '1' : '0';
|
1401 |
-
var bypassRedirURL = jQuery('#wfBypassRedirURL').val();
|
1402 |
-
var bypassRedirDest = jQuery('#wfBypassRedirDest').val();
|
1403 |
-
var bypassViewURL = jQuery('#wfBypassViewURL').val();
|
1404 |
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
});
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
var
|
1476 |
-
|
1477 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1478 |
}
|
1479 |
-
}
|
1480 |
-
}
|
1481 |
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1503 |
});
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
username: username,
|
1515 |
-
phone: phone
|
1516 |
-
}, function(res){
|
1517 |
-
if(res.ok){
|
1518 |
-
self.twoFacStatus('User added! Check the user\'s phone to get the activation code.');
|
1519 |
-
jQuery('<div id="twoFacCont_' + res.userID + '">' + jQuery('#wfTwoFacUserTmpl').tmpl(res).html() + '</div>').prependTo(jQuery('#wfTwoFacUsers'));
|
1520 |
-
}
|
1521 |
-
});
|
1522 |
-
},
|
1523 |
-
twoFacActivate: function(userID, code){
|
1524 |
-
var self = this;
|
1525 |
-
this.ajax('wordfence_twoFacActivate', {
|
1526 |
-
userID: userID,
|
1527 |
-
code: code
|
1528 |
-
}, function(res){
|
1529 |
-
if(res.ok){
|
1530 |
-
jQuery('#twoFacCont_' + res.userID).html(
|
1531 |
-
jQuery('#wfTwoFacUserTmpl').tmpl(res)
|
1532 |
);
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1553 |
}
|
1554 |
-
}
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
var d = dot.split('.');
|
1570 |
-
return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
|
1571 |
-
},
|
1572 |
-
inet_ntoa: function(num){
|
1573 |
-
var d = num % 256;
|
1574 |
-
for(var i = 3; i > 0; i--) {
|
1575 |
-
num = Math.floor(num/256);
|
1576 |
-
d = num%256 + '.' + d;
|
1577 |
-
}
|
1578 |
-
return d;
|
1579 |
-
},
|
1580 |
-
removeCacheExclusion: function(id){
|
1581 |
-
this.ajax('wordfence_removeCacheExclusion', { id: id }, function(res){ window.location.reload(true); });
|
1582 |
-
},
|
1583 |
-
addCacheExclusion: function(patternType, pattern){
|
1584 |
-
if(/^https?:\/\//.test(pattern)){
|
1585 |
-
this.colorbox('400px', "Incorrect pattern for exclusion", "You can not enter full URL's for exclusion from caching. You entered a full URL that started with http:// or https://. You must enter relative URL's e.g. /exclude/this/page/. You can also enter text that might be contained in the path part of a URL or at the end of the path part of a URL.");
|
1586 |
-
return;
|
1587 |
-
}
|
1588 |
-
|
1589 |
-
this.ajax('wordfence_addCacheExclusion', {
|
1590 |
-
patternType: patternType,
|
1591 |
-
pattern: pattern
|
1592 |
-
}, function(res){
|
1593 |
-
if(res.ok){ //Otherwise errorMsg will get caught
|
1594 |
window.location.reload(true);
|
|
|
|
|
|
|
|
|
|
|
|
|
1595 |
}
|
1596 |
-
});
|
1597 |
-
},
|
1598 |
-
loadCacheExclusions: function(){
|
1599 |
-
this.ajax('wordfence_loadCacheExclusions', {}, function(res){
|
1600 |
-
if(res.ex instanceof Array && res.ex.length > 0){
|
1601 |
-
for(var i = 0; i < res.ex.length; i++){
|
1602 |
-
var newElem = jQuery('#wfCacheExclusionTmpl').tmpl(res.ex[i]);
|
1603 |
-
newElem.prependTo('#wfCacheExclusions').fadeIn();
|
1604 |
-
}
|
1605 |
-
jQuery('<h2>Cache Exclusions</h2>').prependTo('#wfCacheExclusions');
|
1606 |
-
} else {
|
1607 |
-
jQuery('<h2>Cache Exclusions</h2><p style="width: 500px;">There are not currently any exclusions. If you have a site that does not change often, it is perfectly normal to not have any pages you want to exclude from the cache.</p>').prependTo('#wfCacheExclusions');
|
1608 |
-
}
|
1609 |
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1633 |
}
|
1634 |
-
}
|
|
|
1635 |
}
|
1636 |
-
|
1637 |
-
|
1638 |
-
}
|
1639 |
-
jQuery
|
1640 |
-
wordfenceAdmin.init();
|
1641 |
-
});
|
1 |
+
(function($) {
|
2 |
+
if (!window['wordfenceAdmin']) { //To compile for checking: java -jar /usr/local/bin/closure.jar --js=admin.js --js_output_file=test.js
|
3 |
+
window['wordfenceAdmin'] = {
|
4 |
+
loading16: '<div class="wfLoading16"></div>',
|
5 |
+
loadingCount: 0,
|
6 |
+
dbCheckTables: [],
|
7 |
+
dbCheckCount_ok: 0,
|
8 |
+
dbCheckCount_skipped: 0,
|
9 |
+
dbCheckCount_errors: 0,
|
10 |
+
issues: [],
|
11 |
+
ignoreData: false,
|
12 |
+
iconErrorMsgs: [],
|
13 |
+
scanIDLoaded: 0,
|
14 |
+
colorboxQueue: [],
|
15 |
+
mode: '',
|
16 |
+
visibleIssuesPanel: 'new',
|
17 |
+
preFirstScanMsgsLoaded: false,
|
18 |
+
newestActivityTime: 0, //must be 0 to force loading of all initially
|
19 |
+
elementGeneratorIter: 1,
|
20 |
+
reloadConfigPage: false,
|
21 |
+
nonce: false,
|
22 |
+
tickerUpdatePending: false,
|
23 |
+
activityLogUpdatePending: false,
|
24 |
+
lastALogCtime: 0,
|
25 |
+
activityQueue: [],
|
26 |
+
totalActAdded: 0,
|
27 |
+
maxActivityLogItems: 1000,
|
28 |
+
scanReqAnimation: false,
|
29 |
+
debugOn: false,
|
30 |
+
blockedCountriesPending: [],
|
31 |
+
ownCountry: "",
|
32 |
+
schedStartHour: false,
|
33 |
+
currentPointer: false,
|
34 |
+
countryMap: false,
|
35 |
+
countryCodesToSave: "",
|
36 |
+
performanceScale: 3,
|
37 |
+
performanceMinWidth: 20,
|
38 |
+
tourClosed: false,
|
39 |
+
welcomeClosed: false,
|
40 |
+
passwdAuditUpdateInt: false,
|
41 |
+
init: function() {
|
42 |
+
this.nonce = WordfenceAdminVars.firstNonce;
|
43 |
+
this.debugOn = WordfenceAdminVars.debugOn == '1' ? true : false;
|
44 |
+
this.tourClosed = WordfenceAdminVars.tourClosed == '1' ? true : false;
|
45 |
+
this.welcomeClosed = WordfenceAdminVars.welcomeClosed == '1' ? true : false;
|
46 |
+
var startTicker = false;
|
47 |
+
var self = this;
|
48 |
+
if (jQuery('#wordfenceMode_scan').length > 0) {
|
49 |
+
this.mode = 'scan';
|
50 |
+
jQuery('#wfALogViewLink').prop('href', WordfenceAdminVars.siteBaseURL + '?_wfsf=viewActivityLog&nonce=' + this.nonce);
|
51 |
+
jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
|
52 |
+
jQuery('#consoleScan').scrollTop(jQuery('#consoleScan').prop('scrollHeight'));
|
53 |
+
this.noScanHTML = jQuery('#wfNoScanYetTmpl').tmpl().html();
|
54 |
+
this.loadIssues();
|
55 |
+
this.startActivityLogUpdates();
|
56 |
+
if (this.needTour()) {
|
57 |
+
this.scanTourStart();
|
58 |
+
}
|
59 |
+
} else if (jQuery('#wordfenceMode_activity').length > 0) {
|
60 |
+
this.mode = 'activity';
|
61 |
+
this.setupSwitches('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
|
62 |
+
});
|
63 |
+
jQuery('#wfLiveTrafficOnOff').change(function() {
|
64 |
+
if (/^(?:falcon|php)$/.test(WordfenceAdminVars.cacheType)) {
|
65 |
+
jQuery('#wfLiveTrafficOnOff').attr('checked', false);
|
66 |
+
self.colorbox('400px', "Live Traffic not available in high performance mode", "Please note that you can't enable live traffic when Falcon Engine or basic caching is enabled. This is done for performance reasons. If you want live traffic, go to the 'Performance Setup' menu and disable caching.");
|
67 |
+
} else {
|
68 |
+
self.updateSwitch('wfLiveTrafficOnOff', 'liveTrafficEnabled', function() {
|
69 |
+
window.location.reload(true);
|
70 |
+
});
|
71 |
+
}
|
72 |
+
});
|
73 |
|
74 |
+
if (WordfenceAdminVars.liveTrafficEnabled) {
|
75 |
+
this.activityMode = 'hit';
|
76 |
+
} else {
|
77 |
+
this.activityMode = 'loginLogout';
|
78 |
+
this.switchTab(jQuery('#wfLoginLogoutTab'), 'wfTab1', 'wfDataPanel', 'wfActivity_loginLogout', function() {
|
79 |
+
WFAD.activityTabChanged();
|
80 |
+
});
|
81 |
+
}
|
82 |
+
startTicker = true;
|
83 |
+
if (this.needTour()) {
|
84 |
+
this.tour('wfWelcomeContent3', 'wfHeading', 'top', 'left', "Learn about Site Performance", function() {
|
85 |
+
self.tourRedir('WordfenceSitePerf');
|
86 |
+
});
|
87 |
+
}
|
88 |
+
} else if (jQuery('#wordfenceMode_options').length > 0) {
|
89 |
+
this.mode = 'options';
|
90 |
+
jQuery('.wfConfigElem').change(function() {
|
91 |
+
jQuery('#securityLevel').val('CUSTOM');
|
92 |
+
});
|
93 |
+
this.updateTicker(true);
|
94 |
+
startTicker = true;
|
95 |
+
if (this.needTour()) {
|
96 |
+
this.tour('wfContentBasicOptions', 'wfMarkerBasicOptions', 'top', 'left', "Learn about Live Traffic Options", function() {
|
97 |
+
self.tour('wfContentLiveTrafficOptions', 'wfMarkerLiveTrafficOptions', 'bottom', 'left', "Learn about Scanning Options", function() {
|
98 |
+
self.tour('wfContentScansToInclude', 'wfMarkerScansToInclude', 'bottom', 'left', "Learn about Firewall Rules", function() {
|
99 |
+
self.tour('wfContentFirewallRules', 'wfMarkerFirewallRules', 'bottom', 'left', "Learn about Login Security", function() {
|
100 |
+
self.tour('wfContentLoginSecurity', 'wfMarkerLoginSecurity', 'bottom', 'left', "Learn about Other Options", function() {
|
101 |
+
self.tour('wfContentOtherOptions', 'wfMarkerOtherOptions', 'bottom', 'left', false, false);
|
102 |
+
});
|
103 |
});
|
104 |
});
|
105 |
});
|
106 |
});
|
107 |
+
}
|
108 |
+
} else if (jQuery('#wordfenceMode_blockedIPs').length > 0) {
|
109 |
+
this.mode = 'blocked';
|
110 |
+
this.staticTabChanged();
|
111 |
+
this.updateTicker(true);
|
112 |
+
startTicker = true;
|
113 |
+
if (this.needTour()) {
|
114 |
+
this.tour('wfWelcomeContent4', 'wfHeading', 'top', 'left', "Learn about Auditing Passwords", function() {
|
115 |
+
self.tourRedir('WordfencePasswdAudit');
|
116 |
+
});
|
117 |
+
}
|
118 |
+
} else if (jQuery('#wordfenceMode_passwd').length > 0) {
|
119 |
+
this.mode = 'passwd';
|
120 |
+
startTicker = false;
|
121 |
+
this.doPasswdAuditUpdate();
|
122 |
+
if (this.needTour()) {
|
123 |
+
this.tour('wfWelcomePasswd', 'wfHeading', 'top', 'left', "Learn about Cellphone Sign-in", function() {
|
124 |
+
self.tourRedir('WordfenceTwoFactor');
|
125 |
+
});
|
126 |
+
}
|
127 |
+
} else if (jQuery('#wordfenceMode_twoFactor').length > 0) {
|
128 |
+
this.mode = 'twoFactor';
|
129 |
+
startTicker = false;
|
130 |
+
if (this.needTour()) {
|
131 |
+
this.tour('wfWelcomeTwoFactor', 'wfHeading', 'top', 'left', "Learn how to Block Countries", function() {
|
132 |
+
self.tourRedir('WordfenceCountryBlocking');
|
133 |
+
});
|
134 |
+
}
|
135 |
+
this.loadTwoFactor();
|
136 |
+
|
137 |
+
} else if (jQuery('#wordfenceMode_countryBlocking').length > 0) {
|
138 |
+
this.mode = 'countryBlocking';
|
139 |
+
startTicker = false;
|
140 |
+
if (this.needTour()) {
|
141 |
+
this.tour('wfWelcomeContentCntBlk', 'wfHeading', 'top', 'left', "Learn how to Schedule Scans", function() {
|
142 |
+
self.tourRedir('WordfenceScanSchedule');
|
143 |
+
});
|
144 |
+
}
|
145 |
+
} else if (jQuery('#wordfenceMode_rangeBlocking').length > 0) {
|
146 |
+
this.mode = 'rangeBlocking';
|
147 |
+
startTicker = false;
|
148 |
+
if (this.needTour()) {
|
149 |
+
this.tour('wfWelcomeContentRangeBlocking', 'wfHeading', 'top', 'left', "Learn how to Customize Wordfence", function() {
|
150 |
+
self.tourRedir('WordfenceSecOpt');
|
151 |
+
});
|
152 |
+
}
|
153 |
+
this.calcRangeTotal();
|
154 |
+
this.loadBlockRanges();
|
155 |
+
} else if (jQuery('#wordfenceMode_whois').length > 0) {
|
156 |
+
this.mode = 'whois';
|
157 |
+
startTicker = false;
|
158 |
+
if (this.needTour()) {
|
159 |
+
this.tour('wfWelcomeContentWhois', 'wfHeading', 'top', 'left', "Learn how to use Advanced Blocking", function() {
|
160 |
+
self.tourRedir('WordfenceRangeBlocking');
|
161 |
+
});
|
162 |
+
}
|
163 |
+
this.calcRangeTotal();
|
164 |
+
this.loadBlockRanges();
|
165 |
+
|
166 |
+
} else if (jQuery('#wordfenceMode_scanScheduling').length > 0) {
|
167 |
+
this.mode = 'scanScheduling';
|
168 |
+
startTicker = false;
|
169 |
+
this.sched_modeChange();
|
170 |
+
if (this.needTour()) {
|
171 |
+
this.tour('wfWelcomeContentScanSched', 'wfHeading', 'top', 'left', "Learn about WHOIS", function() {
|
172 |
+
self.tourRedir('WordfenceWhois');
|
173 |
+
});
|
174 |
+
}
|
175 |
+
} else if (jQuery('#wordfenceMode_caching').length > 0) {
|
176 |
+
this.mode = 'caching';
|
177 |
+
startTicker = false;
|
178 |
+
if (this.needTour()) {
|
179 |
+
this.tour('wfWelcomeContentCaching', 'wfHeading', 'top', 'left', "Learn about IP Blocking", function() {
|
180 |
+
self.tourRedir('WordfenceBlockedIPs');
|
181 |
+
});
|
182 |
+
}
|
183 |
+
this.loadCacheExclusions();
|
184 |
+
} else {
|
185 |
+
this.mode = false;
|
186 |
+
}
|
187 |
+
if (this.mode) { //We are in a Wordfence page
|
188 |
+
if (startTicker) {
|
189 |
+
this.updateTicker();
|
190 |
+
this.liveInt = setInterval(function() {
|
191 |
+
self.updateTicker();
|
192 |
+
}, WordfenceAdminVars.actUpdateInterval);
|
193 |
+
}
|
194 |
+
jQuery(document).bind('cbox_closed', function() {
|
195 |
+
self.colorboxIsOpen = false;
|
196 |
+
self.colorboxServiceQueue();
|
197 |
});
|
198 |
+
}
|
199 |
+
},
|
200 |
+
needTour: function() {
|
201 |
+
if ((!this.tourClosed) && this.welcomeClosed) {
|
202 |
+
return true;
|
203 |
+
} else {
|
204 |
+
return false;
|
205 |
+
}
|
206 |
+
},
|
207 |
+
sendTestEmail: function(email) {
|
208 |
+
var self = this;
|
209 |
+
this.ajax('wordfence_sendTestEmail', {email: email}, function(res) {
|
210 |
+
if (res.result) {
|
211 |
+
self.colorbox('400px', "Test Email Sent", "Your test email was sent to the requested email address. The result we received from the WordPress wp_mail() function was: " +
|
212 |
+
res.result + "<br /><br />A 'True' result means WordPress thinks the mail was sent without errors. A 'False' result means that WordPress encountered an error sending your mail. Note that it's possible to get a 'True' response with an error elsewhere in your mail system that may cause emails to not be delivered.");
|
213 |
+
}
|
214 |
+
});
|
215 |
+
},
|
216 |
+
loadAvgSitePerf: function() {
|
217 |
+
var self = this;
|
218 |
+
this.ajax('wordfence_loadAvgSitePerf', {limit: jQuery('#wfAvgPerfNum').val()}, function(res) {
|
219 |
+
res['scale'] = self.performanceScale;
|
220 |
+
res['min'] = self.performanceMinWidth;
|
221 |
+
jQuery('#wfAvgSitePerfContent').empty();
|
222 |
+
var newElem = jQuery('#wfAvgPerfTmpl').tmpl(res);
|
223 |
+
newElem.prependTo('#wfAvgSitePerfContent').fadeIn();
|
224 |
+
});
|
225 |
+
},
|
226 |
+
updateSwitch: function(elemID, configItem, cb) {
|
227 |
+
var setting = jQuery('#' + elemID).is(':checked');
|
228 |
+
this.updateConfig(configItem, jQuery('#' + elemID).is(':checked') ? 1 : 0, cb);
|
229 |
+
},
|
230 |
+
setupSwitches: function(elemID, configItem, cb) {
|
231 |
+
jQuery('.wfOnOffSwitch-checkbox').change(function() {
|
232 |
+
jQuery.data(this, 'lastSwitchChange', (new Date()).getTime());
|
233 |
+
});
|
234 |
+
var self = this;
|
235 |
+
jQuery('div.wfOnOffSwitch').mouseup(function() {
|
236 |
+
var elem = jQuery(this);
|
237 |
+
setTimeout(function() {
|
238 |
+
var checkedElem = elem.find('.wfOnOffSwitch-checkbox');
|
239 |
+
if ((new Date()).getTime() - jQuery.data(checkedElem[0], 'lastSwitchChange') > 300) {
|
240 |
+
checkedElem.prop('checked', !checkedElem.is(':checked'));
|
241 |
+
self.updateSwitch(elemID, configItem, cb);
|
242 |
+
}
|
243 |
+
}, 50);
|
244 |
+
});
|
245 |
+
},
|
246 |
+
scanTourStart: function() {
|
247 |
+
var self = this;
|
248 |
+
this.tour('wfWelcomeContent1', 'wfHeading', 'top', 'left', "Continue the Tour", function() {
|
249 |
+
self.tour('wfWelcomeContent2', 'wfHeading', 'top', 'left', "Learn how to use Wordfence", function() {
|
250 |
+
self.tour('wfWelcomeContent3', 'wfHeading', 'top', 'left', "Learn about Live Traffic", function() {
|
251 |
+
self.tourRedir('WordfenceActivity');
|
252 |
+
});
|
253 |
+
});
|
254 |
+
});
|
255 |
+
},
|
256 |
+
tourRedir: function(menuItem) {
|
257 |
+
window.location.href = 'admin.php?page=' + menuItem;
|
258 |
+
},
|
259 |
+
updateConfig: function(key, val, cb) {
|
260 |
+
this.ajax('wordfence_updateConfig', {key: key, val: val}, function() {
|
261 |
+
cb();
|
262 |
+
});
|
263 |
+
},
|
264 |
+
tourFinish: function() {
|
265 |
+
this.ajax('wordfence_tourClosed', {}, function(res) {
|
266 |
+
});
|
267 |
+
},
|
268 |
+
downgradeLicense: function() {
|
269 |
+
this.colorbox('400px', "Confirm Downgrade", "Are you sure you want to downgrade your Wordfence Premium License? This will disable all Premium features and return you to the free version of Wordfence. <a href=\"https://www.wordfence.com/manage-wordfence-api-keys/\" target=\"_blank\">Click here to renew your paid membership</a> or click the button below to confirm you want to downgrade.<br /><br /><input type=\"button\" value=\"Downgrade and disable Premium features\" onclick=\"WFAD.downgradeLicenseConfirm();\" /><br />");
|
270 |
+
},
|
271 |
+
downgradeLicenseConfirm: function() {
|
272 |
+
jQuery.colorbox.close();
|
273 |
+
this.ajax('wordfence_downgradeLicense', {}, function(res) {
|
274 |
+
location.reload(true);
|
275 |
+
});
|
276 |
+
},
|
277 |
+
tour: function(contentID, elemID, edge, align, buttonLabel, buttonCallback) {
|
278 |
+
var self = this;
|
279 |
+
if (this.currentPointer) {
|
280 |
+
this.currentPointer.pointer('destroy');
|
281 |
+
this.currentPointer = false;
|
282 |
+
}
|
283 |
+
var options = {
|
284 |
+
buttons: function(event, t) {
|
285 |
+
var buttonElem = jQuery('<div id="wfTourButCont"><a id="pointer-close" style="margin-left:5px" class="button-secondary">End the Tour</a></div><div><a id="wfRateLink" href="http://wordpress.org/extend/plugins/wordfence/" target="_blank" style="font-size: 10px; font-family: Verdana;">Help spread the word by rating us 5★ on WordPress.org</a></div>');
|
286 |
+
buttonElem.find('#pointer-close').bind('click.pointer', function(evtObj) {
|
287 |
+
var evtSourceElem = evtObj.srcElement ? evtObj.srcElement : evtObj.target;
|
288 |
+
if (evtSourceElem.id == 'wfRateLink') {
|
289 |
+
return true;
|
290 |
+
}
|
291 |
+
self.tourFinish();
|
292 |
+
t.element.pointer('close');
|
293 |
+
return false;
|
294 |
+
});
|
295 |
+
return buttonElem;
|
296 |
+
},
|
297 |
+
close: function() {
|
298 |
+
},
|
299 |
+
content: jQuery('#' + contentID).tmpl().html(),
|
300 |
+
pointerWidth: 400,
|
301 |
+
position: {
|
302 |
+
edge: edge,
|
303 |
+
align: align
|
304 |
+
}
|
305 |
+
};
|
306 |
+
this.currentPointer = jQuery('#' + elemID).pointer(options).pointer('open');
|
307 |
+
if (buttonLabel && buttonCallback) {
|
308 |
+
jQuery('#pointer-close').after('<a id="pointer-primary" class="button-primary">' + buttonLabel + '</a>');
|
309 |
+
jQuery('#pointer-primary').click(buttonCallback);
|
310 |
+
}
|
311 |
+
},
|
312 |
+
startTourAgain: function() {
|
313 |
+
var self = this;
|
314 |
+
this.ajax('wordfence_startTourAgain', {}, function(res) {
|
315 |
+
self.tourClosed = false;
|
316 |
+
self.scanTourStart();
|
317 |
+
});
|
318 |
+
},
|
319 |
+
showLoading: function() {
|
320 |
+
this.loadingCount++;
|
321 |
+
if (this.loadingCount == 1) {
|
322 |
+
jQuery('<div id="wordfenceWorking">Wordfence is working...</div>').appendTo('body');
|
323 |
+
}
|
324 |
+
},
|
325 |
+
removeLoading: function() {
|
326 |
+
this.loadingCount--;
|
327 |
+
if (this.loadingCount == 0) {
|
328 |
+
jQuery('#wordfenceWorking').remove();
|
329 |
+
}
|
330 |
+
},
|
331 |
+
startActivityLogUpdates: function() {
|
332 |
+
var self = this;
|
333 |
+
setInterval(function() {
|
334 |
+
self.updateActivityLog();
|
335 |
+
}, parseInt(WordfenceAdminVars.actUpdateInterval));
|
336 |
+
},
|
337 |
+
updateActivityLog: function() {
|
338 |
+
if (this.activityLogUpdatePending) {
|
339 |
+
return;
|
340 |
+
}
|
341 |
+
this.activityLogUpdatePending = true;
|
342 |
+
var self = this;
|
343 |
+
this.ajax('wordfence_activityLogUpdate', {
|
344 |
+
lastctime: this.lastALogCtime
|
345 |
+
}, function(res) {
|
346 |
+
self.doneUpdateActivityLog(res);
|
347 |
+
}, function() {
|
348 |
+
self.activityLogUpdatePending = false;
|
349 |
+
}, true);
|
350 |
|
351 |
+
},
|
352 |
+
doneUpdateActivityLog: function(res) {
|
353 |
+
this.actNextUpdateAt = (new Date()).getTime() + parseInt(WordfenceAdminVars.actUpdateInterval);
|
354 |
+
if (res.ok) {
|
355 |
+
if (res.items.length > 0) {
|
356 |
+
this.activityQueue.push.apply(this.activityQueue, res.items);
|
357 |
+
this.lastALogCtime = res.items[res.items.length - 1].ctime;
|
358 |
+
this.processActQueue(res.currentScanID);
|
359 |
+
}
|
360 |
+
}
|
361 |
+
this.activityLogUpdatePending = false;
|
362 |
+
},
|
363 |
+
processActQueue: function(currentScanID) {
|
364 |
+
if (this.activityQueue.length > 0) {
|
365 |
+
this.addActItem(this.activityQueue.shift());
|
366 |
+
this.totalActAdded++;
|
367 |
+
if (this.totalActAdded > this.maxActivityLogItems) {
|
368 |
+
jQuery('#consoleActivity div:first').remove();
|
369 |
+
this.totalActAdded--;
|
370 |
+
}
|
371 |
+
var timeTillNextUpdate = this.actNextUpdateAt - (new Date()).getTime();
|
372 |
+
var maxRate = 50 / 1000; //Rate per millisecond
|
373 |
+
var bulkTotal = 0;
|
374 |
+
while (this.activityQueue.length > 0 && this.activityQueue.length / timeTillNextUpdate > maxRate) {
|
375 |
+
var item = this.activityQueue.shift();
|
376 |
+
if (item) {
|
377 |
+
bulkTotal++;
|
378 |
+
this.addActItem(item);
|
379 |
+
}
|
380 |
+
}
|
381 |
+
this.totalActAdded += bulkTotal;
|
382 |
+
if (this.totalActAdded > this.maxActivityLogItems) {
|
383 |
+
jQuery('#consoleActivity div:lt(' + bulkTotal + ')').remove();
|
384 |
+
this.totalActAdded -= bulkTotal;
|
385 |
+
}
|
386 |
+
var minDelay = 100;
|
387 |
+
var delay = minDelay;
|
388 |
+
if (timeTillNextUpdate < 1) {
|
389 |
+
delay = minDelay;
|
390 |
+
} else {
|
391 |
+
delay = Math.round(timeTillNextUpdate / this.activityQueue.length);
|
392 |
+
if (delay < minDelay) {
|
393 |
+
delay = minDelay;
|
394 |
+
}
|
395 |
+
}
|
396 |
+
var self = this;
|
397 |
+
setTimeout(function() {
|
398 |
+
self.processActQueue();
|
399 |
+
}, delay);
|
400 |
+
}
|
401 |
+
jQuery('#consoleActivity').scrollTop(jQuery('#consoleActivity').prop('scrollHeight'));
|
402 |
+
},
|
403 |
+
processActArray: function(arr) {
|
404 |
+
for (var i = 0; i < arr.length; i++) {
|
405 |
+
this.addActItem(arr[i]);
|
406 |
+
}
|
407 |
+
},
|
408 |
+
addActItem: function(item) {
|
409 |
+
if (!item) {
|
410 |
+
return;
|
411 |
+
}
|
412 |
+
if (!item.msg) {
|
413 |
+
return;
|
414 |
+
}
|
415 |
+
if (item.msg.indexOf('SUM_') == 0) {
|
416 |
+
this.processSummaryLine(item);
|
417 |
+
jQuery('#consoleSummary').scrollTop(jQuery('#consoleSummary').prop('scrollHeight'));
|
418 |
+
jQuery('#wfStartingScan').addClass('wfSummaryOK').html('Done.');
|
419 |
+
} else if (this.debugOn || item.level < 4) {
|
420 |
|
421 |
+
var html = '<div class="wfActivityLine';
|
422 |
+
if (this.debugOn) {
|
423 |
+
html += ' wf' + item.type;
|
424 |
+
}
|
425 |
+
html += '">[' + item.date + '] ' + item.msg + '</div>';
|
426 |
+
jQuery('#consoleActivity').append(html);
|
427 |
+
if (/Scan complete\./i.test(item.msg)) {
|
428 |
+
this.loadIssues();
|
429 |
+
}
|
430 |
+
}
|
431 |
+
},
|
432 |
+
processSummaryLine: function(item) {
|
433 |
+
var msg, summaryUpdated;
|
434 |
+
if (item.msg.indexOf('SUM_START:') != -1) {
|
435 |
+
msg = item.msg.replace('SUM_START:', '');
|
436 |
+
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
|
437 |
+
summaryUpdated = true;
|
438 |
+
} else if (item.msg.indexOf('SUM_ENDBAD') != -1) {
|
439 |
+
msg = item.msg.replace('SUM_ENDBAD:', '');
|
440 |
+
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryBad').html('Problems found.');
|
441 |
+
summaryUpdated = true;
|
442 |
+
} else if (item.msg.indexOf('SUM_ENDFAILED') != -1) {
|
443 |
+
msg = item.msg.replace('SUM_ENDFAILED:', '');
|
444 |
+
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryBad').html('Failed.');
|
445 |
+
summaryUpdated = true;
|
446 |
+
} else if (item.msg.indexOf('SUM_ENDOK') != -1) {
|
447 |
+
msg = item.msg.replace('SUM_ENDOK:', '');
|
448 |
+
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryOK').html('Secure.');
|
449 |
+
summaryUpdated = true;
|
450 |
+
} else if (item.msg.indexOf('SUM_ENDSUCCESS') != -1) {
|
451 |
+
msg = item.msg.replace('SUM_ENDSUCCESS:', '');
|
452 |
+
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryOK').html('Success.');
|
453 |
+
summaryUpdated = true;
|
454 |
+
} else if (item.msg.indexOf('SUM_ENDERR') != -1) {
|
455 |
+
msg = item.msg.replace('SUM_ENDERR:', '');
|
456 |
+
jQuery('div.wfSummaryMsg:contains("' + msg + '")').next().addClass('wfSummaryErr').html('An error occurred.');
|
457 |
+
summaryUpdated = true;
|
458 |
+
} else if (item.msg.indexOf('SUM_DISABLED:') != -1) {
|
459 |
+
msg = item.msg.replace('SUM_DISABLED:', '');
|
460 |
+
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult">Disabled [<a href="admin.php?page=WordfenceSecOpt">Visit Options to Enable</a>]</div><div class="wfClear"></div>');
|
461 |
+
summaryUpdated = true;
|
462 |
+
} else if (item.msg.indexOf('SUM_PAIDONLY:') != -1) {
|
463 |
+
msg = item.msg.replace('SUM_PAIDONLY:', '');
|
464 |
+
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult"><a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Paid Members Only</a></div><div class="wfClear"></div>');
|
465 |
+
summaryUpdated = true;
|
466 |
+
} else if (item.msg.indexOf('SUM_FINAL:') != -1) {
|
467 |
+
msg = item.msg.replace('SUM_FINAL:', '');
|
468 |
+
jQuery('#consoleSummary').append('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg wfSummaryFinal">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
|
469 |
+
} else if (item.msg.indexOf('SUM_PREP:') != -1) {
|
470 |
+
msg = item.msg.replace('SUM_PREP:', '');
|
471 |
+
jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult" id="wfStartingScan"><div class="wfSummaryLoading"></div></div><div class="wfClear"></div>');
|
472 |
+
} else if (item.msg.indexOf('SUM_KILLED:') != -1) {
|
473 |
+
msg = item.msg.replace('SUM_KILLED:', '');
|
474 |
+
jQuery('#consoleSummary').empty().html('<div class="wfSummaryLine"><div class="wfSummaryDate">[' + item.date + ']</div><div class="wfSummaryMsg">' + msg + '</div><div class="wfSummaryResult wfSummaryOK">Scan Complete.</div><div class="wfClear"></div>');
|
475 |
+
}
|
476 |
+
},
|
477 |
+
processActQueueItem: function() {
|
478 |
+
var item = this.activityQueue.shift();
|
479 |
+
if (item) {
|
480 |
+
jQuery('#consoleActivity').append('<div class="wfActivityLine wf' + item.type + '">[' + item.date + '] ' + item.msg + '</div>');
|
481 |
+
this.totalActAdded++;
|
482 |
+
if (this.totalActAdded > this.maxActivityLogItems) {
|
483 |
+
jQuery('#consoleActivity div:first').remove();
|
484 |
+
this.totalActAdded--;
|
485 |
+
}
|
486 |
+
if (item.msg == 'Scan complete.') {
|
487 |
+
this.loadIssues();
|
488 |
+
}
|
489 |
+
}
|
490 |
+
},
|
491 |
+
updateTicker: function(forceUpdate) {
|
492 |
+
if ((!forceUpdate) && this.tickerUpdatePending) {
|
493 |
+
return;
|
494 |
+
}
|
495 |
+
this.tickerUpdatePending = true;
|
496 |
+
var self = this;
|
497 |
+
var alsoGet = '';
|
498 |
+
var otherParams = '';
|
499 |
+
if (this.mode == 'activity' && /^(?:404|hit|human|ruser|gCrawler|crawler|loginLogout)$/.test(this.activityMode)) {
|
500 |
+
alsoGet = 'logList_' + this.activityMode;
|
501 |
+
otherParams = this.newestActivityTime;
|
502 |
+
} else if (this.mode == 'perfStats') {
|
503 |
+
alsoGet = 'perfStats';
|
504 |
+
otherParams = this.newestActivityTime;
|
505 |
+
}
|
506 |
+
this.ajax('wordfence_ticker', {
|
507 |
+
alsoGet: alsoGet,
|
508 |
+
otherParams: otherParams
|
509 |
+
}, function(res) {
|
510 |
+
self.handleTickerReturn(res);
|
511 |
+
}, function() {
|
512 |
+
self.tickerUpdatePending = false;
|
513 |
+
}, true);
|
514 |
+
},
|
515 |
+
handleTickerReturn: function(res) {
|
516 |
+
this.tickerUpdatePending = false;
|
517 |
+
var newMsg = "";
|
518 |
+
var oldMsg = jQuery('#wfLiveStatus').text();
|
519 |
+
if (res.msg) {
|
520 |
+
newMsg = res.msg;
|
521 |
+
} else {
|
522 |
+
newMsg = "Idle";
|
523 |
+
}
|
524 |
+
if (newMsg && newMsg != oldMsg) {
|
525 |
+
jQuery('#wfLiveStatus').hide().html(newMsg).fadeIn(200);
|
526 |
+
}
|
527 |
+
var haveEvents, newElem;
|
528 |
+
if (this.mode == 'activity') {
|
529 |
+
if (res.alsoGet != 'logList_' + this.activityMode) {
|
530 |
+
return;
|
531 |
+
} //user switched panels since ajax request started
|
532 |
+
if (res.events.length > 0) {
|
533 |
+
this.newestActivityTime = res.events[0]['ctime'];
|
534 |
+
}
|
535 |
+
haveEvents = false;
|
536 |
+
if (jQuery('#wfActivity_' + this.activityMode + ' .wfActEvent').length > 0) {
|
537 |
+
haveEvents = true;
|
538 |
+
}
|
539 |
+
if (res.events.length > 0) {
|
540 |
+
if (!haveEvents) {
|
541 |
+
jQuery('#wfActivity_' + this.activityMode).empty();
|
542 |
+
}
|
543 |
+
for (i = res.events.length - 1; i >= 0; i--) {
|
544 |
+
var elemID = '#wfActEvent_' + res.events[i].id;
|
545 |
+
if (jQuery(elemID).length < 1) {
|
546 |
+
res.events[i]['activityMode'] = this.activityMode;
|
547 |
+
if (this.activityMode == 'loginLogout') {
|
548 |
+
newElem = jQuery('#wfLoginLogoutEventTmpl').tmpl(res.events[i]);
|
549 |
+
} else {
|
550 |
+
newElem = jQuery('#wfHitsEventTmpl').tmpl(res.events[i]);
|
551 |
+
}
|
552 |
+
jQuery(newElem).find('.wfTimeAgo').data('wfctime', res.events[i].ctime);
|
553 |
+
newElem.prependTo('#wfActivity_' + this.activityMode).fadeIn();
|
554 |
+
}
|
555 |
+
}
|
556 |
+
this.reverseLookupIPs();
|
557 |
+
} else {
|
558 |
+
if (!haveEvents) {
|
559 |
+
jQuery('#wfActivity_' + this.activityMode).html('<div>No events to report yet.</div>');
|
560 |
+
}
|
561 |
+
}
|
562 |
+
var self = this;
|
563 |
+
jQuery('.wfTimeAgo').each(function(idx, elem) {
|
564 |
+
jQuery(elem).html(self.makeTimeAgo(res.serverTime - jQuery(elem).data('wfctime')) + ' ago');
|
565 |
+
});
|
566 |
+
} else if (this.mode == 'perfStats') {
|
567 |
+
haveEvents = false;
|
568 |
+
if (jQuery('#wfPerfStats .wfPerfEvent').length > 0) {
|
569 |
+
haveEvents = true;
|
570 |
+
}
|
571 |
+
if (res.events.length > 0) {
|
572 |
+
if (!haveEvents) {
|
573 |
+
jQuery('#wfPerfStats').empty();
|
574 |
+
}
|
575 |
+
var curLength = parseInt(jQuery('#wfPerfStats').css('width'));
|
576 |
+
if (res.longestLine > curLength) {
|
577 |
+
jQuery('#wfPerfStats').css('width', (res.longestLine + 200) + 'px');
|
578 |
+
}
|
579 |
+
this.newestActivityTime = res.events[0]['ctime'];
|
580 |
+
for (var i = res.events.length - 1; i >= 0; i--) {
|
581 |
+
res.events[i]['scale'] = this.performanceScale;
|
582 |
+
res.events[i]['min'] = this.performanceMinWidth;
|
583 |
+
newElem = jQuery('#wfPerfStatTmpl').tmpl(res.events[i]);
|
584 |
+
jQuery(newElem).find('.wfTimeAgo').data('wfctime', res.events[i].ctime);
|
585 |
+
newElem.prependTo('#wfPerfStats').fadeIn();
|
586 |
+
}
|
587 |
+
} else {
|
588 |
+
if (!haveEvents) {
|
589 |
+
jQuery('#wfPerfStats').html('<p>No events to report yet.</p>');
|
590 |
+
}
|
591 |
+
}
|
592 |
+
jQuery('.wfTimeAgo').each(function(idx, elem) {
|
593 |
+
jQuery(elem).html(self.makeTimeAgo(res.serverTime - jQuery(elem).data('wfctime')) + ' ago');
|
594 |
+
});
|
595 |
+
}
|
596 |
+
},
|
597 |
+
reverseLookupIPs: function() {
|
598 |
+
var ips = [];
|
599 |
+
jQuery('.wfReverseLookup').each(function(idx, elem) {
|
600 |
+
var txt = jQuery(elem).text();
|
601 |
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(txt) && (!jQuery(elem).data('wfReverseDone'))) {
|
602 |
+
jQuery(elem).data('wfReverseDone', true);
|
603 |
+
ips.push(jQuery(elem).text());
|
604 |
+
}
|
605 |
+
});
|
606 |
+
if (ips.length < 1) {
|
607 |
+
return;
|
608 |
+
}
|
609 |
+
var uni = {};
|
610 |
+
var uniqueIPs = [];
|
611 |
+
for (var i = 0; i < ips.length; i++) {
|
612 |
+
if (!uni[ips[i]]) {
|
613 |
+
uni[ips[i]] = true;
|
614 |
+
uniqueIPs.push(ips[i]);
|
615 |
+
}
|
616 |
+
}
|
617 |
+
this.ajax('wordfence_reverseLookup', {
|
618 |
+
ips: uniqueIPs.join(',')
|
619 |
+
},
|
620 |
+
function(res) {
|
621 |
+
if (res.ok) {
|
622 |
+
jQuery('.wfReverseLookup').each(function(idx, elem) {
|
623 |
+
var txt = jQuery(elem).text();
|
624 |
+
for (var ip in res.ips) {
|
625 |
+
if (txt == ip) {
|
626 |
+
if (res.ips[ip]) {
|
627 |
+
jQuery(elem).html('<strong>Hostname:</strong> ' + res.ips[ip]);
|
628 |
+
} else {
|
629 |
+
jQuery(elem).html('');
|
630 |
+
}
|
631 |
+
}
|
632 |
+
}
|
633 |
+
});
|
634 |
+
}
|
635 |
+
}, false, false);
|
636 |
+
},
|
637 |
+
killScan: function() {
|
638 |
+
var self = this;
|
639 |
+
this.ajax('wordfence_killScan', {}, function(res) {
|
640 |
+
if (res.ok) {
|
641 |
+
self.colorbox('400px', "Kill requested", "A termination request has been sent to any running scans.");
|
642 |
+
} else {
|
643 |
+
self.colorbox('400px', "Kill failed", "We failed to send a termination request.");
|
644 |
+
}
|
645 |
+
});
|
646 |
+
},
|
647 |
+
startScan: function() {
|
648 |
+
var scanReqAnimation = setInterval(function() {
|
649 |
+
var str = jQuery('#wfStartScanButton1').prop('value');
|
650 |
+
var ch = str.charAt(str.length - 1);
|
651 |
+
if (ch == '/') {
|
652 |
+
ch = '-';
|
653 |
+
}
|
654 |
+
else if (ch == '-') {
|
655 |
+
ch = '\\';
|
656 |
+
}
|
657 |
+
else if (ch == '\\') {
|
658 |
+
ch = '|';
|
659 |
+
}
|
660 |
+
else if (ch == '|') {
|
661 |
+
ch = '/';
|
662 |
+
}
|
663 |
+
else {
|
664 |
+
ch = '/';
|
665 |
+
}
|
666 |
+
jQuery('#wfStartScanButton1,#wfStartScanButton2').prop('value', "Requesting a New Scan " + ch);
|
667 |
+
}, 100);
|
668 |
+
setTimeout(function(res) {
|
669 |
+
clearInterval(scanReqAnimation);
|
670 |
+
jQuery('#wfStartScanButton1,#wfStartScanButton2').prop('value', "Start a Wordfence Scan");
|
671 |
+
}, 3000);
|
672 |
+
this.ajax('wordfence_scan', {}, function(res) {
|
673 |
+
});
|
674 |
+
},
|
675 |
+
displayPWAuditJobs: function(res) {
|
676 |
+
if (res && res.results && res.results.length > 0) {
|
677 |
+
var wfAuditJobs = $('#wfAuditJobs');
|
678 |
+
jQuery('#wfAuditJobs').empty();
|
679 |
+
jQuery('#wfAuditJobsTable').tmpl().appendTo(wfAuditJobs);
|
680 |
+
var wfAuditJobsBody = wfAuditJobs.find('.wf-pw-audit-tbody');
|
681 |
+
for (var i = 0; i < res.results.length; i++) {
|
682 |
+
jQuery('#wfAuditJobsInProg').tmpl(res.results[i]).appendTo(wfAuditJobsBody);
|
683 |
+
}
|
684 |
+
} else {
|
685 |
+
jQuery('#wfAuditJobs').empty().html("<p>You don't have any password auditing jobs in progress or completed yet.</p>");
|
686 |
+
}
|
687 |
+
},
|
688 |
+
loadIssues: function(callback) {
|
689 |
+
if (this.mode != 'scan') {
|
690 |
+
return;
|
691 |
+
}
|
692 |
+
var self = this;
|
693 |
+
this.ajax('wordfence_loadIssues', {}, function(res) {
|
694 |
+
self.displayIssues(res, callback);
|
695 |
+
});
|
696 |
+
},
|
697 |
+
sev2num: function(str) {
|
698 |
+
if (/wfProbSev1/.test(str)) {
|
699 |
+
return 1;
|
700 |
+
} else if (/wfProbSev2/.test(str)) {
|
701 |
+
return 2;
|
702 |
+
} else {
|
703 |
+
return 0;
|
704 |
+
}
|
705 |
+
},
|
706 |
+
displayIssues: function(res, callback) {
|
707 |
+
var self = this;
|
708 |
+
try {
|
709 |
+
res.summary['lastScanCompleted'] = res['lastScanCompleted'];
|
710 |
+
} catch (err) {
|
711 |
+
res.summary['lastScanCompleted'] = 'Never';
|
712 |
+
}
|
713 |
+
jQuery('.wfIssuesContainer').hide();
|
714 |
+
for (var issueStatus in res.issuesLists) {
|
715 |
+
var containerID = 'wfIssues_dataTable_' + issueStatus;
|
716 |
+
var tableID = 'wfIssuesTable_' + issueStatus;
|
717 |
+
if (jQuery('#' + containerID).length < 1) {
|
718 |
+
//Invalid issue status
|
719 |
+
continue;
|
720 |
+
}
|
721 |
+
if (res.issuesLists[issueStatus].length < 1) {
|
722 |
+
if (issueStatus == 'new') {
|
723 |
+
if (res.lastScanCompleted == 'ok') {
|
724 |
+
jQuery('#' + containerID).html('<p style="font-size: 20px; color: #0A0;">Congratulations! No security problems were detected by Wordfence.</p>');
|
725 |
+
} else if (res['lastScanCompleted']) {
|
726 |
+
//jQuery('#' + containerID).html('<p style="font-size: 12px; color: #A00;">The latest scan failed: ' + res.lastScanCompleted + '</p>');
|
727 |
+
} else {
|
728 |
+
jQuery('#' + containerID).html();
|
729 |
+
}
|
730 |
+
|
731 |
+
} else {
|
732 |
+
jQuery('#' + containerID).html('<p>There are currently <strong>no issues</strong> being ignored on this site.</p>');
|
733 |
+
}
|
734 |
+
continue;
|
735 |
+
}
|
736 |
+
jQuery('#' + containerID).html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="' + tableID + '"></table>');
|
737 |
+
|
738 |
+
jQuery.fn.dataTableExt.oSort['severity-asc'] = function(y, x) {
|
739 |
+
x = WFAD.sev2num(x);
|
740 |
+
y = WFAD.sev2num(y);
|
741 |
+
if (x < y) {
|
742 |
+
return 1;
|
743 |
+
}
|
744 |
+
if (x > y) {
|
745 |
+
return -1;
|
746 |
+
}
|
747 |
+
return 0;
|
748 |
+
};
|
749 |
+
jQuery.fn.dataTableExt.oSort['severity-desc'] = function(y, x) {
|
750 |
+
x = WFAD.sev2num(x);
|
751 |
+
y = WFAD.sev2num(y);
|
752 |
+
if (x > y) {
|
753 |
+
return 1;
|
754 |
+
}
|
755 |
+
if (x < y) {
|
756 |
+
return -1;
|
757 |
+
}
|
758 |
+
return 0;
|
759 |
+
};
|
760 |
+
|
761 |
+
jQuery('#' + tableID).dataTable({
|
762 |
+
"bFilter": false,
|
763 |
+
"bInfo": false,
|
764 |
+
"bPaginate": false,
|
765 |
+
"bLengthChange": false,
|
766 |
+
"bAutoWidth": false,
|
767 |
+
"aaData": res.issuesLists[issueStatus],
|
768 |
+
"aoColumns": [
|
769 |
+
{
|
770 |
+
"sTitle": '<div class="th_wrapp">Severity</div>',
|
771 |
+
"sWidth": '128px',
|
772 |
+
"sClass": "center",
|
773 |
+
"sType": 'severity',
|
774 |
+
"fnRender": function(obj) {
|
775 |
+
var cls = 'wfProbSev' + obj.aData.severity;
|
776 |
+
return '<span class="' + cls + '"></span>';
|
777 |
+
}
|
778 |
+
},
|
779 |
+
{
|
780 |
+
"sTitle": '<div class="th_wrapp">Issue</div>',
|
781 |
+
"bSortable": false,
|
782 |
+
"sWidth": '400px',
|
783 |
+
"sType": 'html',
|
784 |
+
fnRender: function(obj) {
|
785 |
+
var tmplName = 'issueTmpl_' + obj.aData.type;
|
786 |
+
return jQuery('#' + tmplName).tmpl(obj.aData).html();
|
787 |
+
}
|
788 |
+
}
|
789 |
+
]
|
790 |
+
});
|
791 |
+
}
|
792 |
+
if (callback) {
|
793 |
+
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500, function() {
|
794 |
+
callback();
|
795 |
+
});
|
796 |
+
} else {
|
797 |
+
jQuery('#wfIssues_' + this.visibleIssuesPanel).fadeIn(500);
|
798 |
+
}
|
799 |
+
return true;
|
800 |
+
},
|
801 |
+
ajax: function(action, data, cb, cbErr, noLoading) {
|
802 |
+
if (typeof(data) == 'string') {
|
803 |
+
if (data.length > 0) {
|
804 |
+
data += '&';
|
805 |
+
}
|
806 |
+
data += 'action=' + action + '&nonce=' + this.nonce;
|
807 |
+
} else if (typeof(data) == 'object') {
|
808 |
+
data['action'] = action;
|
809 |
+
data['nonce'] = this.nonce;
|
810 |
+
}
|
811 |
+
if (!cbErr) {
|
812 |
+
cbErr = function() {
|
813 |
+
};
|
814 |
+
}
|
815 |
+
var self = this;
|
816 |
+
if (!noLoading) {
|
817 |
+
this.showLoading();
|
818 |
+
}
|
819 |
+
jQuery.ajax({
|
820 |
+
type: 'POST',
|
821 |
+
url: WordfenceAdminVars.ajaxURL,
|
822 |
+
dataType: "json",
|
823 |
+
data: data,
|
824 |
+
success: function(json) {
|
825 |
+
if (!noLoading) {
|
826 |
+
self.removeLoading();
|
827 |
+
}
|
828 |
+
if (json && json.nonce) {
|
829 |
+
self.nonce = json.nonce;
|
830 |
+
}
|
831 |
+
if (json && json.errorMsg) {
|
832 |
+
self.colorbox('400px', 'An error occurred', json.errorMsg);
|
833 |
+
}
|
834 |
+
cb(json);
|
835 |
+
},
|
836 |
+
error: function() {
|
837 |
+
if (!noLoading) {
|
838 |
+
self.removeLoading();
|
839 |
+
}
|
840 |
+
cbErr();
|
841 |
+
}
|
842 |
+
});
|
843 |
+
},
|
844 |
+
colorbox: function(width, heading, body) {
|
845 |
+
this.colorboxQueue.push([width, heading, body]);
|
846 |
+
this.colorboxServiceQueue();
|
847 |
+
},
|
848 |
+
colorboxServiceQueue: function() {
|
849 |
+
if (this.colorboxIsOpen) {
|
850 |
+
return;
|
851 |
+
}
|
852 |
+
if (this.colorboxQueue.length < 1) {
|
853 |
+
return;
|
854 |
+
}
|
855 |
+
var elem = this.colorboxQueue.shift();
|
856 |
+
this.colorboxOpen(elem[0], elem[1], elem[2]);
|
857 |
+
},
|
858 |
+
colorboxOpen: function(width, heading, body) {
|
859 |
+
this.colorboxIsOpen = true;
|
860 |
+
jQuery.colorbox({width: width, html: "<h3>" + heading + "</h3><p>" + body + "</p>"});
|
861 |
+
},
|
862 |
+
scanRunningMsg: function() {
|
863 |
+
this.colorbox('400px', "A scan is running", "A scan is currently in progress. Please wait until it finishes before starting another scan.");
|
864 |
+
},
|
865 |
+
errorMsg: function(msg) {
|
866 |
+
this.colorbox('400px', "An error occurred:", msg);
|
867 |
+
},
|
868 |
+
bulkOperation: function(op) {
|
869 |
+
var self = this;
|
870 |
+
if (op == 'del' || op == 'repair') {
|
871 |
+
var ids = jQuery('input.wf' + op + 'Checkbox:checked').map(function() {
|
872 |
+
return jQuery(this).val();
|
873 |
+
}).get();
|
874 |
+
if (ids.length < 1) {
|
875 |
+
this.colorbox('400px', "No files were selected", "You need to select files to perform a bulk operation. There is a checkbox in each issue that lets you select that file. You can then select a bulk operation and hit the button to perform that bulk operation.");
|
876 |
+
return;
|
877 |
+
}
|
878 |
+
if (op == 'del') {
|
879 |
+
this.colorbox('400px', "Are you sure you want to delete?", "Are you sure you want to delete a total of " + ids.length + " files? Do not delete files on your system unless you're ABSOLUTELY sure you know what you're doing. If you delete the wrong file it could cause your WordPress website to stop functioning and you will probably have to restore from backups. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files.<br /><br /><input type=\"button\" value=\"Delete Files\" onclick=\"WFAD.bulkOperationConfirmed('" + op + "');\" /> <input type=\"button\" value=\"Cancel\" onclick=\"jQuery.colorbox.close();\" /><br />");
|
880 |
+
} else if (op == 'repair') {
|
881 |
+
this.colorbox('400px', "Are you sure you want to repair?", "Are you sure you want to repair a total of " + ids.length + " files? Do not repair files on your system unless you're sure you have reviewed the differences between the original file and your version of the file in the files you are repairing. If you repair a file that has been customized for your system by a developer or your hosting provider it may leave your system unusable. If you're unsure, Cancel and work with your hosting provider to clean your system of infected files.<br /><br /><input type=\"button\" value=\"Repair Files\" onclick=\"WFAD.bulkOperationConfirmed('" + op + "');\" /> <input type=\"button\" value=\"Cancel\" onclick=\"jQuery.colorbox.close();\" /><br />");
|
882 |
+
}
|
883 |
+
} else {
|
884 |
+
return;
|
885 |
+
}
|
886 |
+
},
|
887 |
+
bulkOperationConfirmed: function(op) {
|
888 |
+
jQuery.colorbox.close();
|
889 |
+
var self = this;
|
890 |
+
this.ajax('wordfence_bulkOperation', {
|
891 |
+
op: op,
|
892 |
+
ids: jQuery('input.wf' + op + 'Checkbox:checked').map(function() {
|
893 |
+
return jQuery(this).val();
|
894 |
+
}).get()
|
895 |
+
}, function(res) {
|
896 |
+
self.doneBulkOperation(res);
|
897 |
+
});
|
898 |
+
},
|
899 |
+
doneBulkOperation: function(res) {
|
900 |
+
var self = this;
|
901 |
+
if (res.ok) {
|
902 |
+
this.loadIssues(function() {
|
903 |
+
self.colorbox('400px', res.bulkHeading, res.bulkBody);
|
904 |
+
});
|
905 |
+
} else {
|
906 |
+
this.loadIssues(function() {
|
907 |
+
});
|
908 |
+
}
|
909 |
+
},
|
910 |
+
deleteFile: function(issueID) {
|
911 |
+
var self = this;
|
912 |
+
this.ajax('wordfence_deleteFile', {
|
913 |
+
issueID: issueID
|
914 |
+
}, function(res) {
|
915 |
+
self.doneDeleteFile(res);
|
916 |
+
});
|
917 |
+
},
|
918 |
+
doneDeleteFile: function(res) {
|
919 |
+
var cb = false;
|
920 |
+
var self = this;
|
921 |
+
if (res.ok) {
|
922 |
+
this.loadIssues(function() {
|
923 |
+
self.colorbox('400px', "Success deleting file", "The file " + res.file + " was successfully deleted.");
|
924 |
+
});
|
925 |
+
} else if (res.cerrorMsg) {
|
926 |
+
this.loadIssues(function() {
|
927 |
+
self.colorbox('400px', 'An error occurred', res.cerrorMsg);
|
928 |
+
});
|
929 |
+
}
|
930 |
+
},
|
931 |
+
restoreFile: function(issueID) {
|
932 |
+
var self = this;
|
933 |
+
this.ajax('wordfence_restoreFile', {
|
934 |
+
issueID: issueID
|
935 |
+
}, function(res) {
|
936 |
+
self.doneRestoreFile(res);
|
937 |
+
});
|
938 |
+
},
|
939 |
+
doneRestoreFile: function(res) {
|
940 |
+
var self = this;
|
941 |
+
if (res.ok) {
|
942 |
+
this.loadIssues(function() {
|
943 |
+
self.colorbox("400px", "File restored OK", "The file " + res.file + " was restored succesfully.");
|
944 |
+
});
|
945 |
+
} else if (res.cerrorMsg) {
|
946 |
+
this.loadIssues(function() {
|
947 |
+
self.colorbox('400px', 'An error occurred', res.cerrorMsg);
|
948 |
+
});
|
949 |
+
}
|
950 |
+
},
|
951 |
+
deleteIssue: function(id) {
|
952 |
+
var self = this;
|
953 |
+
this.ajax('wordfence_deleteIssue', {id: id}, function(res) {
|
954 |
+
self.loadIssues();
|
955 |
+
});
|
956 |
+
},
|
957 |
+
updateIssueStatus: function(id, st) {
|
958 |
+
var self = this;
|
959 |
+
this.ajax('wordfence_updateIssueStatus', {id: id, 'status': st}, function(res) {
|
960 |
+
if (res.ok) {
|
961 |
+
self.loadIssues();
|
962 |
+
}
|
963 |
+
});
|
964 |
+
},
|
965 |
+
updateAllIssues: function(op) { // deleteIgnored, deleteNew, ignoreAllNew
|
966 |
+
var head = "Please confirm";
|
967 |
+
var body;
|
968 |
+
if (op == 'deleteIgnored') {
|
969 |
+
body = "You have chosen to remove all ignored issues. Once these issues are removed they will be re-scanned by Wordfence and if they have not been fixed, they will appear in the 'new issues' list. Are you sure you want to do this?";
|
970 |
+
} else if (op == 'deleteNew') {
|
971 |
+
body = "You have chosen to mark all new issues as fixed. If you have not really fixed these issues, they will reappear in the new issues list on the next scan. If you have not fixed them and want them excluded from scans you should choose to 'ignore' them instead. Are you sure you want to mark all new issues as fixed?";
|
972 |
+
} else if (op == 'ignoreAllNew') {
|
973 |
+
body = "You have chosen to ignore all new issues. That means they will be excluded from future scans. You should only do this if you're sure all new issues are not a problem. Are you sure you want to ignore all new issues?";
|
974 |
+
} else {
|
975 |
+
return;
|
976 |
+
}
|
977 |
+
this.colorbox('450px', head, body + '<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" /> <input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmUpdateAllIssues(\'' + op + '\');" /><br />');
|
978 |
+
},
|
979 |
+
confirmUpdateAllIssues: function(op) {
|
980 |
+
var self = this;
|
981 |
+
this.ajax('wordfence_updateAllIssues', {op: op}, function(res) {
|
982 |
+
self.loadIssues();
|
983 |
+
});
|
984 |
+
},
|
985 |
+
es: function(val) {
|
986 |
+
if (val) {
|
987 |
+
return val;
|
988 |
+
} else {
|
989 |
+
return "";
|
990 |
+
}
|
991 |
+
},
|
992 |
+
noQuotes: function(str) {
|
993 |
+
return str.replace(/"/g, '"').replace(/\'/g, '‘');
|
994 |
+
},
|
995 |
+
commify: function(num) {
|
996 |
+
return ("" + num).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
|
997 |
+
},
|
998 |
+
switchToLiveTab: function(elem) {
|
999 |
+
jQuery('.wfTab1').removeClass('selected');
|
1000 |
+
jQuery(elem).addClass('selected');
|
1001 |
+
jQuery('.wfDataPanel').hide();
|
1002 |
+
var self = this;
|
1003 |
+
jQuery('#wfActivity').fadeIn(function() {
|
1004 |
+
self.completeLiveTabSwitch();
|
1005 |
+
});
|
1006 |
+
},
|
1007 |
+
completeLiveTabSwitch: function() {
|
1008 |
+
this.ajax('wordfence_loadActivityLog', {}, function(res) {
|
1009 |
+
var html = '<a href="#" class="wfALogMailLink" onclick="WFAD.emailActivityLog(); return false;"></a><a href="#" class="wfALogReloadLink" onclick="WFAD.reloadActivityData(); return false;"></a>';
|
1010 |
+
if (res.events && res.events.length > 0) {
|
1011 |
+
jQuery('#wfActivity').empty();
|
1012 |
+
for (var i = 0; i < res.events.length; i++) {
|
1013 |
+
var timeTaken = '0.0000';
|
1014 |
+
if (res.events[i + 1]) {
|
1015 |
+
timeTaken = (res.events[i].ctime - res.events[i + 1].ctime).toFixed(4);
|
1016 |
+
}
|
1017 |
+
var red = "";
|
1018 |
+
if (res.events[i].type == 'error') {
|
1019 |
+
red = ' class="wfWarn" ';
|
1020 |
+
}
|
1021 |
+
html += '<div ' + red + 'class="wfALogEntry"><span ' + red + 'class="wfALogTime">[' + res.events[i].type + ' : ' + timeTaken + ' : ' + res.events[i].timeAgo + ' ago]</span> ' + res.events[i].msg + "</div>";
|
1022 |
+
}
|
1023 |
+
jQuery('#wfActivity').html(html);
|
1024 |
+
} else {
|
1025 |
+
jQuery('#wfActivity').html("<p> No activity to report yet. Please complete your first scan.</p>");
|
1026 |
+
}
|
1027 |
+
});
|
1028 |
+
},
|
1029 |
+
emailActivityLog: function() {
|
1030 |
+
this.colorbox('400px', 'Email Wordfence Activity Log', "Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team. It also contains your PHP configuration from the phpinfo() function for diagnostic data.<br /><br /><input type='text' value='support@wordfence.com' size='20' id='wfALogRecip' /><input type='button' value='Send' onclick=\"WFAD.completeEmailActivityLog();\" /><input type='button' value='Cancel' onclick='jQuery.colorbox.close();' /><br /><br />");
|
1031 |
+
},
|
1032 |
+
completeEmailActivityLog: function() {
|
1033 |
+
jQuery.colorbox.close();
|
1034 |
+
var email = jQuery('#wfALogRecip').val();
|
1035 |
+
if (!/^[^@]+@[^@]+$/.test(email)) {
|
1036 |
+
alert("Please enter a valid email address.");
|
1037 |
+
return;
|
1038 |
+
}
|
1039 |
+
var self = this;
|
1040 |
+
this.ajax('wordfence_sendActivityLog', {email: jQuery('#wfALogRecip').val()}, function(res) {
|
1041 |
+
if (res.ok) {
|
1042 |
+
self.colorbox('400px', 'Activity Log Sent', "Your Wordfence activity log was sent to " + email + "<br /><br /><input type='button' value='Close' onclick='jQuery.colorbox.close();' /><br /><br />");
|
1043 |
+
}
|
1044 |
+
});
|
1045 |
+
},
|
1046 |
+
reloadActivityData: function() {
|
1047 |
+
jQuery('#wfActivity').html('<div class="wfLoadingWhite32"></div>'); // <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
|
1048 |
+
this.completeLiveTabSwitch();
|
1049 |
+
},
|
1050 |
+
switchToSummaryTab: function(elem) {
|
1051 |
+
jQuery('.wfTab1').removeClass('selected');
|
1052 |
+
jQuery(elem).addClass('selected');
|
1053 |
+
jQuery('.wfDataPanel').hide();
|
1054 |
+
jQuery('#wfSummaryTables').fadeIn();
|
1055 |
+
},
|
1056 |
+
switchIssuesTab: function(elem, type) {
|
1057 |
+
jQuery('.wfTab2').removeClass('selected');
|
1058 |
+
jQuery('.wfIssuesContainer').hide();
|
1059 |
+
jQuery(elem).addClass('selected');
|
1060 |
+
this.visibleIssuesPanel = type;
|
1061 |
+
jQuery('#wfIssues_' + type).fadeIn();
|
1062 |
+
},
|
1063 |
+
switchTab: function(tabElement, tabClass, contentClass, selectedContentID, callback) {
|
1064 |
+
jQuery('.' + tabClass).removeClass('selected');
|
1065 |
+
jQuery(tabElement).addClass('selected');
|
1066 |
+
jQuery('.' + contentClass).hide().html('<div class="wfLoadingWhite32"></div>');
|
1067 |
+
var func = function() {
|
1068 |
+
};
|
1069 |
+
if (callback) {
|
1070 |
+
func = function() {
|
1071 |
+
callback();
|
1072 |
+
};
|
1073 |
+
}
|
1074 |
+
jQuery('#' + selectedContentID).fadeIn(func);
|
1075 |
+
},
|
1076 |
+
activityTabChanged: function() {
|
1077 |
+
var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_', '');
|
1078 |
+
if (!mode) {
|
1079 |
+
return;
|
1080 |
+
}
|
1081 |
+
this.activityMode = mode;
|
1082 |
+
this.reloadActivities();
|
1083 |
+
},
|
1084 |
+
reloadActivities: function() {
|
1085 |
+
jQuery('#wfActivity_' + this.activityMode).html('<div class="wfLoadingWhite32"></div>');
|
1086 |
+
this.newestActivityTime = 0;
|
1087 |
+
this.updateTicker(true);
|
1088 |
+
},
|
1089 |
+
staticTabChanged: function() {
|
1090 |
+
var mode = jQuery('.wfDataPanel:visible')[0].id.replace('wfActivity_', '');
|
1091 |
+
if (!mode) {
|
1092 |
+
return;
|
1093 |
+
}
|
1094 |
+
this.activityMode = mode;
|
1095 |
+
|
1096 |
+
var self = this;
|
1097 |
+
this.ajax('wordfence_loadStaticPanel', {
|
1098 |
+
mode: this.activityMode
|
1099 |
+
}, function(res) {
|
1100 |
+
self.completeLoadStaticPanel(res);
|
1101 |
+
});
|
1102 |
+
},
|
1103 |
+
completeLoadStaticPanel: function(res) {
|
1104 |
+
var contentElem = '#wfActivity_' + this.activityMode;
|
1105 |
+
jQuery(contentElem).empty();
|
1106 |
+
if (res.results && res.results.length > 0) {
|
1107 |
+
var tmpl;
|
1108 |
+
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
|
1109 |
+
tmpl = '#wfLeechersTmpl';
|
1110 |
+
} else if (this.activityMode == 'blockedIPs') {
|
1111 |
+
tmpl = '#wfBlockedIPsTmpl';
|
1112 |
+
} else if (this.activityMode == 'lockedOutIPs') {
|
1113 |
+
tmpl = '#wfLockedOutIPsTmpl';
|
1114 |
+
} else if (this.activityMode == 'throttledIPs') {
|
1115 |
+
tmpl = '#wfThrottledIPsTmpl';
|
1116 |
+
} else {
|
1117 |
+
return;
|
1118 |
+
}
|
1119 |
+
var i, j, chunk = 1000;
|
1120 |
+
var bigArray = res.results.slice(0);
|
1121 |
+
res.results = false;
|
1122 |
+
for (i = 0, j = bigArray.length; i < j; i += chunk) {
|
1123 |
+
res.results = bigArray.slice(i, i + chunk);
|
1124 |
+
jQuery(tmpl).tmpl(res).appendTo(contentElem);
|
1125 |
+
}
|
1126 |
+
this.reverseLookupIPs();
|
1127 |
+
} else {
|
1128 |
+
if (this.activityMode == 'topScanners' || this.activityMode == 'topLeechers') {
|
1129 |
+
jQuery(contentElem).html("No site hits have been logged yet. Check back soon.");
|
1130 |
+
} else if (this.activityMode == 'blockedIPs') {
|
1131 |
+
jQuery(contentElem).html("No IP addresses have been blocked yet. If you manually block an IP address or if Wordfence automatically blocks one, it will appear here.");
|
1132 |
+
} else if (this.activityMode == 'lockedOutIPs') {
|
1133 |
+
jQuery(contentElem).html("No IP addresses have been locked out from signing in or using the password recovery system.");
|
1134 |
+
} else if (this.activityMode == 'throttledIPs') {
|
1135 |
+
jQuery(contentElem).html("No IP addresses have been throttled yet. If an IP address accesses the site too quickly and breaks one of the Wordfence rules, it will appear here.");
|
1136 |
+
} else {
|
1137 |
+
return;
|
1138 |
+
}
|
1139 |
+
}
|
1140 |
+
},
|
1141 |
+
loadPasswdAuditResults: function() {
|
1142 |
+
var self = this;
|
1143 |
+
this.ajax('wordfence_passwdLoadResults', {}, function(res) {
|
1144 |
+
self.displayPWAuditResults(res);
|
1145 |
+
});
|
1146 |
+
},
|
1147 |
+
doPasswdAuditUpdate: function(freq) {
|
1148 |
+
this.loadPasswdAuditJobs();
|
1149 |
+
this.loadPasswdAuditResults();
|
1150 |
+
},
|
1151 |
+
stopPasswdAuditUpdate: function() {
|
1152 |
+
clearInterval(this.passwdAuditUpdateInt);
|
1153 |
+
},
|
1154 |
+
killPasswdAudit: function(jobID) {
|
1155 |
+
var self = this;
|
1156 |
+
this.ajax('wordfence_killPasswdAudit', {jobID: jobID}, function(res) {
|
1157 |
+
if (res.ok) {
|
1158 |
+
self.colorbox('300px', "Stop Requested", "We have sent a request to stop the password audit in progress. It may take a few minutes before results stop appearing. You can immediately start another audit if you'd like.");
|
1159 |
+
}
|
1160 |
+
});
|
1161 |
+
},
|
1162 |
+
displayPWAuditResults: function(res) {
|
1163 |
+
if (res && res.results && res.results.length > 0) {
|
1164 |
+
var wfAuditResults = $('#wfAuditResults');
|
1165 |
+
jQuery('#wfAuditResults').empty();
|
1166 |
+
jQuery('#wfAuditResultsTable').tmpl().appendTo(wfAuditResults);
|
1167 |
+
var wfAuditResultsBody = wfAuditResults.find('.wf-pw-audit-tbody');
|
1168 |
+
for (var i = 0; i < res.results.length; i++) {
|
1169 |
+
jQuery('#wfAuditResultsRow').tmpl(res.results[i]).appendTo(wfAuditResultsBody);
|
1170 |
+
}
|
1171 |
+
} else {
|
1172 |
+
jQuery('#wfAuditResults').empty().html("<p>You don't have any user accounts with a weak password at this time.</p>");
|
1173 |
+
}
|
1174 |
+
},
|
1175 |
+
loadPasswdAuditJobs: function() {
|
1176 |
+
var self = this;
|
1177 |
+
this.ajax('wordfence_passwdLoadJobs', {}, function(res) {
|
1178 |
+
if (res && res.results && res.results.length > 0) {
|
1179 |
+
var stat = res.results[0].jobStatus;
|
1180 |
+
if (stat == 'running' || stat == 'queued') {
|
1181 |
+
setTimeout(function() {
|
1182 |
+
self.doPasswdAuditUpdate()
|
1183 |
+
}, 10000);
|
1184 |
+
}
|
1185 |
+
}
|
1186 |
+
|
1187 |
+
self.displayPWAuditJobs(res);
|
1188 |
+
});
|
1189 |
+
},
|
1190 |
+
deletePasswdAudit: function(jobID) {
|
1191 |
+
var self = this;
|
1192 |
+
this.ajax('wordfence_deletePasswdAudit', {jobID: jobID}, function(res) {
|
1193 |
+
self.loadPasswdAuditJobs(res);
|
1194 |
+
});
|
1195 |
+
},
|
1196 |
+
doFixWeakPasswords: function() {
|
1197 |
+
var self = this;
|
1198 |
+
var mode = jQuery('#wfPasswdFixAction').val();
|
1199 |
+
var ids = jQuery('input.wfUserCheck:checked').map(function() {
|
1200 |
+
return jQuery(this).val();
|
1201 |
+
}).get();
|
1202 |
+
if (ids.length < 1) {
|
1203 |
+
self.colorbox('300px', "Please select users", "You did not select any users from the list. Select which site members you want to email or to change their passwords.");
|
1204 |
+
return;
|
1205 |
+
}
|
1206 |
+
this.ajax('wordfence_weakPasswordsFix', {
|
1207 |
+
mode: mode,
|
1208 |
+
ids: ids.join(',')
|
1209 |
+
}, function(res) {
|
1210 |
+
if (res.ok && res.title && res.msg) {
|
1211 |
+
self.colorbox('300px', res.title, res.msg);
|
1212 |
+
}
|
1213 |
+
});
|
1214 |
+
},
|
1215 |
+
ucfirst: function(str) {
|
1216 |
+
str = "" + str;
|
1217 |
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
1218 |
+
},
|
1219 |
+
makeIPTrafLink: function(IP) {
|
1220 |
+
return WordfenceAdminVars.siteBaseURL + '?_wfsf=IPTraf&nonce=' + this.nonce + '&IP=' + encodeURIComponent(IP);
|
1221 |
+
},
|
1222 |
+
makeDiffLink: function(dat) {
|
1223 |
+
return WordfenceAdminVars.siteBaseURL + '?_wfsf=diff&nonce=' + this.nonce +
|
1224 |
+
'&file=' + encodeURIComponent(this.es(dat['file'])) +
|
1225 |
+
'&cType=' + encodeURIComponent(this.es(dat['cType'])) +
|
1226 |
+
'&cKey=' + encodeURIComponent(this.es(dat['cKey'])) +
|
1227 |
+
'&cName=' + encodeURIComponent(this.es(dat['cName'])) +
|
1228 |
+
'&cVersion=' + encodeURIComponent(this.es(dat['cVersion']));
|
1229 |
+
},
|
1230 |
+
makeViewFileLink: function(file) {
|
1231 |
+
return WordfenceAdminVars.siteBaseURL + '?_wfsf=view&nonce=' + this.nonce + '&file=' + encodeURIComponent(file);
|
1232 |
+
},
|
1233 |
+
makeTimeAgo: function(t) {
|
1234 |
+
var months = Math.floor(t / (86400 * 30));
|
1235 |
+
var days = Math.floor(t / 86400);
|
1236 |
+
var hours = Math.floor(t / 3600);
|
1237 |
+
var minutes = Math.floor(t / 60);
|
1238 |
+
if (months > 0) {
|
1239 |
+
days -= months * 30;
|
1240 |
+
return this.pluralize(months, 'month', days, 'day');
|
1241 |
+
} else if (days > 0) {
|
1242 |
+
hours -= days * 24;
|
1243 |
+
return this.pluralize(days, 'day', hours, 'hour');
|
1244 |
+
} else if (hours > 0) {
|
1245 |
+
minutes -= hours * 60;
|
1246 |
+
return this.pluralize(hours, 'hour', minutes, 'min');
|
1247 |
+
} else if (minutes > 0) {
|
1248 |
+
//t -= minutes * 60;
|
1249 |
+
return this.pluralize(minutes, 'minute');
|
1250 |
+
} else {
|
1251 |
+
return Math.round(t) + " seconds";
|
1252 |
+
}
|
1253 |
+
},
|
1254 |
+
pluralize: function(m1, t1, m2, t2) {
|
1255 |
+
if (m1 != 1) {
|
1256 |
+
t1 = t1 + 's';
|
1257 |
+
}
|
1258 |
+
if (m2 != 1) {
|
1259 |
+
t2 = t2 + 's';
|
1260 |
+
}
|
1261 |
+
if (m1 && m2) {
|
1262 |
+
return m1 + ' ' + t1 + ' ' + m2 + ' ' + t2;
|
1263 |
+
} else {
|
1264 |
+
return m1 + ' ' + t1;
|
1265 |
+
}
|
1266 |
+
},
|
1267 |
+
calcRangeTotal: function() {
|
1268 |
+
var range = jQuery('#ipRange').val();
|
1269 |
+
if (!range) {
|
1270 |
+
return;
|
1271 |
+
}
|
1272 |
+
range = range.replace(/ /g, '');
|
1273 |
+
if (range && /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s*\-\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(range)) {
|
1274 |
+
var ips = range.split('-');
|
1275 |
+
var total = this.inet_aton(ips[1]) - this.inet_aton(ips[0]) + 1;
|
1276 |
+
if (total < 1) {
|
1277 |
+
jQuery('#wfShowRangeTotal').html("<span style=\"color: #F00;\">Invalid. Starting IP is greater than ending IP.</span>");
|
1278 |
+
return;
|
1279 |
+
}
|
1280 |
+
jQuery('#wfShowRangeTotal').html("<span style=\"color: #0A0;\">Valid: " + total + " addresses in range.</span>");
|
1281 |
+
} else {
|
1282 |
+
jQuery('#wfShowRangeTotal').empty();
|
1283 |
+
}
|
1284 |
+
},
|
1285 |
+
loadBlockRanges: function() {
|
1286 |
+
var self = this;
|
1287 |
+
this.ajax('wordfence_loadBlockRanges', {}, function(res) {
|
1288 |
+
self.completeLoadBlockRanges(res);
|
1289 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1290 |
|
1291 |
+
},
|
1292 |
+
completeLoadBlockRanges: function(res) {
|
1293 |
+
jQuery('#currentBlocks').empty();
|
1294 |
+
if (res.results && res.results.length > 0) {
|
1295 |
+
jQuery('#wfBlockedRangesTmpl').tmpl(res).prependTo('#currentBlocks');
|
1296 |
+
} else {
|
1297 |
+
jQuery('#currentBlocks').html("You have not blocked any IP ranges or other patterns yet.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1298 |
}
|
1299 |
+
},
|
1300 |
+
whois: function(val) {
|
1301 |
+
val = val.replace(' ', '');
|
1302 |
+
if (!/\w+/.test(val)) {
|
1303 |
+
this.colorbox('300px', "Enter a valid IP or domain", "Please enter a valid IP address or domain name for your whois lookup.");
|
1304 |
+
return;
|
1305 |
+
}
|
1306 |
+
var self = this;
|
1307 |
+
jQuery('#whoisbutton').attr('disabled', 'disabled');
|
1308 |
+
jQuery('#whoisbutton').attr('value', 'Loading...');
|
1309 |
+
this.ajax('wordfence_whois', {
|
1310 |
+
val: val
|
1311 |
+
}, function(res) {
|
1312 |
+
jQuery('#whoisbutton').removeAttr('disabled');
|
1313 |
+
jQuery('#whoisbutton').attr('value', 'Look up IP or Domain');
|
1314 |
+
if (res.ok) {
|
1315 |
+
self.completeWhois(res);
|
1316 |
+
}
|
1317 |
+
});
|
1318 |
+
},
|
1319 |
+
completeWhois: function(res) {
|
1320 |
+
if (res.ok && res.result && res.result.rawdata && res.result.rawdata.length > 0) {
|
1321 |
+
var rawhtml = "";
|
1322 |
+
for (var i = 0; i < res.result.rawdata.length; i++) {
|
1323 |
+
res.result.rawdata[i] = jQuery('<div />').text(res.result.rawdata[i]).html();
|
1324 |
+
res.result.rawdata[i] = res.result.rawdata[i].replace(/([^\s\t\r\n:;]+@[^\s\t\r\n:;\.]+\.[^\s\t\r\n:;]+)/, "<a href=\"mailto:$1\">$1<\/a>");
|
1325 |
+
res.result.rawdata[i] = res.result.rawdata[i].replace(/(https?:\/\/[^\/]+[^\s\r\n\t]+)/, "<a target=\"_blank\" href=\"$1\">$1<\/a>");
|
1326 |
+
var redStyle = "";
|
1327 |
+
if (this.getQueryParam('wfnetworkblock')) {
|
1328 |
+
redStyle = " style=\"color: #F00;\"";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1329 |
}
|
1330 |
+
var self = this;
|
1331 |
+
|
1332 |
+
function wfm21(str, ipRange, offset, totalStr) {
|
1333 |
+
var ips = ipRange.split(/\s*\-\s*/);
|
1334 |
+
var ip1num = self.inet_aton(ips[0]);
|
1335 |
+
var ip2num = self.inet_aton(ips[1]);
|
1336 |
+
var totalIPs = ip2num - ip1num + 1;
|
1337 |
+
return "<a href=\"admin.php?page=WordfenceRangeBlocking&wfBlockRange=" + ipRange + "\"" + redStyle + ">" + ipRange + " [<strong>" + totalIPs + "</strong> addresses in this network. Click to block this network]<\/a>";
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
res.result.rawdata[i] = res.result.rawdata[i].replace(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} - \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/, wfm21);
|
1341 |
+
rawhtml += res.result.rawdata[i] + "<br />";
|
1342 |
}
|
1343 |
+
jQuery('#wfrawhtml').html(rawhtml);
|
1344 |
+
} else {
|
1345 |
+
jQuery('#wfrawhtml').html('<span style="color: #F00;">Sorry, but no data for that IP or domain was found.</span>');
|
1346 |
}
|
1347 |
+
},
|
1348 |
+
blockIPUARange: function(ipRange, uaRange, referer, reason) {
|
1349 |
+
if (!/\w+/.test(reason)) {
|
1350 |
+
this.colorbox('300px', "Please specify a reason", "You forgot to include a reason you're blocking this IP range. We ask you to include this for your own record keeping.");
|
1351 |
+
return;
|
1352 |
}
|
1353 |
+
ipRange = ipRange.replace(/ /g, '');
|
1354 |
+
if (ipRange) {
|
1355 |
+
if (!/^\d+\.\d+\.\d+\.\d+\-\d+\.\d+\.\d+\.\d+$/.test(ipRange)) {
|
1356 |
+
this.colorbox('300px', 'Specify a valid IP range', "Please specify a valid IP address range in the form of \"1.2.3.4 - 1.2.3.5\" without quotes. Make sure the dash between the IP addresses in a normal dash (a minus sign on your keyboard) and not another character that looks like a dash.");
|
1357 |
+
return;
|
1358 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1359 |
}
|
1360 |
+
if (!(/\w+/.test(ipRange) || /\w+/.test(uaRange) || /\w+/.test(referer))) {
|
1361 |
+
this.colorbox('300px', 'Specify an IP range or Browser pattern', "Please specify either an IP address range or a web browser pattern to match.");
|
1362 |
+
return;
|
1363 |
+
}
|
1364 |
+
var self = this;
|
1365 |
+
this.ajax('wordfence_blockIPUARange', {
|
1366 |
+
ipRange: ipRange,
|
1367 |
+
uaRange: uaRange,
|
1368 |
+
referer: referer,
|
1369 |
+
reason: reason
|
1370 |
+
}, function(res) {
|
1371 |
+
if (res.ok) {
|
1372 |
+
self.loadBlockRanges();
|
1373 |
+
return;
|
1374 |
+
}
|
1375 |
});
|
1376 |
+
},
|
1377 |
+
unblockRange: function(id) {
|
1378 |
+
var self = this;
|
1379 |
+
this.ajax('wordfence_unblockRange', {
|
1380 |
+
id: id
|
1381 |
+
}, function(res) {
|
1382 |
+
self.loadBlockRanges();
|
1383 |
+
});
|
1384 |
+
},
|
1385 |
+
blockIP: function(IP, reason) {
|
1386 |
+
var self = this;
|
1387 |
+
this.ajax('wordfence_blockIP', {
|
1388 |
+
IP: IP,
|
1389 |
+
reason: reason
|
1390 |
+
}, function(res) {
|
1391 |
+
if (res.errorMsg) {
|
1392 |
+
return;
|
1393 |
+
} else {
|
1394 |
+
self.reloadActivities();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1395 |
}
|
1396 |
+
});
|
1397 |
+
},
|
1398 |
+
blockIPTwo: function(IP, reason, perm) {
|
1399 |
+
var self = this;
|
1400 |
+
this.ajax('wordfence_blockIP', {
|
1401 |
+
IP: IP,
|
1402 |
+
reason: reason,
|
1403 |
+
perm: (perm ? '1' : '0')
|
1404 |
+
}, function(res) {
|
1405 |
+
if (res.errorMsg) {
|
1406 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1407 |
} else {
|
1408 |
+
self.staticTabChanged();
|
1409 |
}
|
1410 |
+
});
|
1411 |
+
},
|
1412 |
+
unlockOutIP: function(IP) {
|
1413 |
+
var self = this;
|
1414 |
+
this.ajax('wordfence_unlockOutIP', {
|
1415 |
+
IP: IP
|
1416 |
+
}, function(res) {
|
1417 |
+
self.staticTabChanged();
|
1418 |
+
});
|
1419 |
+
},
|
1420 |
+
unblockIP: function(IP) {
|
1421 |
+
var self = this;
|
1422 |
+
this.ajax('wordfence_unblockIP', {
|
1423 |
+
IP: IP
|
1424 |
+
}, function(res) {
|
1425 |
+
self.reloadActivities();
|
1426 |
+
});
|
1427 |
+
},
|
1428 |
+
unblockIPTwo: function(IP) {
|
1429 |
+
var self = this;
|
1430 |
+
this.ajax('wordfence_unblockIP', {
|
1431 |
+
IP: IP
|
1432 |
+
}, function(res) {
|
1433 |
+
self.staticTabChanged();
|
1434 |
+
});
|
1435 |
+
},
|
1436 |
+
permBlockIP: function(IP) {
|
1437 |
+
var self = this;
|
1438 |
+
this.ajax('wordfence_permBlockIP', {
|
1439 |
+
IP: IP
|
1440 |
+
}, function(res) {
|
1441 |
+
self.staticTabChanged();
|
1442 |
+
});
|
1443 |
+
},
|
1444 |
+
makeElemID: function() {
|
1445 |
+
return 'wfElemGen' + this.elementGeneratorIter++;
|
1446 |
+
},
|
1447 |
+
pulse: function(sel) {
|
1448 |
+
jQuery(sel).fadeIn(function() {
|
1449 |
+
setTimeout(function() {
|
1450 |
+
jQuery(sel).fadeOut();
|
1451 |
+
}, 2000);
|
1452 |
+
});
|
1453 |
+
},
|
1454 |
+
getCacheStats: function() {
|
1455 |
+
var self = this;
|
1456 |
+
this.ajax('wordfence_getCacheStats', {}, function(res) {
|
1457 |
+
if (res.ok) {
|
1458 |
+
self.colorbox('400px', res.heading, res.body);
|
1459 |
+
}
|
1460 |
+
});
|
1461 |
+
},
|
1462 |
+
clearPageCache: function() {
|
1463 |
+
var self = this;
|
1464 |
+
this.ajax('wordfence_clearPageCache', {}, function(res) {
|
1465 |
+
if (res.ok) {
|
1466 |
+
self.colorbox('400px', res.heading, res.body);
|
1467 |
+
}
|
1468 |
+
});
|
1469 |
+
},
|
1470 |
+
switchToFalcon: function() {
|
1471 |
+
var self = this;
|
1472 |
+
this.ajax('wordfence_checkFalconHtaccess', {}, function(res) {
|
1473 |
+
if (res.ok) {
|
1474 |
+
self.colorbox('400px', "Enabling Falcon Engine", 'First read this <a href="http://www.wordfence.com/introduction-to-wordfence-falcon-engine/" target="_blank">Introduction to Falcon Engine</a>. Falcon modifies your website configuration file which is called your .htaccess file. To enable Falcon we ask that you make a backup of this file. This is a safety precaution in case for some reason Falcon is not compatible with your site.<br /><br /><a href="' + WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadHtaccess&nonce=' + self.nonce + '" onclick="jQuery(\'#wfNextBut\').prop(\'disabled\', false); return true;">Click here to download a backup copy of your .htaccess file now</a><br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" disabled="disabled" onclick="WFAD.confirmSwitchToFalcon(0);" />');
|
1475 |
+
} else if (res.nginx) {
|
1476 |
+
self.colorbox('400px', "Enabling Falcon Engine", 'You are using an Nginx web server and using a FastCGI processor like PHP5-FPM. To use Falcon you will need to manually modify your nginx.conf configuration file and reload your Nginx server for the changes to take effect. You can find the <a href="http://www.wordfence.com/blog/2014/05/nginx-wordfence-falcon-engine-php-fpm-fastcgi-fast-cgi/" target="_blank">rules you need to make these changes to nginx.conf on this page on wordfence.com</a>. Once you have made these changes, compressed cached files will be served to your visitors directly from Nginx making your site extremely fast. When you have made the changes and reloaded your Nginx server, you can click the button below to enable Falcon.<br /><br /><input type="button" name="but1" id="wfNextBut" value="Click to Enable Falcon Engine" onclick="WFAD.confirmSwitchToFalcon(1);" />');
|
1477 |
+
} else if (res.err) {
|
1478 |
+
self.colorbox('400px', "We encountered a problem", "We can't modify your .htaccess file for you because: " + res.err + "<br /><br />Advanced users: If you would like to manually enable Falcon yourself by editing your .htaccess, you can add the rules below to the beginning of your .htaccess file. Then click the button below to enable Falcon. Don't do this unless you understand website configuration.<br /><textarea style='width: 300px; height:100px;' readonly>" + jQuery('<div/>').text(res.code).html() + "</textarea><br /><input type='button' value='Enable Falcon after manually editing .htaccess' onclick='WFAD.confirmSwitchToFalcon(1);' />");
|
1479 |
+
}
|
1480 |
+
});
|
1481 |
+
},
|
1482 |
+
confirmSwitchToFalcon: function(noEditHtaccess) {
|
1483 |
+
jQuery.colorbox.close();
|
1484 |
+
var cacheType = 'falcon';
|
1485 |
+
var self = this;
|
1486 |
+
this.ajax('wordfence_saveCacheConfig', {
|
1487 |
+
cacheType: cacheType,
|
1488 |
+
noEditHtaccess: noEditHtaccess
|
1489 |
+
}, function(res) {
|
1490 |
+
if (res.ok) {
|
1491 |
+
self.colorbox('400px', res.heading, res.body);
|
1492 |
}
|
1493 |
+
}
|
1494 |
+
);
|
1495 |
+
},
|
1496 |
+
saveCacheConfig: function() {
|
1497 |
+
var cacheType = jQuery('input:radio[name=cacheType]:checked').val();
|
1498 |
+
if (cacheType == 'falcon') {
|
1499 |
+
return this.switchToFalcon();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1500 |
}
|
1501 |
var self = this;
|
1502 |
+
this.ajax('wordfence_saveCacheConfig', {
|
1503 |
+
cacheType: cacheType
|
1504 |
+
}, function(res) {
|
1505 |
+
if (res.ok) {
|
1506 |
+
self.colorbox('400px', res.heading, res.body);
|
1507 |
+
}
|
1508 |
+
}
|
1509 |
+
);
|
1510 |
+
},
|
1511 |
+
saveCacheOptions: function() {
|
1512 |
+
var self = this;
|
1513 |
+
this.ajax('wordfence_saveCacheOptions', {
|
1514 |
+
allowHTTPSCaching: (jQuery('#wfallowHTTPSCaching').is(':checked') ? 1 : 0),
|
1515 |
+
addCacheComment: (jQuery('#wfaddCacheComment').is(':checked') ? 1 : 0),
|
1516 |
+
clearCacheSched: (jQuery('#wfclearCacheSched').is(':checked') ? 1 : 0)
|
1517 |
+
}, function(res) {
|
1518 |
+
if (res.updateErr) {
|
1519 |
+
self.colorbox('400px', "You need to manually update your .htaccess", res.updateErr + "<br />Your option was updated but you need to change the Wordfence code in your .htaccess to the following:<br /><textarea style='width: 300px; height: 120px;'>" + jQuery('<div/>').text(res.code).html() + '</textarea>');
|
1520 |
+
}
|
1521 |
+
}
|
1522 |
+
);
|
1523 |
+
},
|
1524 |
+
saveConfig: function() {
|
1525 |
+
var qstr = jQuery('#wfConfigForm').serialize();
|
1526 |
+
var self = this;
|
1527 |
+
jQuery('.wfSavedMsg').hide();
|
1528 |
+
jQuery('.wfAjax24').show();
|
1529 |
+
this.ajax('wordfence_saveConfig', qstr, function(res) {
|
1530 |
+
jQuery('.wfAjax24').hide();
|
1531 |
+
if (res.ok) {
|
1532 |
+
if (res['paidKeyMsg']) {
|
1533 |
+
self.colorbox('400px', "Congratulations! You have been upgraded to Premium Scanning.", "You have upgraded to a Premium API key. Once this page reloads, you can choose which premium scanning options you would like to enable and then click save. Click the button below to reload this page now.<br /><br /><center><input type='button' name='wfReload' value='Reload page and enable Premium options' onclick='window.location.reload(true);' /></center>");
|
1534 |
+
return;
|
1535 |
+
} else if (res['reload'] == 'reload' || WFAD.reloadConfigPage) {
|
1536 |
+
self.colorbox('400px', "Please reload this page", "You selected a config option that requires a page reload. Click the button below to reload this page to update the menu.<br /><br /><center><input type='button' name='wfReload' value='Reload page' onclick='window.location.reload(true);' /></center>");
|
1537 |
+
return;
|
1538 |
+
} else {
|
1539 |
+
self.pulse('.wfSavedMsg');
|
1540 |
+
}
|
1541 |
+
} else if (res.errorMsg) {
|
1542 |
+
return;
|
1543 |
+
} else {
|
1544 |
+
self.colorbox('400px', 'An error occurred', 'We encountered an error trying to save your changes.');
|
1545 |
+
}
|
1546 |
+
});
|
1547 |
+
},
|
1548 |
+
changeSecurityLevel: function() {
|
1549 |
+
var level = jQuery('#securityLevel').val();
|
1550 |
+
for (var k in WFSLevels[level].checkboxes) {
|
1551 |
+
if (k != 'liveTraf_ignorePublishers') {
|
1552 |
+
jQuery('#' + k).prop("checked", WFSLevels[level].checkboxes[k]);
|
1553 |
+
}
|
1554 |
}
|
1555 |
+
for (var k in WFSLevels[level].otherParams) {
|
1556 |
+
if (!/^(?:apiKey|securityLevel|alertEmails|liveTraf_ignoreUsers|liveTraf_ignoreIPs|liveTraf_ignoreUA|liveTraf_hitsMaxSize|maxMem|maxExecutionTime|actUpdateInterval)$/.test(k)) {
|
1557 |
+
jQuery('#' + k).val(WFSLevels[level].otherParams[k]);
|
1558 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1559 |
}
|
1560 |
+
},
|
1561 |
+
clearAllBlocked: function(op) {
|
1562 |
+
if (op == 'blocked') {
|
1563 |
+
body = "Are you sure you want to clear all blocked IP addresses and allow visitors from those addresses to access the site again?";
|
1564 |
+
} else if (op == 'locked') {
|
1565 |
+
body = "Are you sure you want to clear all locked IP addresses and allow visitors from those addresses to sign in again?";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1566 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1567 |
return;
|
|
|
|
|
1568 |
}
|
1569 |
+
this.colorbox('450px', "Please confirm", body +
|
1570 |
+
'<br /><br /><center><input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" /> ' +
|
1571 |
+
'<input type="button" name="but2" value="Yes I\'m sure" onclick="jQuery.colorbox.close(); WFAD.confirmClearAllBlocked(\'' + op + '\');"><br />');
|
1572 |
+
},
|
1573 |
+
confirmClearAllBlocked: function(op) {
|
1574 |
+
var self = this;
|
1575 |
+
this.ajax('wordfence_clearAllBlocked', {op: op}, function(res) {
|
1576 |
+
self.staticTabChanged();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1577 |
});
|
1578 |
+
},
|
1579 |
+
setOwnCountry: function(code) {
|
1580 |
+
this.ownCountry = (code + "").toUpperCase();
|
1581 |
+
},
|
1582 |
+
loadBlockedCountries: function(str) {
|
1583 |
+
var codes = str.split(',');
|
1584 |
+
for (var i = 0; i < codes.length; i++) {
|
1585 |
+
jQuery('#wfCountryCheckbox_' + codes[i]).prop('checked', true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1586 |
}
|
1587 |
+
},
|
1588 |
+
saveCountryBlocking: function() {
|
1589 |
+
var action = jQuery('#wfBlockAction').val();
|
1590 |
+
var redirURL = jQuery('#wfRedirURL').val();
|
1591 |
+
var bypassRedirURL = jQuery('#wfBypassRedirURL').val();
|
1592 |
+
var bypassRedirDest = jQuery('#wfBypassRedirDest').val();
|
1593 |
+
var bypassViewURL = jQuery('#wfBypassViewURL').val();
|
1594 |
+
|
1595 |
+
if (action == 'redir' && (!/^https?:\/\/[^\/]+/i.test(redirURL))) {
|
1596 |
+
this.colorbox('400px', "Please enter a URL for redirection", "You have chosen to redirect blocked countries to a specific page. You need to enter a URL in the text box provided that starts with http:// or https://");
|
1597 |
+
return;
|
|
|
|
|
|
|
1598 |
}
|
1599 |
+
if (bypassRedirURL || bypassRedirDest) {
|
1600 |
+
if (!(bypassRedirURL && bypassRedirDest)) {
|
1601 |
+
this.colorbox('400px', "Missing data from form", "If you want to set up a URL that will bypass country blocking, you must enter a URL that a visitor can hit and the destination they will be redirected to. You have only entered one of these components. Please enter both.");
|
1602 |
+
return;
|
1603 |
+
}
|
1604 |
+
if (bypassRedirURL == bypassRedirDest) {
|
1605 |
+
this.colorbox('400px', "URLs are the same", "The URL that a user hits to bypass country blocking and the URL they are redirected to are the same. This would cause a circular redirect. Please fix this.");
|
1606 |
+
return;
|
1607 |
+
}
|
|
|
|
|
|
|
1608 |
}
|
1609 |
+
if (bypassRedirURL && (!/^(?:\/|http:\/\/)/.test(bypassRedirURL))) {
|
1610 |
+
this.invalidCountryURLMsg(bypassRedirURL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1611 |
return;
|
1612 |
+
}
|
1613 |
+
if (bypassRedirDest && (!/^(?:\/|http:\/\/)/.test(bypassRedirDest))) {
|
1614 |
+
this.invalidCountryURLMsg(bypassRedirDest);
|
1615 |
+
return;
|
1616 |
+
}
|
1617 |
+
if (bypassViewURL && (!/^(?:\/|http:\/\/)/.test(bypassViewURL))) {
|
1618 |
+
this.invalidCountryURLMsg(bypassViewURL);
|
1619 |
return;
|
|
|
|
|
1620 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1621 |
|
1622 |
+
var codesArr = [];
|
1623 |
+
var ownCountryBlocked = false;
|
1624 |
+
var self = this;
|
1625 |
+
jQuery('.wfCountryCheckbox').each(function(idx, elem) {
|
1626 |
+
if (jQuery(elem).is(':checked')) {
|
1627 |
+
var code = jQuery(elem).val();
|
1628 |
+
codesArr.push(code);
|
1629 |
+
if (code == self.ownCountry) {
|
1630 |
+
ownCountryBlocked = true;
|
1631 |
+
}
|
1632 |
+
}
|
1633 |
+
});
|
1634 |
+
this.countryCodesToSave = codesArr.join(',');
|
1635 |
+
if (ownCountryBlocked) {
|
1636 |
+
this.colorbox('400px', "Please confirm blocking yourself", "You are about to block your own country. This could lead to you being locked out. Please make sure that your user profile on this machine has a current and valid email address and make sure you know what it is. That way if you are locked out, you can send yourself an unlock email. If you're sure you want to block your own country, click 'Confirm' below, otherwise click 'Cancel'.<br />" +
|
1637 |
+
'<input type="button" name="but1" value="Confirm" onclick="jQuery.colorbox.close(); WFAD.confirmSaveCountryBlocking();" /> <input type="button" name="but1" value="Cancel" onclick="jQuery.colorbox.close();" />');
|
1638 |
+
} else {
|
1639 |
+
this.confirmSaveCountryBlocking();
|
1640 |
}
|
1641 |
+
},
|
1642 |
+
invalidCountryURLMsg: function(URL) {
|
1643 |
+
this.colorbox('400px', "Invalid URL", "URL's that you provide for bypassing country blocking must start with '/' or 'http://' without quotes. The URL that is invalid is: " + URL);
|
1644 |
+
return;
|
1645 |
+
},
|
1646 |
+
confirmSaveCountryBlocking: function() {
|
1647 |
+
var action = jQuery('#wfBlockAction').val();
|
1648 |
+
var redirURL = jQuery('#wfRedirURL').val();
|
1649 |
+
var loggedInBlocked = jQuery('#wfLoggedInBlocked').is(':checked') ? '1' : '0';
|
1650 |
+
var loginFormBlocked = jQuery('#wfLoginFormBlocked').is(':checked') ? '1' : '0';
|
1651 |
+
var restOfSiteBlocked = jQuery('#wfRestOfSiteBlocked').is(':checked') ? '1' : '0';
|
1652 |
+
var bypassRedirURL = jQuery('#wfBypassRedirURL').val();
|
1653 |
+
var bypassRedirDest = jQuery('#wfBypassRedirDest').val();
|
1654 |
+
var bypassViewURL = jQuery('#wfBypassViewURL').val();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1655 |
|
1656 |
+
jQuery('.wfAjax24').show();
|
1657 |
+
var self = this;
|
1658 |
+
this.ajax('wordfence_saveCountryBlocking', {
|
1659 |
+
blockAction: action,
|
1660 |
+
redirURL: redirURL,
|
1661 |
+
loggedInBlocked: loggedInBlocked,
|
1662 |
+
loginFormBlocked: loginFormBlocked,
|
1663 |
+
restOfSiteBlocked: restOfSiteBlocked,
|
1664 |
+
bypassRedirURL: bypassRedirURL,
|
1665 |
+
bypassRedirDest: bypassRedirDest,
|
1666 |
+
bypassViewURL: bypassViewURL,
|
1667 |
+
codes: this.countryCodesToSave
|
1668 |
+
}, function(res) {
|
1669 |
+
jQuery('.wfAjax24').hide();
|
1670 |
+
self.pulse('.wfSavedMsg');
|
1671 |
});
|
1672 |
+
},
|
1673 |
+
paidUsersOnly: function(msg) {
|
1674 |
+
var pos = jQuery('#paidWrap').position();
|
1675 |
+
var width = jQuery('#paidWrap').width();
|
1676 |
+
var height = jQuery('#paidWrap').height();
|
1677 |
+
jQuery('<div style="position: absolute; left: ' + pos.left + 'px; top: ' + pos.top + 'px; background-color: #FFF; width: ' + width + 'px; height: ' + height + 'px;"><div class="paidInnerMsg">' + msg + ' <a href="https://www.wordfence.com/wordfence-signup/" target="_blank">Click here to upgrade and gain access to this feature.</div></div>').insertAfter('#paidWrap').fadeTo(10000, 0.7);
|
1678 |
+
},
|
1679 |
+
sched_modeChange: function() {
|
1680 |
+
var self = this;
|
1681 |
+
if (jQuery('#schedMode').val() == 'auto') {
|
1682 |
+
jQuery('.wfSchedCheckbox').attr('disabled', true);
|
1683 |
+
} else {
|
1684 |
+
jQuery('.wfSchedCheckbox').attr('disabled', false);
|
1685 |
+
}
|
1686 |
+
},
|
1687 |
+
sched_shortcut: function(mode) {
|
1688 |
+
if (jQuery('#schedMode').val() == 'auto') {
|
1689 |
+
this.colorbox('400px', 'Change the scan mode', "You need to change the scan mode to manually scheduled scans if you want to select scan times.");
|
1690 |
+
return;
|
1691 |
+
}
|
1692 |
+
jQuery('.wfSchedCheckbox').prop('checked', false);
|
1693 |
+
if (this.schedStartHour === false) {
|
1694 |
+
this.schedStartHour = Math.floor((Math.random() * 24));
|
1695 |
+
} else {
|
1696 |
+
this.schedStartHour++;
|
1697 |
+
if (this.schedStartHour > 23) {
|
1698 |
+
this.schedStartHour = 0;
|
1699 |
+
}
|
1700 |
+
}
|
1701 |
+
if (mode == 'onceDaily') {
|
1702 |
+
for (var i = 0; i <= 6; i++) {
|
1703 |
+
jQuery('#wfSchedDay_' + i + '_' + this.schedStartHour).attr('checked', true);
|
1704 |
+
}
|
1705 |
+
} else if (mode == 'twiceDaily') {
|
1706 |
+
var secondHour = this.schedStartHour + 12;
|
1707 |
+
if (secondHour >= 24) {
|
1708 |
+
secondHour = secondHour - 24;
|
1709 |
+
}
|
1710 |
+
for (var i = 0; i <= 6; i++) {
|
1711 |
+
jQuery('#wfSchedDay_' + i + '_' + this.schedStartHour).attr('checked', true);
|
1712 |
+
jQuery('#wfSchedDay_' + i + '_' + secondHour).attr('checked', true);
|
1713 |
+
}
|
1714 |
+
} else if (mode == 'oddDaysWE') {
|
1715 |
+
var startDay = Math.floor((Math.random()));
|
1716 |
+
jQuery('#wfSchedDay_1_' + this.schedStartHour).attr('checked', true);
|
1717 |
+
jQuery('#wfSchedDay_3_' + this.schedStartHour).attr('checked', true);
|
1718 |
+
jQuery('#wfSchedDay_5_' + this.schedStartHour).attr('checked', true);
|
1719 |
+
jQuery('#wfSchedDay_6_' + this.schedStartHour).attr('checked', true);
|
1720 |
+
jQuery('#wfSchedDay_0_' + this.schedStartHour).attr('checked', true);
|
1721 |
+
} else if (mode == 'weekends') {
|
1722 |
+
var startDay = Math.floor((Math.random()));
|
1723 |
+
jQuery('#wfSchedDay_6_' + this.schedStartHour).attr('checked', true);
|
1724 |
+
jQuery('#wfSchedDay_0_' + this.schedStartHour).attr('checked', true);
|
1725 |
+
} else if (mode == 'every6hours') {
|
1726 |
+
for (var i = 0; i <= 6; i++) {
|
1727 |
+
for (var hour = this.schedStartHour; hour < this.schedStartHour + 24; hour = hour + 6) {
|
1728 |
+
var displayHour = hour;
|
1729 |
+
if (displayHour >= 24) {
|
1730 |
+
displayHour = displayHour - 24;
|
1731 |
+
}
|
1732 |
+
jQuery('#wfSchedDay_' + i + '_' + displayHour).attr('checked', true);
|
1733 |
+
}
|
1734 |
+
}
|
1735 |
}
|
|
|
|
|
1736 |
|
1737 |
+
},
|
1738 |
+
sched_save: function() {
|
1739 |
+
var schedMode = jQuery('#schedMode').val();
|
1740 |
+
var schedule = [];
|
1741 |
+
for (var day = 0; day <= 6; day++) {
|
1742 |
+
var hours = [];
|
1743 |
+
for (var hour = 0; hour <= 23; hour++) {
|
1744 |
+
var elemID = '#wfSchedDay_' + day + '_' + hour;
|
1745 |
+
hours[hour] = jQuery(elemID).is(':checked') ? '1' : '0';
|
1746 |
+
}
|
1747 |
+
schedule[day] = hours.join(',');
|
1748 |
+
}
|
1749 |
+
var scheduleTxt = schedule.join('|');
|
1750 |
+
var self = this;
|
1751 |
+
this.ajax('wordfence_saveScanSchedule', {
|
1752 |
+
schedMode: schedMode,
|
1753 |
+
schedTxt: scheduleTxt
|
1754 |
+
}, function(res) {
|
1755 |
+
jQuery('#wfScanStartTime').html(res.nextStart);
|
1756 |
+
jQuery('.wfAjax24').hide();
|
1757 |
+
self.pulse('.wfSaveMsg');
|
1758 |
+
});
|
1759 |
+
},
|
1760 |
+
twoFacStatus: function(msg) {
|
1761 |
+
jQuery('#wfTwoFacMsg').html(msg);
|
1762 |
+
jQuery('#wfTwoFacMsg').fadeIn(function() {
|
1763 |
+
setTimeout(function() {
|
1764 |
+
jQuery('#wfTwoFacMsg').fadeOut();
|
1765 |
+
}, 2000);
|
1766 |
+
});
|
1767 |
+
},
|
1768 |
+
addTwoFactor: function(username, phone) {
|
1769 |
+
var self = this;
|
1770 |
+
this.ajax('wordfence_addTwoFactor', {
|
1771 |
+
username: username,
|
1772 |
+
phone: phone
|
1773 |
+
}, function(res) {
|
1774 |
+
if (res.ok) {
|
1775 |
+
self.twoFacStatus('User added! Check the user\'s phone to get the activation code.');
|
1776 |
+
jQuery('<div id="twoFacCont_' + res.userID + '">' + jQuery('#wfTwoFacUserTmpl').tmpl(res).html() + '</div>').prependTo(jQuery('#wfTwoFacUsers'));
|
1777 |
+
}
|
1778 |
});
|
1779 |
+
},
|
1780 |
+
twoFacActivate: function(userID, code) {
|
1781 |
+
var self = this;
|
1782 |
+
this.ajax('wordfence_twoFacActivate', {
|
1783 |
+
userID: userID,
|
1784 |
+
code: code
|
1785 |
+
}, function(res) {
|
1786 |
+
if (res.ok) {
|
1787 |
+
jQuery('#twoFacCont_' + res.userID).html(
|
1788 |
+
jQuery('#wfTwoFacUserTmpl').tmpl(res)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1789 |
);
|
1790 |
+
self.twoFacStatus('Cellphone Sign-in activated for user.');
|
1791 |
+
}
|
1792 |
+
});
|
1793 |
+
},
|
1794 |
+
delTwoFac: function(userID) {
|
1795 |
+
this.ajax('wordfence_twoFacDel', {
|
1796 |
+
userID: userID
|
1797 |
+
}, function(res) {
|
1798 |
+
if (res.ok) {
|
1799 |
+
jQuery('#twoFacCont_' + res.userID).fadeOut(function() {
|
1800 |
+
jQuery(this).remove();
|
1801 |
+
});
|
1802 |
+
}
|
1803 |
+
});
|
1804 |
+
},
|
1805 |
+
loadTwoFactor: function() {
|
1806 |
+
this.ajax('wordfence_loadTwoFactor', {}, function(res) {
|
1807 |
+
if (res.users && res.users.length > 0) {
|
1808 |
+
for (var i = 0; i < res.users.length; i++) {
|
1809 |
+
jQuery('<div id="twoFacCont_' + res.users[i].userID + '">' +
|
1810 |
+
jQuery('#wfTwoFacUserTmpl').tmpl(res.users[i]).html() + '</div>').appendTo(jQuery('#wfTwoFacUsers'));
|
1811 |
+
}
|
1812 |
+
}
|
1813 |
+
});
|
1814 |
+
},
|
1815 |
+
getQueryParam: function(name) {
|
1816 |
+
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
|
1817 |
+
var regexS = "[\\?&]" + name + "=([^&#]*)";
|
1818 |
+
var regex = new RegExp(regexS);
|
1819 |
+
var results = regex.exec(window.location.search);
|
1820 |
+
if (results == null) {
|
1821 |
+
return "";
|
1822 |
+
} else {
|
1823 |
+
return decodeURIComponent(results[1].replace(/\+/g, " "));
|
1824 |
}
|
1825 |
+
},
|
1826 |
+
inet_aton: function(dot) {
|
1827 |
+
var d = dot.split('.');
|
1828 |
+
return ((((((+d[0]) * 256) + (+d[1])) * 256) + (+d[2])) * 256) + (+d[3]);
|
1829 |
+
},
|
1830 |
+
inet_ntoa: function(num) {
|
1831 |
+
var d = num % 256;
|
1832 |
+
for (var i = 3; i > 0; i--) {
|
1833 |
+
num = Math.floor(num / 256);
|
1834 |
+
d = num % 256 + '.' + d;
|
1835 |
+
}
|
1836 |
+
return d;
|
1837 |
+
},
|
1838 |
+
removeCacheExclusion: function(id) {
|
1839 |
+
this.ajax('wordfence_removeCacheExclusion', {id: id}, function(res) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1840 |
window.location.reload(true);
|
1841 |
+
});
|
1842 |
+
},
|
1843 |
+
addCacheExclusion: function(patternType, pattern) {
|
1844 |
+
if (/^https?:\/\//.test(pattern)) {
|
1845 |
+
this.colorbox('400px', "Incorrect pattern for exclusion", "You can not enter full URL's for exclusion from caching. You entered a full URL that started with http:// or https://. You must enter relative URL's e.g. /exclude/this/page/. You can also enter text that might be contained in the path part of a URL or at the end of the path part of a URL.");
|
1846 |
+
return;
|
1847 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1848 |
|
1849 |
+
this.ajax('wordfence_addCacheExclusion', {
|
1850 |
+
patternType: patternType,
|
1851 |
+
pattern: pattern
|
1852 |
+
}, function(res) {
|
1853 |
+
if (res.ok) { //Otherwise errorMsg will get caught
|
1854 |
+
window.location.reload(true);
|
1855 |
+
}
|
1856 |
+
});
|
1857 |
+
},
|
1858 |
+
loadCacheExclusions: function() {
|
1859 |
+
this.ajax('wordfence_loadCacheExclusions', {}, function(res) {
|
1860 |
+
if (res.ex instanceof Array && res.ex.length > 0) {
|
1861 |
+
for (var i = 0; i < res.ex.length; i++) {
|
1862 |
+
var newElem = jQuery('#wfCacheExclusionTmpl').tmpl(res.ex[i]);
|
1863 |
+
newElem.prependTo('#wfCacheExclusions').fadeIn();
|
1864 |
+
}
|
1865 |
+
jQuery('<h2>Cache Exclusions</h2>').prependTo('#wfCacheExclusions');
|
1866 |
+
} else {
|
1867 |
+
jQuery('<h2>Cache Exclusions</h2><p style="width: 500px;">There are not currently any exclusions. If you have a site that does not change often, it is perfectly normal to not have any pages you want to exclude from the cache.</p>').prependTo('#wfCacheExclusions');
|
1868 |
+
}
|
1869 |
+
|
1870 |
+
});
|
1871 |
+
},
|
1872 |
+
exportSettings: function() {
|
1873 |
+
var self = this;
|
1874 |
+
this.ajax('wordfence_exportSettings', {}, function(res) {
|
1875 |
+
if (res.ok && res.token) {
|
1876 |
+
self.colorbox('400px', "Export Successful", "We successfully exported your site settings. To import your site settings on another site, copy and paste the token below into the import text box on the destination site. Keep this token secret. It is like a password. If anyone else discovers the token it will allow them to import your settings excluding your API key.<br /><br />Token:<input type=\"text\" size=\"20\" value=\"" + res.token + "\" onclick=\"this.select();\" /><br />");
|
1877 |
+
} else if (res.err) {
|
1878 |
+
self.colorbox('400px', "Error during Export", res.err);
|
1879 |
+
} else {
|
1880 |
+
self.colorbox('400px', "An unknown error occurred", "An unknown error occurred during the export. We received an undefined error from your web server.");
|
1881 |
+
}
|
1882 |
+
});
|
1883 |
+
},
|
1884 |
+
importSettings: function(token) {
|
1885 |
+
var self = this;
|
1886 |
+
this.ajax('wordfence_importSettings', {token: token}, function(res) {
|
1887 |
+
if (res.ok) {
|
1888 |
+
self.colorbox('400px', "Import Successful", "You successfully imported " + res.totalSet + " options. Your import is complete. Please reload this page or click the button below to reload it:<br /><br /><input type=\"button\" value=\"Reload Page\" onclick=\"window.location.reload(true);\" />");
|
1889 |
+
} else if (res.err) {
|
1890 |
+
self.colorbox('400px', "Error during Import", res.err);
|
1891 |
+
} else {
|
1892 |
+
self.colorbox('400px', "Error during Export", "An unknown error occurred during the import");
|
1893 |
+
}
|
1894 |
+
});
|
1895 |
+
},
|
1896 |
+
startPasswdAudit: function(auditType, emailAddr) {
|
1897 |
+
var self = this;
|
1898 |
+
this.ajax('wordfence_startPasswdAudit', {auditType: auditType, emailAddr: emailAddr}, function(res) {
|
1899 |
+
self.loadPasswdAuditJobs();
|
1900 |
+
if (res.ok) {
|
1901 |
+
self.colorbox('400px', "Password Audit Started", "Your password audit started successfully. The results will appear here once it is complete. You will also receive an email letting you know the results are ready at: " + emailAddr);
|
1902 |
+
} else if (!res.errorMsg) { //error displayed
|
1903 |
+
self.colorbox('400px', "Error Starting Audit", "An unknown error occurred when trying to start your password audit.");
|
1904 |
+
}
|
1905 |
+
});
|
1906 |
}
|
1907 |
+
};
|
1908 |
+
window['WFAD'] = window['wordfenceAdmin'];
|
1909 |
}
|
1910 |
+
jQuery(function() {
|
1911 |
+
wordfenceAdmin.init();
|
1912 |
+
});
|
1913 |
+
})(jQuery);
|
|
|
|
lib/email_passwdChanged.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
This email was sent from <?php echo $homeURL; ?>.
|
2 |
+
|
3 |
+
We recently used Wordfence to audit the strength of passwords on our website.
|
4 |
+
We have detected that you have a weak password.
|
5 |
+
|
6 |
+
To ensure your user account remains secure we have changed your password to:
|
7 |
+
|
8 |
+
<?php echo $passwd; ?>
|
9 |
+
|
10 |
+
Please sign into <?php echo $homeURL; ?> now using this new password to verify
|
11 |
+
that it works. Your username is: <?php echo $username; ?>
|
12 |
+
|
13 |
+
We recommend that once you are signed-in you immediately change
|
14 |
+
this password to one of your own choosing. We suggest you use a pass-phrase or
|
15 |
+
a combination of upper-case, lower-case, numbers and symbols.
|
16 |
+
|
17 |
+
You can sign in here:
|
18 |
+
|
19 |
+
<?php echo $loginURL; ?>
|
20 |
+
|
21 |
+
Thank you.
|
22 |
+
|
23 |
+
Email generated by Wordfence. Learn more at http://www.wordfence.com/
|
lib/email_pleaseChangePasswd.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
This email was sent from <?php echo $homeURL; ?>.
|
2 |
+
|
3 |
+
We recently used Wordfence to audit the strength of passwords on our website.
|
4 |
+
We have detected that you have a weak password.
|
5 |
+
|
6 |
+
This may mean that you have a password that is easy to guess. It may also mean that
|
7 |
+
you are using a password that is known to hackers.
|
8 |
+
|
9 |
+
Please sign into <?php echo $homeURL; ?> now and change your password to ensure
|
10 |
+
your account remains secure. You can access our sign-in page at:
|
11 |
+
|
12 |
+
<?php echo $loginURL; ?>
|
13 |
+
|
14 |
+
|
15 |
+
Your username is: <?php echo $username; ?>
|
16 |
+
|
17 |
+
|
18 |
+
We recommend that you use a pass-phrase or a combination of upper-case, lower-case,
|
19 |
+
numbers and symbols in your password.
|
20 |
+
|
21 |
+
Thank you.
|
22 |
+
|
23 |
+
Email generated by Wordfence. Learn more at http://www.wordfence.com/
|
lib/menu_countryBlocking.php
CHANGED
@@ -37,7 +37,7 @@ WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
|
|
37 |
<option value="redir"<?php if(wfConfig::get('cbl_action') == 'redir'){ echo ' selected'; } ?>>Redirect to the URL below</option>
|
38 |
</select>
|
39 |
</td></tr>
|
40 |
-
<tr><th>URL to redirect blocked users to:</th><td><input type="text" id="wfRedirURL" size="40" value="<?php if(wfConfig::get('cbl_redirURL')){ echo
|
41 |
<br />
|
42 |
<span style="color: #999;">Must start with http:// for example http://yoursite.com/blocked/</span></td></tr>
|
43 |
<tr><th>Block countries even if they are logged in:</th><td><input type="checkbox" id="wfLoggedInBlocked" value="1" <?php if(wfConfig::get('cbl_loggedInBlocked')){ echo 'checked'; } ?> /></td></tr>
|
@@ -46,9 +46,9 @@ WFAD.countryMap = <?php echo json_encode($wfBulkCountries); ?>;
|
|
46 |
<tr><td colspan="2"><h2>Advanced Country Blocking Options</h2></td></tr>
|
47 |
<tr><th colspan="2">
|
48 |
If user hits the URL
|
49 |
-
<input type="text" id="wfBypassRedirURL" value="<?php echo
|
50 |
then redirect that user to
|
51 |
-
<input type="text" id="wfBypassRedirDest" value="<?php echo
|
52 |
</th></tr>
|
53 |
<tr><th colspan="2">
|
54 |
If user who is allowed to access the site views the URL
|
37 |
<option value="redir"<?php if(wfConfig::get('cbl_action') == 'redir'){ echo ' selected'; } ?>>Redirect to the URL below</option>
|
38 |
</select>
|
39 |
</td></tr>
|
40 |
+
<tr><th>URL to redirect blocked users to:</th><td><input type="text" id="wfRedirURL" size="40" value="<?php if(wfConfig::get('cbl_redirURL')){ echo esc_attr(wfConfig::get('cbl_redirURL')); } ?>" />
|
41 |
<br />
|
42 |
<span style="color: #999;">Must start with http:// for example http://yoursite.com/blocked/</span></td></tr>
|
43 |
<tr><th>Block countries even if they are logged in:</th><td><input type="checkbox" id="wfLoggedInBlocked" value="1" <?php if(wfConfig::get('cbl_loggedInBlocked')){ echo 'checked'; } ?> /></td></tr>
|
46 |
<tr><td colspan="2"><h2>Advanced Country Blocking Options</h2></td></tr>
|
47 |
<tr><th colspan="2">
|
48 |
If user hits the URL
|
49 |
+
<input type="text" id="wfBypassRedirURL" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirURL'), array()); ?>" size="20" />
|
50 |
then redirect that user to
|
51 |
+
<input type="text" id="wfBypassRedirDest" value="<?php echo esc_attr(wfConfig::get('cbl_bypassRedirDest'), array()); ?>" size="20" /> and set a cookie that will bypass all country blocking.
|
52 |
</th></tr>
|
53 |
<tr><th colspan="2">
|
54 |
If user who is allowed to access the site views the URL
|
lib/menu_options.php
CHANGED
@@ -318,6 +318,51 @@ $w = new wfConfig();
|
|
318 |
alerts will be sent.
|
319 |
</td>
|
320 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
<tr>
|
322 |
<td colspan="2">
|
323 |
<div class="wfMarker" id="wfMarkerLiveTrafficOptions"></div>
|
@@ -359,7 +404,7 @@ $w = new wfConfig();
|
|
359 |
href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site"
|
360 |
target="_blank" class="wfhelp"></a></th>
|
361 |
<td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem"
|
362 |
-
name="scansEnabled_public" value="1" <?php $w->cb( 'scansEnabled_public' );
|
363 |
</tr>
|
364 |
<?php } else { ?>
|
365 |
<tr>
|
@@ -377,7 +422,7 @@ $w = new wfConfig();
|
|
377 |
href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_the_HeartBleed_vulnerability"
|
378 |
target="_blank" class="wfhelp"></a></th>
|
379 |
<td><input type="checkbox" id="scansEnabled_heartbleed" class="wfConfigElem"
|
380 |
-
name="scansEnabled_heartbleed" value="1" <?php $w->cb( 'scansEnabled_heartbleed' ); ?>
|
381 |
</td>
|
382 |
</tr>
|
383 |
<tr>
|
318 |
alerts will be sent.
|
319 |
</td>
|
320 |
</tr>
|
321 |
+
<tr>
|
322 |
+
<td colspan="2">
|
323 |
+
<div class="wfMarker" id="wfMarkerEmailSummary"></div>
|
324 |
+
<h3 class="wfConfigHeading">Email Summary<a
|
325 |
+
href="http://docs.wordfence.com/en/Wordfence_options#Email_Summary" target="_blank"
|
326 |
+
class="wfhelp"></a></h3>
|
327 |
+
</td>
|
328 |
+
</tr>
|
329 |
+
<tr>
|
330 |
+
<th>Enable email summary:</th>
|
331 |
+
<td> <input type="checkbox" id="email_summary_enabled" name="email_summary_enabled"
|
332 |
+
value="1" <?php $w->cb('email_summary_enabled'); ?> />
|
333 |
+
</td>
|
334 |
+
</tr>
|
335 |
+
<tr>
|
336 |
+
<th>Email summary frequency:</th>
|
337 |
+
<td>
|
338 |
+
<select id="email_summary_interval" class="wfConfigElem" name="email_summary_interval">
|
339 |
+
<option value="weekly"<?php $w->sel( 'email_summary_interval', 'weekly' ); ?>>Once a week</option>
|
340 |
+
<option value="biweekly"<?php $w->sel( 'email_summary_interval', 'biweekly' ); ?>>Once every 2 weeks</option>
|
341 |
+
<option value="monthly"<?php $w->sel( 'email_summary_interval', 'monthly' ); ?>>Once a month</option>
|
342 |
+
</select>
|
343 |
+
</td>
|
344 |
+
</tr>
|
345 |
+
<tr>
|
346 |
+
<th>Comma-separated list of directories to exclude from recently modified file list:</th>
|
347 |
+
<td>
|
348 |
+
<input name="email_summary_excluded_directories" type="text" value="<?php $w->f('email_summary_excluded_directories') ?>"/>
|
349 |
+
</td>
|
350 |
+
</tr>
|
351 |
+
<?php if ((defined('WP_DEBUG') && WP_DEBUG) || wfConfig::get('debugOn', 0)): ?>
|
352 |
+
<tr>
|
353 |
+
<th>Send test email:</th>
|
354 |
+
<td>
|
355 |
+
<input type="email" id="email_summary_email_address_debug" />
|
356 |
+
<a class="button" href="javascript:void(0);" onclick="WFAD.ajax('wordfence_email_summary_email_address_debug', {email: jQuery('#email_summary_email_address_debug').val()});">Send Email</a>
|
357 |
+
</td>
|
358 |
+
</tr>
|
359 |
+
<?php endif ?>
|
360 |
+
<tr>
|
361 |
+
<th>Enable activity report widget on dashboard:</th>
|
362 |
+
<td> <input type="checkbox" id="email_summary_dashboard_widget_enabled" name="email_summary_dashboard_widget_enabled"
|
363 |
+
value="1" <?php $w->cb('email_summary_dashboard_widget_enabled'); ?> />
|
364 |
+
</td>
|
365 |
+
</tr>
|
366 |
<tr>
|
367 |
<td colspan="2">
|
368 |
<div class="wfMarker" id="wfMarkerLiveTrafficOptions"></div>
|
404 |
href="http://docs.wordfence.com/en/Wordfence_options#Scan_public_facing_site"
|
405 |
target="_blank" class="wfhelp"></a></th>
|
406 |
<td><input type="checkbox" id="scansEnabled_public" class="wfConfigElem"
|
407 |
+
name="scansEnabled_public" value="1" <?php $w->cb( 'scansEnabled_public' ); ?> /></td>
|
408 |
</tr>
|
409 |
<?php } else { ?>
|
410 |
<tr>
|
422 |
href="http://docs.wordfence.com/en/Wordfence_options#Scan_for_the_HeartBleed_vulnerability"
|
423 |
target="_blank" class="wfhelp"></a></th>
|
424 |
<td><input type="checkbox" id="scansEnabled_heartbleed" class="wfConfigElem"
|
425 |
+
name="scansEnabled_heartbleed" value="1" <?php $w->cb( 'scansEnabled_heartbleed' ); ?> />
|
426 |
</td>
|
427 |
</tr>
|
428 |
<tr>
|
lib/menu_passwd.php
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wordfenceModeElem" id="wordfenceMode_passwd"></div>
|
2 |
+
<div class="wrap" id="paidWrap">
|
3 |
+
<?php require('menuHeader.php'); ?>
|
4 |
+
<?php $pageTitle = "Audit the Strength of your Passwords";
|
5 |
+
$helpLink = "http://docs.wordfence.com/en/Wordfence_Password_Auditing";
|
6 |
+
$helpLabel = "Learn more about Password Auditing";
|
7 |
+
include('pageTitle.php'); ?>
|
8 |
+
<?php if (!wfConfig::get('isPaid')) { ?>
|
9 |
+
<div class="wfPaidOnlyNotice">
|
10 |
+
<strong>Password Auditing is only available to Premium Members at this time</strong><br/><br/>
|
11 |
+
Wordfence Password Auditing uses our high performance password auditing cluster to test the strength of your admin and user passwords.
|
12 |
+
We securely simulate a high-performance password cracking attack on your password database and will alert you to weak passwords.
|
13 |
+
We then provide a way to change weak passwords or alert members that they need to improve their password strength.
|
14 |
+
To activate this feature, simply
|
15 |
+
<a href="https://www.wordfence.com/wordfence-signup/" target="_blank">click here and get a premium Wordfence API Key</a>, and then copy and paste it into your options page. You can
|
16 |
+
<a href="http://docs.wordfence.com/en/Wordfence_Password_Auditing" target="_blank">learn more about Password Auditing on our Documentation Website</a>.
|
17 |
+
</div>
|
18 |
+
<?php } ?>
|
19 |
+
|
20 |
+
<div class="wordfenceWrap" style="margin: 20px 20px 20px 30px;">
|
21 |
+
<h2>Start a Password Audit</h2>
|
22 |
+
<table class="wfConfigForm" width="800px">
|
23 |
+
<tr>
|
24 |
+
<td colspan="2">Audit your site passwords by having
|
25 |
+
us securely simulate a password cracking attempt using our high performance servers.
|
26 |
+
Your report will appear here and you can easily alert your users to a weak password or change their passwords and email them the change.
|
27 |
+
</td>
|
28 |
+
</tr>
|
29 |
+
<tr>
|
30 |
+
<th colspan="2">Select the kind of audit you would like to do:</th>
|
31 |
+
</tr>
|
32 |
+
<tr>
|
33 |
+
<th colspan="2">
|
34 |
+
<select id="auditType">
|
35 |
+
<option value="admin">Audit administrator level accounts (extensive audit against a large dictionary of approx. 260 Million passwords)</option>
|
36 |
+
<option value="user">Audit user level accounts (less extensive against a dictionary of approximately 50,000 passwords)</option>
|
37 |
+
<option value="both">Audit all WordPress accounts</option>
|
38 |
+
</select>
|
39 |
+
</th>
|
40 |
+
</tr>
|
41 |
+
<tr>
|
42 |
+
<th>Results will appear on this page. We will email you when they're ready. Enter the email address we should email:</th>
|
43 |
+
<td><input type="text" id="emailAddr" size="50" maxlength="255" value="<?php wfConfig::f('alertEmails') ?>"/></td>
|
44 |
+
</tr>
|
45 |
+
<tr>
|
46 |
+
<td colspan="2"><input type="button" name="but4" class="button-primary" value="Start Password Audit"
|
47 |
+
onclick="WFAD.startPasswdAudit(jQuery('#auditType').val(), jQuery('#emailAddr').val());"/>
|
48 |
+
</td>
|
49 |
+
</tr>
|
50 |
+
|
51 |
+
</table>
|
52 |
+
<h2 style="margin-top: 20px;">Audit Status:</h2>
|
53 |
+
|
54 |
+
<div id="wfAuditJobs">
|
55 |
+
</div>
|
56 |
+
<h2 style="margin-top: 20px;">Password Audit Results:</h2>
|
57 |
+
|
58 |
+
<div id="wfAuditResults">
|
59 |
+
</div>
|
60 |
+
</div>
|
61 |
+
|
62 |
+
</div>
|
63 |
+
<script type="text/x-jquery-template" id="wfAuditResultsTable">
|
64 |
+
<div style="margin: 0 0 20px 0;">
|
65 |
+
<select id="wfPasswdFixAction">
|
66 |
+
<option value="email">Action: Email selected users and ask them to change their weak password.</option>
|
67 |
+
<option value="fix">Action: Change weak passwords to a strong password and email users the new password.</option>
|
68 |
+
</select><input type="button" value="Fix Weak Passwords" onclick="WFAD.doFixWeakPasswords(); return false;" class="button-primary"/>
|
69 |
+
</div>
|
70 |
+
<table class="wf-table">
|
71 |
+
<thead>
|
72 |
+
<th style="text-align: center">
|
73 |
+
<input type="checkbox" id="wfSelectAll" onclick="jQuery('.wfUserCheck').attr('checked', this.checked);" />
|
74 |
+
</th>
|
75 |
+
<th>User Level</th>
|
76 |
+
<th>Username</th>
|
77 |
+
<th>Full Name</th>
|
78 |
+
<th>Email</th>
|
79 |
+
<th>Password</th>
|
80 |
+
<th>Crack Time</th>
|
81 |
+
<th>Crack Difficulty</th>
|
82 |
+
</thead>
|
83 |
+
<tbody class="wf-pw-audit-tbody"></tbody>
|
84 |
+
</table>
|
85 |
+
</script>
|
86 |
+
|
87 |
+
<script type="text/x-jquery-template" id="wfAuditResultsRow">
|
88 |
+
<tr>
|
89 |
+
<td style="text-align: center;">
|
90 |
+
<input type="checkbox" class="wfUserCheck" value="${wpUserID}"/>
|
91 |
+
</td>
|
92 |
+
<td>{{if wpIsAdmin == '1'}}<span style="color: #F00;">Admin</span>{{else}}User{{/if}}</td>
|
93 |
+
<td>${username}</td>
|
94 |
+
<td>${firstName} ${lastName}</td>
|
95 |
+
<td>${email}</td>
|
96 |
+
<td>${starredPassword}</td>
|
97 |
+
<td>${crackTime}</td>
|
98 |
+
<td>${crackDifficulty}</td>
|
99 |
+
</tr>
|
100 |
+
</script>
|
101 |
+
|
102 |
+
<script type="text/x-jquery-template" id="wfAuditJobsTable">
|
103 |
+
<table class="wf-table">
|
104 |
+
<thead>
|
105 |
+
<th>Audit Type</th>
|
106 |
+
<th>Admin Accounts</th>
|
107 |
+
<th>User Accounts</th>
|
108 |
+
<th>Run Time</th>
|
109 |
+
<th>Email results to</th>
|
110 |
+
<th>Weak Passwords Found</th>
|
111 |
+
<th colspan="2">Status</th>
|
112 |
+
</thead>
|
113 |
+
<tbody class="wf-pw-audit-tbody"></tbody>
|
114 |
+
</table>
|
115 |
+
</script>
|
116 |
+
<script type="text/x-jquery-template" id="wfAuditJobsInProg">
|
117 |
+
<tr>
|
118 |
+
<td>
|
119 |
+
{{if auditType == 'admin'}}
|
120 |
+
Admin Accounts
|
121 |
+
{{else auditType == 'user'}}
|
122 |
+
User Accounts
|
123 |
+
{{else auditType == 'both'}}
|
124 |
+
All WordPress Accounts
|
125 |
+
{{/if}}
|
126 |
+
</td>
|
127 |
+
<td>${totalAdmins}</td>
|
128 |
+
<td>${totalUsers}</td>
|
129 |
+
<td>${WFAD.makeTimeAgo(timeTaken)}</td>
|
130 |
+
<td>${email}</td>
|
131 |
+
<td>${weakFound}</td>
|
132 |
+
{{if jobStatus == 'done'}}
|
133 |
+
<td colspan="2">
|
134 |
+
<span style="color: #FFC200;">Complete</span>
|
135 |
+
</td>
|
136 |
+
{{else jobStatus == 'killed'}}
|
137 |
+
<td colspan="2">
|
138 |
+
<span style="color: #A00;">Stopped</span>
|
139 |
+
</td>
|
140 |
+
{{else jobStatus == 'queued'}}
|
141 |
+
<td>
|
142 |
+
<span style="color: #F00;">Queued</span>
|
143 |
+
</td>
|
144 |
+
<td>
|
145 |
+
<a href="#" onclick="WFAD.killPasswdAudit('${id}'); return false;">Cancel Audit</a>
|
146 |
+
</td>
|
147 |
+
{{else jobStatus == 'running'}}
|
148 |
+
<td>
|
149 |
+
<span style="color: #0A0;">Running</span>
|
150 |
+
</td>
|
151 |
+
<td>
|
152 |
+
<a href="#" onclick="WFAD.killPasswdAudit('${id}'); return false;">Stop Audit</a>
|
153 |
+
</td>
|
154 |
+
{{/if}}
|
155 |
+
</tr>
|
156 |
+
</script>
|
157 |
+
<script type="text/x-jquery-template" id="wfWelcomePasswd">
|
158 |
+
<div>
|
159 |
+
<h3>Premium Feature: Audit your Password Strength</h3>
|
160 |
+
<strong><p>Want to know how easily a hacker can crack your passwords?</p></strong>
|
161 |
+
|
162 |
+
<p>
|
163 |
+
Wordfence Premium includes password auditing. Using this feature
|
164 |
+
we securely test your passwords against a cracking program that hackers use.
|
165 |
+
The difference is that we use extremely fast servers in our data center which
|
166 |
+
allow us to quickly simulate a complex password cracking attack. We then tell
|
167 |
+
you which passwords on your system are weak and help you easily fix the problem.
|
168 |
+
</p>
|
169 |
+
|
170 |
+
<p>
|
171 |
+
<?php
|
172 |
+
if (wfConfig::get('isPaid')){
|
173 |
+
?>
|
174 |
+
You have upgraded to the premium version of Wordfence and have full access
|
175 |
+
to this feature along with our other premium features and priority support.
|
176 |
+
<?php
|
177 |
+
} else {
|
178 |
+
?>
|
179 |
+
If you would like access to this premium feature, please
|
180 |
+
<a href="https://www.wordfence.com/wordfence-signup/" target="_blank">upgrade to our premium version</a>.
|
181 |
+
</p>
|
182 |
+
<?php
|
183 |
+
}
|
184 |
+
?>
|
185 |
+
</div>
|
186 |
+
</script>
|
lib/wfAPI.php
CHANGED
@@ -1,181 +1,98 @@
|
|
1 |
<?php
|
2 |
require_once('wordfenceConstants.php');
|
3 |
require_once('wordfenceClass.php');
|
|
|
4 |
class wfAPI {
|
5 |
public $lastHTTPStatus = '';
|
6 |
public $lastCurlErrorNo = '';
|
7 |
private $curlContent = 0;
|
8 |
private $APIKey = '';
|
9 |
private $wordpressVersion = '';
|
10 |
-
|
|
|
11 |
$this->APIKey = $apiKey;
|
12 |
$this->wordpressVersion = $wordpressVersion;
|
13 |
}
|
14 |
-
|
|
|
15 |
return $this->getURL($this->getAPIURL() . $url);
|
16 |
}
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
)), $postParams);
|
23 |
-
if(
|
24 |
throw new Exception("We received an empty data response from the Wordfence scanning servers when calling the '$action' function.");
|
25 |
}
|
26 |
|
27 |
$dat = json_decode($json, true);
|
28 |
-
if(isset($dat['_isPaidKey'])){
|
29 |
wfConfig::set('keyExpDays', $dat['_keyExpDays']);
|
30 |
-
if($dat['_keyExpDays'] > -1){
|
31 |
wfConfig::set('isPaid', 1);
|
32 |
-
} else if($dat['_keyExpDays'] < 0){
|
33 |
wfConfig::set('isPaid', '');
|
34 |
}
|
35 |
}
|
36 |
-
|
37 |
-
if(!
|
38 |
throw new Exception("We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '$action' function.");
|
39 |
}
|
40 |
-
if(is_array($dat) && isset($dat['errorMsg'])){
|
41 |
throw new Exception($dat['errorMsg']);
|
42 |
}
|
43 |
return $dat;
|
44 |
}
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
$this->curlDataWritten = 0;
|
52 |
-
$this->curlContent = "";
|
53 |
-
$curl = curl_init($url);
|
54 |
-
if(defined('WP_PROXY_HOST') && defined('WP_PROXY_PORT') && wfUtils::hostNotExcludedFromProxy($url) ){
|
55 |
-
curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, 0);
|
56 |
-
curl_setopt($curl, CURLOPT_PROXY, WP_PROXY_HOST . ':' . WP_PROXY_PORT);
|
57 |
-
if(defined('WP_PROXY_USERNAME') && defined('WP_PROXY_PASSWORD')){
|
58 |
-
curl_setopt($curl, CURLOPT_PROXYUSERPWD, WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD);
|
59 |
-
}
|
60 |
-
}
|
61 |
-
curl_setopt ($curl, CURLOPT_TIMEOUT, 900);
|
62 |
-
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]') );
|
63 |
-
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
64 |
-
curl_setopt ($curl, CURLOPT_HEADER, 0);
|
65 |
-
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
|
66 |
-
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
|
67 |
-
curl_setopt ($curl, CURLOPT_WRITEFUNCTION, array($this, 'curlWrite'));
|
68 |
-
curl_setopt($curl, CURLOPT_POST, true);
|
69 |
-
curl_setopt($curl, CURLOPT_POSTFIELDS, $postParams);
|
70 |
-
wordfence::status(4, 'info', "CURL fetching URL: " . $url);
|
71 |
-
curl_exec($curl);
|
72 |
-
|
73 |
-
$httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
74 |
-
$this->lastCurlErrorNo = curl_errno($curl);
|
75 |
-
if($httpStatus == 200){
|
76 |
-
curl_close($curl);
|
77 |
-
return $this->curlContent;
|
78 |
-
} else {
|
79 |
-
$cerror = curl_error($curl);
|
80 |
-
curl_close($curl);
|
81 |
-
throw new Exception("We received an error response when trying to contact the Wordfence scanning servers. The HTTP status code was [$httpStatus] and the curl error number was [" . $this->lastCurlErrorNo . "] " . ($cerror ? (' and the error from CURL was: ' . $cerror) : ''));
|
82 |
-
}
|
83 |
-
} else {
|
84 |
-
wordfence::status(4, 'info', "Fetching URL with file_get: " . $url);
|
85 |
-
$data = $this->fileGet($url, $postParams);
|
86 |
-
if($data === false){
|
87 |
-
$err = error_get_last();
|
88 |
-
if($err){
|
89 |
-
throw new Exception("We received an error response when trying to contact the Wordfence scanning servers using PHP's file_get_contents function. The error was: " . var_export($err, true));
|
90 |
-
} else {
|
91 |
-
throw new Exception("We received an empty response when trying to contact the Wordfence scanning servers using PHP's file_get_contents function.");
|
92 |
-
}
|
93 |
-
}
|
94 |
-
return $data;
|
95 |
}
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
$
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
$body = $postParams;
|
107 |
}
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
'content' => $body,
|
112 |
-
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
|
113 |
-
'timeout' => 60
|
114 |
-
)
|
115 |
-
);
|
116 |
-
$context = stream_context_create($opts);
|
117 |
-
return @file_get_contents($url, false, $context, -1);
|
118 |
}
|
119 |
-
|
|
|
120 |
$url = $this->getAPIURL() . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&action=' . $func;
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
curl_setopt($curl, CURLOPT_HTTPPROXYTUNNEL, 0);
|
126 |
-
curl_setopt($curl, CURLOPT_PROXY, WP_PROXY_HOST . ':' . WP_PROXY_PORT);
|
127 |
-
if(defined('WP_PROXY_USERNAME') && defined('WP_PROXY_PASSWORD')){
|
128 |
-
curl_setopt($curl, CURLOPT_PROXYUSERPWD, WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD);
|
129 |
-
}
|
130 |
-
}
|
131 |
-
curl_setopt ($curl, CURLOPT_TIMEOUT, 900);
|
132 |
-
//curl_setopt($curl, CURLOPT_VERBOSE, true);
|
133 |
-
curl_setopt ($curl, CURLOPT_USERAGENT, "Wordfence");
|
134 |
-
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
135 |
-
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, false);
|
136 |
-
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, false);
|
137 |
-
curl_setopt($curl, CURLOPT_POST, true);
|
138 |
-
if($postData){
|
139 |
-
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
|
140 |
-
} else {
|
141 |
-
curl_setopt($curl, CURLOPT_POSTFIELDS, array());
|
142 |
-
}
|
143 |
-
$data = curl_exec($curl);
|
144 |
-
|
145 |
-
$httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
146 |
-
if($httpStatus != 200){
|
147 |
-
$cError = curl_error($curl);
|
148 |
-
curl_close($curl);
|
149 |
-
if($cError){
|
150 |
-
throw new Exception("We received an error response when trying to fetch binary data from the Wordfence scanning server. The HTTP status was [$httpStatus] with error: $cError");
|
151 |
-
} else {
|
152 |
-
throw new Exception("We received an error HTTP response when trying to fetch binary data from the Wordfence scanning server: [$httpStatus]");
|
153 |
-
}
|
154 |
-
}
|
155 |
-
} else {
|
156 |
-
$data = $this->fileGet($url, $postData);
|
157 |
-
if($data === false){
|
158 |
-
$err = error_get_last();
|
159 |
-
if($err){
|
160 |
-
throw new Exception("We received an error response when trying to fetch binary data from the Wordfence scanning server using file_get_contents: $err");
|
161 |
-
} else {
|
162 |
-
throw new Exception("We received an error when trying to fetch binary data from the Wordfence scanning server using file_get_contents. There was no message explaining the error.");
|
163 |
-
}
|
164 |
-
}
|
165 |
-
$httpStatus = '200';
|
166 |
-
}
|
167 |
-
if(preg_match('/\{.*errorMsg/', $data)){
|
168 |
$jdat = @json_decode($data, true);
|
169 |
-
if(is_array($jdat) && $jdat['errorMsg']){
|
170 |
throw new Exception($jdat['errorMsg']);
|
171 |
}
|
172 |
}
|
173 |
-
return array('code' => $
|
174 |
}
|
175 |
-
|
|
|
176 |
$siteurl = '';
|
177 |
-
if(function_exists('get_bloginfo')){
|
178 |
-
if(is_multisite()){
|
179 |
$siteurl = network_home_url();
|
180 |
$siteurl = rtrim($siteurl, '/'); //Because previously we used get_bloginfo and it returns http://example.com without a '/' char.
|
181 |
} else {
|
@@ -183,25 +100,29 @@ class wfAPI {
|
|
183 |
}
|
184 |
}
|
185 |
return self::buildQuery(array(
|
186 |
-
'v' => $this->wordpressVersion,
|
187 |
-
's' => $siteurl,
|
188 |
'k' => $this->APIKey
|
189 |
-
|
190 |
}
|
191 |
-
|
192 |
-
|
|
|
193 |
return http_build_query($data, '', '&'); //arg_separator parameter was only added in PHP 5.1.2. We do this because some PHP.ini's have arg_separator.output set to '&'
|
194 |
} else {
|
195 |
return http_build_query($data);
|
196 |
}
|
197 |
}
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
|
|
|
|
|
|
203 |
}
|
204 |
-
return
|
205 |
}
|
206 |
}
|
207 |
|
1 |
<?php
|
2 |
require_once('wordfenceConstants.php');
|
3 |
require_once('wordfenceClass.php');
|
4 |
+
|
5 |
class wfAPI {
|
6 |
public $lastHTTPStatus = '';
|
7 |
public $lastCurlErrorNo = '';
|
8 |
private $curlContent = 0;
|
9 |
private $APIKey = '';
|
10 |
private $wordpressVersion = '';
|
11 |
+
|
12 |
+
public function __construct($apiKey, $wordpressVersion) {
|
13 |
$this->APIKey = $apiKey;
|
14 |
$this->wordpressVersion = $wordpressVersion;
|
15 |
}
|
16 |
+
|
17 |
+
public function getStaticURL($url) { // In the form '/something.bin' without quotes
|
18 |
return $this->getURL($this->getAPIURL() . $url);
|
19 |
}
|
20 |
+
|
21 |
+
public function call($action, $getParams = array(), $postParams = array(), $forceSSL = false) {
|
22 |
+
$apiURL = $this->getAPIURL();
|
23 |
+
//Sanity check. Developer should call wfAPI::SSLEnabled() to check if SSL is enabled before forcing SSL and return a user friendly msg if it's not.
|
24 |
+
if ($forceSSL && (!preg_match('/^https:/i', $apiURL))) {
|
25 |
+
//User's should never see this message unless we aren't calling SSLEnabled() to check if SSL is enabled before using call() with forceSSL
|
26 |
+
throw new Exception("SSL is not supported by your web server and is required to use this function. Please ask your hosting provider or site admin to install cURL with openSSL to use this feature.");
|
27 |
+
}
|
28 |
+
$json = $this->getURL($apiURL . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&' . self::buildQuery(
|
29 |
+
array_merge(
|
30 |
+
array('action' => $action),
|
31 |
+
$getParams
|
32 |
)), $postParams);
|
33 |
+
if (!$json) {
|
34 |
throw new Exception("We received an empty data response from the Wordfence scanning servers when calling the '$action' function.");
|
35 |
}
|
36 |
|
37 |
$dat = json_decode($json, true);
|
38 |
+
if (isset($dat['_isPaidKey'])) {
|
39 |
wfConfig::set('keyExpDays', $dat['_keyExpDays']);
|
40 |
+
if ($dat['_keyExpDays'] > -1) {
|
41 |
wfConfig::set('isPaid', 1);
|
42 |
+
} else if ($dat['_keyExpDays'] < 0) {
|
43 |
wfConfig::set('isPaid', '');
|
44 |
}
|
45 |
}
|
46 |
+
|
47 |
+
if (!is_array($dat)) {
|
48 |
throw new Exception("We received a data structure that is not the expected array when contacting the Wordfence scanning servers and calling the '$action' function.");
|
49 |
}
|
50 |
+
if (is_array($dat) && isset($dat['errorMsg'])) {
|
51 |
throw new Exception($dat['errorMsg']);
|
52 |
}
|
53 |
return $dat;
|
54 |
}
|
55 |
+
|
56 |
+
protected function getURL($url, $postParams = array()) {
|
57 |
+
wordfence::status(4, 'info', "Calling Wordfence API v" . WORDFENCE_API_VERSION . ":" . $url);
|
58 |
+
|
59 |
+
if (!function_exists('wp_remote_post')) {
|
60 |
+
require_once ABSPATH . WPINC . 'http.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
+
$response = wp_remote_post($url, array(
|
64 |
+
'timeout' => 900,
|
65 |
+
'user-agent' => "Wordfence.com UA " . (defined('WORDFENCE_VERSION') ? WORDFENCE_VERSION : '[Unknown version]'),
|
66 |
+
'body' => $postParams,
|
67 |
+
));
|
68 |
+
|
69 |
+
$this->lastHTTPStatus = (int) wp_remote_retrieve_response_code($response);
|
70 |
+
if (is_wp_error($response) || 200 != $this->lastHTTPStatus) {
|
71 |
+
throw new Exception("We received an error response when trying to contact the Wordfence scanning servers. The HTTP status code was [$this->lastHTTPStatus]");
|
|
|
72 |
}
|
73 |
+
|
74 |
+
$this->curlContent = wp_remote_retrieve_body($response);
|
75 |
+
return $this->curlContent;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
+
|
78 |
+
public function binCall($func, $postData) {
|
79 |
$url = $this->getAPIURL() . '/v' . WORDFENCE_API_VERSION . '/?' . $this->makeAPIQueryString() . '&action=' . $func;
|
80 |
+
|
81 |
+
$data = $this->getURL($url, $postData);
|
82 |
+
|
83 |
+
if (preg_match('/\{.*errorMsg/', $data)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
$jdat = @json_decode($data, true);
|
85 |
+
if (is_array($jdat) && $jdat['errorMsg']) {
|
86 |
throw new Exception($jdat['errorMsg']);
|
87 |
}
|
88 |
}
|
89 |
+
return array('code' => $this->lastHTTPStatus, 'data' => $data);
|
90 |
}
|
91 |
+
|
92 |
+
public function makeAPIQueryString() {
|
93 |
$siteurl = '';
|
94 |
+
if (function_exists('get_bloginfo')) {
|
95 |
+
if (is_multisite()) {
|
96 |
$siteurl = network_home_url();
|
97 |
$siteurl = rtrim($siteurl, '/'); //Because previously we used get_bloginfo and it returns http://example.com without a '/' char.
|
98 |
} else {
|
100 |
}
|
101 |
}
|
102 |
return self::buildQuery(array(
|
103 |
+
'v' => $this->wordpressVersion,
|
104 |
+
's' => $siteurl,
|
105 |
'k' => $this->APIKey
|
106 |
+
));
|
107 |
}
|
108 |
+
|
109 |
+
private function buildQuery($data) {
|
110 |
+
if (version_compare(phpversion(), '5.1.2', '>=')) {
|
111 |
return http_build_query($data, '', '&'); //arg_separator parameter was only added in PHP 5.1.2. We do this because some PHP.ini's have arg_separator.output set to '&'
|
112 |
} else {
|
113 |
return http_build_query($data);
|
114 |
}
|
115 |
}
|
116 |
+
|
117 |
+
private function getAPIURL() {
|
118 |
+
return self::SSLEnabled() ? WORDFENCE_API_URL_SEC : WORDFENCE_API_URL_NONSEC;
|
119 |
+
}
|
120 |
+
|
121 |
+
public static function SSLEnabled() {
|
122 |
+
if (!function_exists('wp_http_supports')) {
|
123 |
+
require_once ABSPATH . WPINC . 'http.php';
|
124 |
}
|
125 |
+
return wp_http_supports(array('ssl'));
|
126 |
}
|
127 |
}
|
128 |
|
lib/wfActivityReport.php
ADDED
@@ -0,0 +1,462 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wfActivityReport {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var int
|
7 |
+
*/
|
8 |
+
private $limit = 10;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var wpdb
|
12 |
+
*/
|
13 |
+
private $db;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param int $limit
|
17 |
+
*/
|
18 |
+
public function __construct($limit = 10) {
|
19 |
+
global $wpdb;
|
20 |
+
$this->db = $wpdb;
|
21 |
+
$this->limit = $limit;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Schedule the activity report cron job.
|
26 |
+
*/
|
27 |
+
public static function scheduleCronJob() {
|
28 |
+
self::clearCronJobs();
|
29 |
+
|
30 |
+
if (!wfConfig::get('email_summary_enabled', 1)) {
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
|
34 |
+
list(, $end_time) = wfActivityReport::getReportDateRange();
|
35 |
+
wp_schedule_single_event($end_time, 'wordfence_email_activity_report');
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Remove the activity report cron job.
|
40 |
+
*/
|
41 |
+
public static function disableCronJob() {
|
42 |
+
self::clearCronJobs();
|
43 |
+
}
|
44 |
+
|
45 |
+
public static function clearCronJobs() {
|
46 |
+
wp_clear_scheduled_hook('wordfence_email_activity_report');
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Send out the report and reschedule the next report's cron job.
|
51 |
+
*/
|
52 |
+
public static function executeCronJob() {
|
53 |
+
$report = new self();
|
54 |
+
$report->sendReportViaEmail(wfConfig::getAlertEmails());
|
55 |
+
self::scheduleCronJob();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Output a compact version of the email for the WP dashboard.
|
60 |
+
*/
|
61 |
+
public static function outputDashboardWidget() {
|
62 |
+
$report = new self(5);
|
63 |
+
echo $report->toWidgetView();
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @return array
|
68 |
+
*/
|
69 |
+
public static function getReportDateRange() {
|
70 |
+
$interval = wfConfig::get('email_summary_interval', 'weekly');
|
71 |
+
$offset = get_option('gmt_offset');
|
72 |
+
return self::_getReportDateRange($interval, $offset);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Testable code.
|
77 |
+
*
|
78 |
+
* @param string $interval
|
79 |
+
* @param int $offset
|
80 |
+
* @param null $time
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
public static function _getReportDateRange($interval = 'weekly', $offset = 0, $time = null) {
|
84 |
+
if ($time === null) {
|
85 |
+
$time = time();
|
86 |
+
}
|
87 |
+
|
88 |
+
$day = (int) gmdate('w', $time);
|
89 |
+
$month = (int) gmdate("n", $time);
|
90 |
+
$day_of_month = (int) gmdate("j", $time);
|
91 |
+
$year = (int) gmdate("Y", $time);
|
92 |
+
|
93 |
+
$start_time = 0;
|
94 |
+
$end_time = 0;
|
95 |
+
|
96 |
+
switch ($interval) {
|
97 |
+
// Send a report 4pm every Monday
|
98 |
+
case 'weekly':
|
99 |
+
$start_time = gmmktime(16, 0, 0, $month, $day_of_month - $day + 1, $year) + (-$offset * 60 * 60);
|
100 |
+
$end_time = $start_time + (86400 * 7);
|
101 |
+
break;
|
102 |
+
|
103 |
+
// Send a report 4pm every other Monday
|
104 |
+
case 'biweekly':
|
105 |
+
$start_time = gmmktime(16, 0, 0, $month, $day_of_month - $day + 1, $year) + (-$offset * 60 * 60);
|
106 |
+
$end_time = $start_time + (86400 * 14);
|
107 |
+
break;
|
108 |
+
|
109 |
+
// Send a report at 4pm the first of every month
|
110 |
+
case 'monthly':
|
111 |
+
$start_time = gmmktime(16, 0, 0, $month, 1, $year) + (-$offset * 60 * 60);
|
112 |
+
$end_time = gmmktime(16, 0, 0, $month + 1, 1, $year) + (-$offset * 60 * 60);
|
113 |
+
break;
|
114 |
+
}
|
115 |
+
|
116 |
+
return array($start_time, $end_time);
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @return array
|
121 |
+
*/
|
122 |
+
public function getFullReport() {
|
123 |
+
$start_time = microtime(true);
|
124 |
+
return array(
|
125 |
+
'top_ips_blocked' => $this->getTopIPsBlocked($this->limit),
|
126 |
+
'top_countries_blocked' => $this->getTopCountriesBlocked($this->limit),
|
127 |
+
'top_failed_logins' => $this->getTopFailedLogins($this->limit),
|
128 |
+
'recently_modified_files' => $this->getRecentFilesModified($this->limit),
|
129 |
+
'updates_needed' => $this->getUpdatesNeeded(),
|
130 |
+
'microseconds' => microtime(true) - $start_time,
|
131 |
+
);
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* @return array
|
136 |
+
*/
|
137 |
+
public function getWidgetReport() {
|
138 |
+
$start_time = microtime(true);
|
139 |
+
return array(
|
140 |
+
'top_ips_blocked' => $this->getTopIPsBlocked($this->limit),
|
141 |
+
'top_countries_blocked' => $this->getTopCountriesBlocked($this->limit),
|
142 |
+
'top_failed_logins' => $this->getTopFailedLogins($this->limit),
|
143 |
+
'updates_needed' => $this->getUpdatesNeeded(),
|
144 |
+
'microseconds' => microtime(true) - $start_time,
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @param int $limit
|
150 |
+
* @return mixed
|
151 |
+
*/
|
152 |
+
public function getTopIPsBlocked($limit = 10) {
|
153 |
+
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
154 |
+
SELECT * FROM {$this->db->prefix}wfBlockedIPLog
|
155 |
+
ORDER BY blockCount DESC
|
156 |
+
LIMIT %d
|
157 |
+
SQL
|
158 |
+
, $limit));
|
159 |
+
return $results;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* @param int $limit
|
164 |
+
* @return array
|
165 |
+
*/
|
166 |
+
public function getTopCountriesBlocked($limit = 10) {
|
167 |
+
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
168 |
+
SELECT *, COUNT(IP) as totalIPs, SUM(blockCount) as totalBlockCount
|
169 |
+
FROM {$this->db->base_prefix}wfBlockedIPLog
|
170 |
+
GROUP BY countryCode
|
171 |
+
ORDER BY totalBlockCount DESC
|
172 |
+
LIMIT %d
|
173 |
+
SQL
|
174 |
+
, $limit));
|
175 |
+
return $results;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @param int $limit
|
180 |
+
* @return mixed
|
181 |
+
*/
|
182 |
+
public function getTopFailedLogins($limit = 10) {
|
183 |
+
$results = $this->db->get_results($this->db->prepare(<<<SQL
|
184 |
+
SELECT *, sum(fail) as fail_count
|
185 |
+
FROM {$this->db->base_prefix}wfLogins
|
186 |
+
WHERE fail = 1
|
187 |
+
GROUP BY username
|
188 |
+
ORDER BY fail_count DESC
|
189 |
+
LIMIT %d
|
190 |
+
SQL
|
191 |
+
, $limit));
|
192 |
+
return $results;
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Returns any updates needs or false if everything is up to date.
|
197 |
+
*
|
198 |
+
* @return array|bool
|
199 |
+
*/
|
200 |
+
public function getUpdatesNeeded() {
|
201 |
+
$update_check = new wfUpdateCheck();
|
202 |
+
$needs_update = $update_check->checkAllUpdates()
|
203 |
+
->needsAnyUpdates();
|
204 |
+
if ($needs_update) {
|
205 |
+
return array(
|
206 |
+
'core' => $update_check->getCoreUpdateVersion(),
|
207 |
+
'plugins' => $update_check->getPluginUpdates(),
|
208 |
+
'themes' => $update_check->getThemeUpdates(),
|
209 |
+
);
|
210 |
+
}
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Returns list of files modified within given timeframe.
|
216 |
+
*
|
217 |
+
* @todo Add option to configure the regex used to filter files allowed in this list.
|
218 |
+
* @todo Add option to exclude directories (such as cache directories).
|
219 |
+
*
|
220 |
+
* @param string $directory Search for files within this directory
|
221 |
+
* @param int $time_range One week
|
222 |
+
* @param int $limit Max files to return in results
|
223 |
+
* @param int $directory_limit Hard limit for number of files to search within a directory.
|
224 |
+
* @return array
|
225 |
+
*/
|
226 |
+
public function getRecentFilesModified($limit = 300, $directory = ABSPATH, $time_range = 604800, $directory_limit = 20000) {
|
227 |
+
$recently_modified = new wfRecentlyModifiedFiles($directory);
|
228 |
+
$recently_modified->run();
|
229 |
+
return $recently_modified->mostRecentFiles($limit);
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Remove entries older than a week in the IP log.
|
234 |
+
*/
|
235 |
+
public function rotateIPLog() {
|
236 |
+
// default to weekly
|
237 |
+
$interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 7 day)) / 86400)';
|
238 |
+
switch (wfConfig::get('email_summary_interval', 'weekly')) {
|
239 |
+
case 'biweekly':
|
240 |
+
$interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 14 day)) / 86400)';
|
241 |
+
break;
|
242 |
+
case 'monthly':
|
243 |
+
$interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval 1 month)) / 86400)';
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
$this->db->query(<<<SQL
|
247 |
+
DELETE FROM {$this->db->base_prefix}wfBlockedIPLog
|
248 |
+
WHERE unixday < $interval
|
249 |
+
SQL
|
250 |
+
);
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @param mixed $ip_address
|
255 |
+
* @param null $unixday
|
256 |
+
*/
|
257 |
+
public static function logBlockedIP($ip_address, $unixday = null) {
|
258 |
+
global $wpdb;
|
259 |
+
|
260 |
+
if (is_string($ip_address) && !is_numeric($ip_address)) {
|
261 |
+
$ip_address = wfUtils::inet_aton($ip_address);
|
262 |
+
}
|
263 |
+
|
264 |
+
$blocked_table = "{$wpdb->base_prefix}wfBlockedIPLog";
|
265 |
+
|
266 |
+
$unixday_insert = 'FLOOR(UNIX_TIMESTAMP() / 86400)';
|
267 |
+
if (is_int($unixday)) {
|
268 |
+
$unixday_insert = absint($unixday);
|
269 |
+
}
|
270 |
+
|
271 |
+
$country = wfUtils::IP2Country(is_numeric($ip_address) ? wfUtils::inet_ntoa($ip_address) : $ip_address);
|
272 |
+
|
273 |
+
$wpdb->query($wpdb->prepare(<<<SQL
|
274 |
+
INSERT INTO $blocked_table (IP, countryCode, blockCount, unixday)
|
275 |
+
VALUES (%s, %s, 1, $unixday_insert)
|
276 |
+
ON DUPLICATE KEY UPDATE blockCount = blockCount + 1
|
277 |
+
SQL
|
278 |
+
, $ip_address, $country));
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* @return wfActivityReportView
|
283 |
+
*/
|
284 |
+
public function toView() {
|
285 |
+
return new wfActivityReportView('reports/activity-report', $this->getFullReport() + array(
|
286 |
+
'limit' => $this->getLimit(),
|
287 |
+
));
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* @return wfActivityReportView
|
292 |
+
*/
|
293 |
+
public function toWidgetView() {
|
294 |
+
return new wfActivityReportView('reports/activity-report', $this->getWidgetReport() + array(
|
295 |
+
'limit' => $this->getLimit(),
|
296 |
+
));
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* @return wfActivityReportView
|
301 |
+
*/
|
302 |
+
public function toEmailView() {
|
303 |
+
return new wfActivityReportView('reports/activity-report-email-inline', $this->getFullReport());
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* @param $email_addresses string|array
|
308 |
+
* @return bool
|
309 |
+
*/
|
310 |
+
public function sendReportViaEmail($email_addresses) {
|
311 |
+
// TODO: setup a title that contains activity range
|
312 |
+
return wp_mail($email_addresses, 'Wordfence activity for ' . date_i18n(get_option('date_format')), $this->toEmailView()->__toString(), 'Content-Type: text/html');
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* @return string
|
317 |
+
* @throws wfViewNotFoundException
|
318 |
+
*/
|
319 |
+
public function render() {
|
320 |
+
return $this->toView()
|
321 |
+
->render();
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* @return string
|
326 |
+
*/
|
327 |
+
public function __toString() {
|
328 |
+
return $this->toView()
|
329 |
+
->__toString();
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* @return int
|
334 |
+
*/
|
335 |
+
public function getLimit() {
|
336 |
+
return $this->limit;
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* @param int $limit
|
341 |
+
*/
|
342 |
+
public function setLimit($limit) {
|
343 |
+
$this->limit = $limit;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
|
347 |
+
|
348 |
+
class wfRecentlyModifiedFiles extends wfDirectoryIterator {
|
349 |
+
|
350 |
+
/**
|
351 |
+
* @var int
|
352 |
+
*/
|
353 |
+
private $time_range = 604800;
|
354 |
+
|
355 |
+
/**
|
356 |
+
* @var array
|
357 |
+
*/
|
358 |
+
private $files = array();
|
359 |
+
private $excluded_directories;
|
360 |
+
|
361 |
+
/**
|
362 |
+
* @param string $directory
|
363 |
+
* @param int $max_files_per_directory
|
364 |
+
* @param int $max_iterations
|
365 |
+
* @param int $time_range
|
366 |
+
*/
|
367 |
+
public function __construct($directory = ABSPATH, $max_files_per_directory = 20000, $max_iterations = 250000, $time_range = 604800) {
|
368 |
+
parent::__construct($directory, $max_files_per_directory, $max_iterations);
|
369 |
+
$this->time_range = $time_range;
|
370 |
+
$excluded_directories = explode(',', (string) wfConfig::get('email_summary_excluded_directories'));
|
371 |
+
$this->excluded_directories = array();
|
372 |
+
foreach ($excluded_directories as $index => $path) {
|
373 |
+
if (($dir = realpath(ABSPATH . $path)) !== false) {
|
374 |
+
$this->excluded_directories[$dir] = 1;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* @param $dir
|
381 |
+
* @return bool
|
382 |
+
*/
|
383 |
+
protected function scan($dir) {
|
384 |
+
if (!array_key_exists(realpath($dir), $this->excluded_directories)) {
|
385 |
+
return parent::scan($dir);
|
386 |
+
}
|
387 |
+
return true;
|
388 |
+
}
|
389 |
+
|
390 |
+
|
391 |
+
/**
|
392 |
+
* @param string $file
|
393 |
+
*/
|
394 |
+
public function file($file) {
|
395 |
+
$mtime = filemtime($file);
|
396 |
+
if (time() - $mtime < $this->time_range) {
|
397 |
+
$this->files[] = array($file, $mtime);
|
398 |
+
}
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* @param int $limit
|
403 |
+
* @return array
|
404 |
+
*/
|
405 |
+
public function mostRecentFiles($limit = 300) {
|
406 |
+
usort($this->files, array(
|
407 |
+
$this,
|
408 |
+
'_sortMostRecentFiles',
|
409 |
+
));
|
410 |
+
return array_slice($this->files, 0, $limit);
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* Sort in descending order.
|
415 |
+
*
|
416 |
+
* @param $a
|
417 |
+
* @param $b
|
418 |
+
* @return int
|
419 |
+
*/
|
420 |
+
private function _sortMostRecentFiles($a, $b) {
|
421 |
+
if ($a[1] > $b[1]) {
|
422 |
+
return -1;
|
423 |
+
}
|
424 |
+
if ($a[1] < $b[1]) {
|
425 |
+
return 1;
|
426 |
+
}
|
427 |
+
return 0;
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* @return mixed
|
432 |
+
*/
|
433 |
+
public function getFiles() {
|
434 |
+
return $this->files;
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
+
class wfActivityReportView extends wfView {
|
440 |
+
|
441 |
+
/**
|
442 |
+
* @param $file
|
443 |
+
* @return string
|
444 |
+
*/
|
445 |
+
public function displayFile($file) {
|
446 |
+
if (stripos($file, ABSPATH) === 0) {
|
447 |
+
return substr($file, strlen(ABSPATH));
|
448 |
+
}
|
449 |
+
return $file;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* @param null $unix_time
|
454 |
+
* @return string
|
455 |
+
*/
|
456 |
+
public function modTime($unix_time = null) {
|
457 |
+
if ($unix_time === null) {
|
458 |
+
$unix_time = time();
|
459 |
+
}
|
460 |
+
return date_i18n('F j, Y g:ia', $unix_time);
|
461 |
+
}
|
462 |
+
}
|
lib/wfCache.php
CHANGED
@@ -142,6 +142,7 @@ class wfCache {
|
|
142 |
|
143 |
$file = self::fileFromRequest( ($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']), $_SERVER['REQUEST_URI']);
|
144 |
self::makeDirIfNeeded($file);
|
|
|
145 |
$append = "";
|
146 |
$appendGzip = "";
|
147 |
if(wfConfig::get('addCacheComment', false)){
|
@@ -219,8 +220,29 @@ class wfCache {
|
|
219 |
}
|
220 |
return $msg;
|
221 |
}
|
222 |
-
return
|
223 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
public static function action_publishPost($id){
|
225 |
$perm = get_permalink($id);
|
226 |
self::deleteFileFromPermalink($perm);
|
142 |
|
143 |
$file = self::fileFromRequest( ($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']), $_SERVER['REQUEST_URI']);
|
144 |
self::makeDirIfNeeded($file);
|
145 |
+
self::writeCacheDirectoryHtaccess();
|
146 |
$append = "";
|
147 |
$appendGzip = "";
|
148 |
if(wfConfig::get('addCacheComment', false)){
|
220 |
}
|
221 |
return $msg;
|
222 |
}
|
223 |
+
return self::writeCacheDirectoryHtaccess(); //Everything is OK
|
224 |
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Returns false on success to match wfCache::cacheDirectoryTest
|
228 |
+
*
|
229 |
+
* @see wfCache::cacheDirectoryTest
|
230 |
+
*
|
231 |
+
* @return bool|string
|
232 |
+
*/
|
233 |
+
public static function writeCacheDirectoryHtaccess() {
|
234 |
+
$cacheDir = WP_CONTENT_DIR . '/wfcache/';
|
235 |
+
if (!file_exists($cacheDir . '.htaccess') && !@file_put_contents($cacheDir . '.htaccess', 'Deny from all', LOCK_EX)) {
|
236 |
+
$err = error_get_last();
|
237 |
+
$msg = "We could not write to the file $cacheDir" . ".htaccess.";
|
238 |
+
if($err){
|
239 |
+
$msg .= " The error was: " . $err['message'];
|
240 |
+
}
|
241 |
+
return $msg;
|
242 |
+
}
|
243 |
+
return false;
|
244 |
+
}
|
245 |
+
|
246 |
public static function action_publishPost($id){
|
247 |
$perm = get_permalink($id);
|
248 |
self::deleteFileFromPermalink($perm);
|
lib/wfConfig.php
CHANGED
@@ -64,8 +64,11 @@ class wfConfig {
|
|
64 |
"startScansRemotely" => false,
|
65 |
"disableConfigCaching" => false,
|
66 |
"addCacheComment" => false,
|
|
|
67 |
"allowHTTPSCaching" => false,
|
68 |
-
"debugOn" => false
|
|
|
|
|
69 |
),
|
70 |
"otherParams" => array(
|
71 |
'securityLevel' => '0',
|
@@ -88,7 +91,9 @@ class wfConfig {
|
|
88 |
'max404Humans_action' => "throttle",
|
89 |
'maxScanHits' => "DISABLED",
|
90 |
'maxScanHits_action' => "throttle",
|
91 |
-
'blockedTime' => "300"
|
|
|
|
|
92 |
)
|
93 |
),
|
94 |
array( //level 1
|
@@ -146,8 +151,11 @@ class wfConfig {
|
|
146 |
"startScansRemotely" => false,
|
147 |
"disableConfigCaching" => false,
|
148 |
"addCacheComment" => false,
|
|
|
149 |
"allowHTTPSCaching" => false,
|
150 |
-
"debugOn" => false
|
|
|
|
|
151 |
),
|
152 |
"otherParams" => array(
|
153 |
'securityLevel' => '1',
|
@@ -170,7 +178,9 @@ class wfConfig {
|
|
170 |
'max404Humans_action' => "throttle",
|
171 |
'maxScanHits' => "DISABLED",
|
172 |
'maxScanHits_action' => "throttle",
|
173 |
-
'blockedTime' => "300"
|
|
|
|
|
174 |
)
|
175 |
),
|
176 |
array( //level 2
|
@@ -230,7 +240,9 @@ class wfConfig {
|
|
230 |
"addCacheComment" => false,
|
231 |
"disableCodeExecutionUploads" => false,
|
232 |
"allowHTTPSCaching" => false,
|
233 |
-
"debugOn" => false
|
|
|
|
|
234 |
),
|
235 |
"otherParams" => array(
|
236 |
'securityLevel' => '2',
|
@@ -253,7 +265,9 @@ class wfConfig {
|
|
253 |
'max404Humans_action' => "throttle",
|
254 |
'maxScanHits' => "DISABLED",
|
255 |
'maxScanHits_action' => "throttle",
|
256 |
-
'blockedTime' => "300"
|
|
|
|
|
257 |
)
|
258 |
),
|
259 |
array( //level 3
|
@@ -311,8 +325,11 @@ class wfConfig {
|
|
311 |
"startScansRemotely" => false,
|
312 |
"disableConfigCaching" => false,
|
313 |
"addCacheComment" => false,
|
|
|
314 |
"allowHTTPSCaching" => false,
|
315 |
-
"debugOn" => false
|
|
|
|
|
316 |
),
|
317 |
"otherParams" => array(
|
318 |
'securityLevel' => '3',
|
@@ -335,7 +352,9 @@ class wfConfig {
|
|
335 |
'max404Humans_action' => "throttle",
|
336 |
'maxScanHits' => "30",
|
337 |
'maxScanHits_action' => "throttle",
|
338 |
-
'blockedTime' => "1800"
|
|
|
|
|
339 |
)
|
340 |
),
|
341 |
array( //level 4
|
@@ -393,8 +412,11 @@ class wfConfig {
|
|
393 |
"startScansRemotely" => false,
|
394 |
"disableConfigCaching" => false,
|
395 |
"addCacheComment" => false,
|
|
|
396 |
"allowHTTPSCaching" => false,
|
397 |
-
"debugOn" => false
|
|
|
|
|
398 |
),
|
399 |
"otherParams" => array(
|
400 |
'securityLevel' => '4',
|
@@ -417,7 +439,9 @@ class wfConfig {
|
|
417 |
'max404Humans_action' => "block",
|
418 |
'maxScanHits' => "10",
|
419 |
'maxScanHits_action' => "block",
|
420 |
-
'blockedTime' => "7200"
|
|
|
|
|
421 |
)
|
422 |
)
|
423 |
);
|
@@ -439,6 +463,12 @@ class wfConfig {
|
|
439 |
if(self::get('other_scanOutside', false) === false){
|
440 |
self::set('other_scanOutside', 0);
|
441 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
442 |
}
|
443 |
public static function getExportableOptionsKeys(){
|
444 |
$ret = array();
|
@@ -790,7 +820,9 @@ class wfConfig {
|
|
790 |
function show_message($msg = 'null'){}
|
791 |
}
|
792 |
*/
|
793 |
-
|
|
|
|
|
794 |
require_once(ABSPATH . 'wp-includes/update.php');
|
795 |
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
796 |
wp_update_plugins();
|
64 |
"startScansRemotely" => false,
|
65 |
"disableConfigCaching" => false,
|
66 |
"addCacheComment" => false,
|
67 |
+
"disableCodeExecutionUploads" => false,
|
68 |
"allowHTTPSCaching" => false,
|
69 |
+
"debugOn" => false,
|
70 |
+
'email_summary_enabled' => true,
|
71 |
+
'email_summary_dashboard_widget_enabled' => true,
|
72 |
),
|
73 |
"otherParams" => array(
|
74 |
'securityLevel' => '0',
|
91 |
'max404Humans_action' => "throttle",
|
92 |
'maxScanHits' => "DISABLED",
|
93 |
'maxScanHits_action' => "throttle",
|
94 |
+
'blockedTime' => "300",
|
95 |
+
'email_summary_interval' => 'biweekly',
|
96 |
+
'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
|
97 |
)
|
98 |
),
|
99 |
array( //level 1
|
151 |
"startScansRemotely" => false,
|
152 |
"disableConfigCaching" => false,
|
153 |
"addCacheComment" => false,
|
154 |
+
"disableCodeExecutionUploads" => false,
|
155 |
"allowHTTPSCaching" => false,
|
156 |
+
"debugOn" => false,
|
157 |
+
'email_summary_enabled' => true,
|
158 |
+
'email_summary_dashboard_widget_enabled' => true,
|
159 |
),
|
160 |
"otherParams" => array(
|
161 |
'securityLevel' => '1',
|
178 |
'max404Humans_action' => "throttle",
|
179 |
'maxScanHits' => "DISABLED",
|
180 |
'maxScanHits_action' => "throttle",
|
181 |
+
'blockedTime' => "300",
|
182 |
+
'email_summary_interval' => 'biweekly',
|
183 |
+
'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
|
184 |
)
|
185 |
),
|
186 |
array( //level 2
|
240 |
"addCacheComment" => false,
|
241 |
"disableCodeExecutionUploads" => false,
|
242 |
"allowHTTPSCaching" => false,
|
243 |
+
"debugOn" => false,
|
244 |
+
'email_summary_enabled' => true,
|
245 |
+
'email_summary_dashboard_widget_enabled' => true,
|
246 |
),
|
247 |
"otherParams" => array(
|
248 |
'securityLevel' => '2',
|
265 |
'max404Humans_action' => "throttle",
|
266 |
'maxScanHits' => "DISABLED",
|
267 |
'maxScanHits_action' => "throttle",
|
268 |
+
'blockedTime' => "300",
|
269 |
+
'email_summary_interval' => 'biweekly',
|
270 |
+
'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
|
271 |
)
|
272 |
),
|
273 |
array( //level 3
|
325 |
"startScansRemotely" => false,
|
326 |
"disableConfigCaching" => false,
|
327 |
"addCacheComment" => false,
|
328 |
+
"disableCodeExecutionUploads" => false,
|
329 |
"allowHTTPSCaching" => false,
|
330 |
+
"debugOn" => false,
|
331 |
+
'email_summary_enabled' => true,
|
332 |
+
'email_summary_dashboard_widget_enabled' => true,
|
333 |
),
|
334 |
"otherParams" => array(
|
335 |
'securityLevel' => '3',
|
352 |
'max404Humans_action' => "throttle",
|
353 |
'maxScanHits' => "30",
|
354 |
'maxScanHits_action' => "throttle",
|
355 |
+
'blockedTime' => "1800",
|
356 |
+
'email_summary_interval' => 'biweekly',
|
357 |
+
'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
|
358 |
)
|
359 |
),
|
360 |
array( //level 4
|
412 |
"startScansRemotely" => false,
|
413 |
"disableConfigCaching" => false,
|
414 |
"addCacheComment" => false,
|
415 |
+
"disableCodeExecutionUploads" => false,
|
416 |
"allowHTTPSCaching" => false,
|
417 |
+
"debugOn" => false,
|
418 |
+
'email_summary_enabled' => true,
|
419 |
+
'email_summary_dashboard_widget_enabled' => true,
|
420 |
),
|
421 |
"otherParams" => array(
|
422 |
'securityLevel' => '4',
|
439 |
'max404Humans_action' => "block",
|
440 |
'maxScanHits' => "10",
|
441 |
'maxScanHits_action' => "block",
|
442 |
+
'blockedTime' => "7200",
|
443 |
+
'email_summary_interval' => 'biweekly',
|
444 |
+
'email_summary_excluded_directories' => 'wp-content/cache,wp-content/wfcache,wp-content/plugins/wordfence/tmp',
|
445 |
)
|
446 |
)
|
447 |
);
|
463 |
if(self::get('other_scanOutside', false) === false){
|
464 |
self::set('other_scanOutside', 0);
|
465 |
}
|
466 |
+
|
467 |
+
if (self::get('email_summary_enabled')) {
|
468 |
+
wfActivityReport::scheduleCronJob();
|
469 |
+
} else {
|
470 |
+
wfActivityReport::disableCronJob();
|
471 |
+
}
|
472 |
}
|
473 |
public static function getExportableOptionsKeys(){
|
474 |
$ret = array();
|
820 |
function show_message($msg = 'null'){}
|
821 |
}
|
822 |
*/
|
823 |
+
if(! defined('FS_METHOD')){
|
824 |
+
define('FS_METHOD', 'direct'); //May be defined already and might not be 'direct' so this could cause problems. But we were getting reports of a warning that this is already defined, so this check added.
|
825 |
+
}
|
826 |
require_once(ABSPATH . 'wp-includes/update.php');
|
827 |
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
828 |
wp_update_plugins();
|
lib/wfCrypt.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class wfCrypt {
|
3 |
+
private static function getPubKey(){
|
4 |
+
#Command to generate our keypair was: openssl req -x509 -newkey rsa:2048 -keyout mycert.key -out mycert.pem -nodes -subj "/C=US/ST=Washington/L=Seattle/O=Wordfence/OU=IT/CN=wordfence.com" -days 7300
|
5 |
+
#This is a 2048 bit key using SHA256 with RSA.
|
6 |
+
$key = <<<ENDKEY
|
7 |
+
-----BEGIN CERTIFICATE-----
|
8 |
+
MIIDrTCCApWgAwIBAgIJAIg6Va5tcvwyMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
|
9 |
+
BAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRIw
|
10 |
+
EAYDVQQKDAlXb3JkZmVuY2UxCzAJBgNVBAsMAklUMRYwFAYDVQQDDA13b3JkZmVu
|
11 |
+
Y2UuY29tMB4XDTE1MDMxMjA1NTIzMFoXDTM1MDMwNzA1NTIzMFowbTELMAkGA1UE
|
12 |
+
BhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEjAQ
|
13 |
+
BgNVBAoMCVdvcmRmZW5jZTELMAkGA1UECwwCSVQxFjAUBgNVBAMMDXdvcmRmZW5j
|
14 |
+
ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/9Ogj1PIQsuZu
|
15 |
+
dTUNWlG0zaDNWpeY1ZiB/6oBS/YXkGFuG8R/nZ/kYsRmBm6yRp/3jC/HiPjg+7Zc
|
16 |
+
bA/CKoHdUlNjFZ+10DmS369wVX+c0oV9f720b/a0xN0qeKxJTiN2NsAl5szYv2CQ
|
17 |
+
Bvzjeb5VfKgrfV9tgYr38swudxvexponYaK0OlDL3u/Xca4SLRKmB+ZYCcZJttoG
|
18 |
+
SNFsQMlLHWWmM0FJH9qZ3x8MtRM5KsNEWO+/op511Rr36ZnLJdzUnETsaxHKwuCv
|
19 |
+
0+D9b0mwk8K/c67l63v4+zywXNkdYIslgo7Aeeyb6t0lyyfruXutEyMinmApACT2
|
20 |
+
sDMAbYk7AgMBAAGjUDBOMB0GA1UdDgQWBBTstr/AoPQyLLIt4/peFSjj0FFXHzAf
|
21 |
+
BgNVHSMEGDAWgBTstr/AoPQyLLIt4/peFSjj0FFXHzAMBgNVHRMEBTADAQH/MA0G
|
22 |
+
CSqGSIb3DQEBCwUAA4IBAQA9HsK+XdZh2MGP2SDdggA+MxkNBCCFBtcsmQrpiLUW
|
23 |
+
67xt59FPRMwTgSA9Lt8uqcWaXoHXiaTnXTRtN/BKZR0F71HQfiV6zy511blIRlk2
|
24 |
+
nV+vYzwLUENCZ31hQEZsY+uYqBSTiHecUKohn8A9pOOEpis2YEn2zVo4cobdyGa1
|
25 |
+
zCnaAN99KT8s9lOO0UW0J52qZhvv4y8YhELtrXKBsFatGEsVIM0NFI+ZDsNpMnSQ
|
26 |
+
cmUtLiIJtk5hxNbOaIz2vzbOkbzJ3ehzODJ1X5rya7X0v2akLLhwP9jqz5ua6ttP
|
27 |
+
duLv4Q6v3LY6pwDoyKQMDqNNxVjaFmx5HyFWRPofpu/T
|
28 |
+
-----END CERTIFICATE-----
|
29 |
+
ENDKEY;
|
30 |
+
return $key;
|
31 |
+
}
|
32 |
+
public static function makeSymHexKey($length){
|
33 |
+
$charset='ABCDEF0123456789';
|
34 |
+
$str = '';
|
35 |
+
$count = strlen($charset);
|
36 |
+
while($length--) {
|
37 |
+
$str .= $charset[mt_rand(0, $count-1)];
|
38 |
+
}
|
39 |
+
return $str;
|
40 |
+
}
|
41 |
+
public static function pubCrypt($symKey){ #encrypts a symmetric key and returns it base64
|
42 |
+
openssl_public_encrypt($symKey, $encSymKey, self::getPubKey(), OPENSSL_PKCS1_PADDING); //OPENSSL_PKCS1_PADDING is the default but setting explicitly because that's what we expect on the server.
|
43 |
+
return base64_encode($encSymKey);
|
44 |
+
}
|
45 |
+
}
|
46 |
+
?>
|
lib/wfDirectoryIterator.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class wfDirectoryIterator {
|
4 |
+
|
5 |
+
abstract public function file($file);
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var string
|
9 |
+
*/
|
10 |
+
private $directory;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var int
|
14 |
+
*/
|
15 |
+
private $directory_limit;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var callback
|
19 |
+
*/
|
20 |
+
private $callback;
|
21 |
+
/**
|
22 |
+
* @var int
|
23 |
+
*/
|
24 |
+
private $max_iterations;
|
25 |
+
private $iterations;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param string $directory
|
29 |
+
* @param int $max_files_per_directory
|
30 |
+
* @param int $max_iterations
|
31 |
+
*/
|
32 |
+
public function __construct($directory = ABSPATH, $max_files_per_directory = 20000, $max_iterations = 1000000) {
|
33 |
+
$this->directory = $directory;
|
34 |
+
$this->directory_limit = $max_files_per_directory;
|
35 |
+
$this->max_iterations = $max_iterations;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function run() {
|
39 |
+
$this->iterations = 0;
|
40 |
+
$this->scan($this->directory);
|
41 |
+
}
|
42 |
+
|
43 |
+
protected function scan($dir) {
|
44 |
+
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
|
45 |
+
$handle = opendir($dir);
|
46 |
+
$file_count = 0;
|
47 |
+
while ($file = readdir($handle)) {
|
48 |
+
if ($file == '.' || $file == '..') {
|
49 |
+
continue;
|
50 |
+
}
|
51 |
+
$file_path = $dir . '/' . $file;
|
52 |
+
if (is_dir($file_path)) {
|
53 |
+
if ($this->scan($file_path) === false) {
|
54 |
+
closedir($handle);
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
} else {
|
58 |
+
if ($this->file($file_path) === false) {
|
59 |
+
closedir($handle);
|
60 |
+
return false;
|
61 |
+
}
|
62 |
+
}
|
63 |
+
if ($file_count++ >= $this->directory_limit) {
|
64 |
+
break;
|
65 |
+
}
|
66 |
+
if ($this->iterations++ >= $this->max_iterations) {
|
67 |
+
closedir($handle);
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
closedir($handle);
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
lib/wfHelperString.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class wfHelperString {
|
5 |
+
|
6 |
+
/**
|
7 |
+
* cycle through arguments
|
8 |
+
*
|
9 |
+
* @return mixed
|
10 |
+
*/
|
11 |
+
public static function cycle() {
|
12 |
+
static $counter = 0;
|
13 |
+
$args = func_get_args();
|
14 |
+
if (empty($args)) {
|
15 |
+
$counter = 0;
|
16 |
+
return null;
|
17 |
+
}
|
18 |
+
$return_val = $args[$counter % count($args)];
|
19 |
+
$counter++;
|
20 |
+
return $return_val;
|
21 |
+
}
|
22 |
+
}
|
lib/wfLog.php
CHANGED
@@ -297,6 +297,9 @@ class wfLog {
|
|
297 |
$wfsn
|
298 |
);
|
299 |
}
|
|
|
|
|
|
|
300 |
wfCache::updateBlockedIPs('add');
|
301 |
wfConfig::inc('totalIPsBlocked');
|
302 |
return true;
|
297 |
$wfsn
|
298 |
);
|
299 |
}
|
300 |
+
|
301 |
+
wfActivityReport::logBlockedIP($IP);
|
302 |
+
|
303 |
wfCache::updateBlockedIPs('add');
|
304 |
wfConfig::inc('totalIPsBlocked');
|
305 |
return true;
|
lib/wfScanEngine.php
CHANGED
@@ -852,6 +852,10 @@ class wfScanEngine {
|
|
852 |
}
|
853 |
wordfence::statusEnd($this->statusIDX['dns'], $haveIssues);
|
854 |
}
|
|
|
|
|
|
|
|
|
855 |
private function scan_oldVersions(){
|
856 |
$this->statusIDX['oldVersions'] = wordfence::statusStart("Scanning for old themes, plugins and core files");
|
857 |
if(! function_exists( 'get_preferred_from_update_core')){
|
852 |
}
|
853 |
wordfence::statusEnd($this->statusIDX['dns'], $haveIssues);
|
854 |
}
|
855 |
+
|
856 |
+
/**
|
857 |
+
* @todo move the update login into wfUpdateCheck
|
858 |
+
*/
|
859 |
private function scan_oldVersions(){
|
860 |
$this->statusIDX['oldVersions'] = wordfence::statusStart("Scanning for old themes, plugins and core files");
|
861 |
if(! function_exists( 'get_preferred_from_update_core')){
|
lib/wfSchema.php
CHANGED
@@ -159,6 +159,13 @@ class wfSchema {
|
|
159 |
reason varchar(255) NOT NULL,
|
160 |
totalBlocked int UNSIGNED default 0,
|
161 |
lastBlocked int UNSIGNED default 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
) default charset=utf8"
|
163 |
/*
|
164 |
'wfPerfLog' => "(
|
159 |
reason varchar(255) NOT NULL,
|
160 |
totalBlocked int UNSIGNED default 0,
|
161 |
lastBlocked int UNSIGNED default 0
|
162 |
+
) default charset=utf8",
|
163 |
+
'wfBlockedIPLog' => "(
|
164 |
+
IP int UNSIGNED NOT NULL,
|
165 |
+
countryCode VARCHAR(2) NOT NULL,
|
166 |
+
blockCount int UNSIGNED NOT NULL DEFAULT 0,
|
167 |
+
unixday int UNSIGNED NOT NULL,
|
168 |
+
PRIMARY KEY(IP, unixday)
|
169 |
) default charset=utf8"
|
170 |
/*
|
171 |
'wfPerfLog' => "(
|
lib/wfUpdateCheck.php
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wfUpdateCheck {
|
4 |
+
|
5 |
+
private $needs_core_update = false;
|
6 |
+
private $core_update_version = 0;
|
7 |
+
private $plugin_updates = array();
|
8 |
+
private $theme_updates = array();
|
9 |
+
|
10 |
+
public function __construct() {
|
11 |
+
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return bool
|
16 |
+
*/
|
17 |
+
public function needsAnyUpdates() {
|
18 |
+
return $this->needsCoreUpdate() || count($this->getPluginUpdates()) > 0 || count($this->getThemeUpdates()) > 0;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Check for any core, plugin or theme updates.
|
23 |
+
*
|
24 |
+
* @return $this
|
25 |
+
*/
|
26 |
+
public function checkAllUpdates() {
|
27 |
+
return $this->checkCoreUpdates()
|
28 |
+
->checkPluginUpdates()
|
29 |
+
->checkThemeUpdates();
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Check if there is an update to the WordPress core.
|
34 |
+
*
|
35 |
+
* @return $this
|
36 |
+
*/
|
37 |
+
public function checkCoreUpdates() {
|
38 |
+
$this->needs_core_update = false;
|
39 |
+
if (!function_exists('get_preferred_from_update_core')) {
|
40 |
+
require_once(ABSPATH . 'wp-admin/includes/update.php');
|
41 |
+
}
|
42 |
+
$cur = get_preferred_from_update_core();
|
43 |
+
if (isset($cur->response) && $cur->response == 'upgrade') {
|
44 |
+
$this->needs_core_update = true;
|
45 |
+
$this->core_update_version = $cur->current;
|
46 |
+
}
|
47 |
+
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Check if any plugins need an update.
|
53 |
+
*
|
54 |
+
* @return $this
|
55 |
+
*/
|
56 |
+
public function checkPluginUpdates() {
|
57 |
+
$this->plugin_updates = array();
|
58 |
+
|
59 |
+
$update_plugins = get_site_transient('update_plugins');
|
60 |
+
if ($update_plugins && !empty($update_plugins->response)) {
|
61 |
+
foreach ($update_plugins->response as $plugin => $vals) {
|
62 |
+
if (!function_exists('get_plugin_data')) {
|
63 |
+
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
64 |
+
}
|
65 |
+
$pluginFile = wfUtils::getPluginBaseDir() . $plugin;
|
66 |
+
$data = get_plugin_data($pluginFile);
|
67 |
+
$data['newVersion'] = $vals->new_version;
|
68 |
+
$this->plugin_updates[] = $data;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
return $this;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Check if any themes need an update.
|
77 |
+
*
|
78 |
+
* @return $this
|
79 |
+
*/
|
80 |
+
public function checkThemeUpdates() {
|
81 |
+
$this->theme_updates = array();
|
82 |
+
|
83 |
+
$update_themes = get_site_transient('update_themes');
|
84 |
+
if ($update_themes && (!empty($update_themes->response))) {
|
85 |
+
if (!function_exists('wp_get_themes')) {
|
86 |
+
require_once ABSPATH . '/wp-includes/theme.php';
|
87 |
+
}
|
88 |
+
$themes = wp_get_themes();
|
89 |
+
foreach ($update_themes->response as $theme => $vals) {
|
90 |
+
foreach ($themes as $name => $themeData) {
|
91 |
+
if (strtolower($name) == $theme) {
|
92 |
+
$this->theme_updates[] = array(
|
93 |
+
'newVersion' => $vals['new_version'],
|
94 |
+
'package' => $vals['package'],
|
95 |
+
'URL' => $vals['url'],
|
96 |
+
'name' => $themeData['Name'],
|
97 |
+
'version' => $themeData['Version']
|
98 |
+
);
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
return $this;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @return boolean
|
108 |
+
*/
|
109 |
+
public function needsCoreUpdate() {
|
110 |
+
return $this->needs_core_update;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @return int
|
115 |
+
*/
|
116 |
+
public function getCoreUpdateVersion() {
|
117 |
+
return $this->core_update_version;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @return array
|
122 |
+
*/
|
123 |
+
public function getPluginUpdates() {
|
124 |
+
return $this->plugin_updates;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* @return array
|
129 |
+
*/
|
130 |
+
public function getThemeUpdates() {
|
131 |
+
return $this->theme_updates;
|
132 |
+
}
|
133 |
+
}
|
lib/wfView.php
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wfView {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string
|
7 |
+
*/
|
8 |
+
protected $view_path;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string
|
12 |
+
*/
|
13 |
+
protected $view_file_extension = '.php';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
protected $view;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
protected $data;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param string $view
|
27 |
+
* @param array $data
|
28 |
+
* @return wfView
|
29 |
+
*/
|
30 |
+
public static function create($view, $data = array()) {
|
31 |
+
return new self($view, $data);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param string $view
|
36 |
+
* @param array $data
|
37 |
+
*/
|
38 |
+
public function __construct($view, $data = array()) {
|
39 |
+
$this->view_path = WP_PLUGIN_DIR . '/wordfence/views';
|
40 |
+
$this->view = $view;
|
41 |
+
$this->data = $data;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return string
|
46 |
+
* @throws wfViewNotFoundException
|
47 |
+
*/
|
48 |
+
public function render() {
|
49 |
+
$view = preg_replace('/\.{2,}/', '.', $this->view);
|
50 |
+
$view_path = $this->view_path . '/' . $view . $this->view_file_extension;
|
51 |
+
if (!file_exists($view_path)) {
|
52 |
+
throw new wfViewNotFoundException('The view ' . $view_path . ' does not exist or is not readable.');
|
53 |
+
}
|
54 |
+
|
55 |
+
extract($this->data, EXTR_SKIP);
|
56 |
+
|
57 |
+
ob_start();
|
58 |
+
/** @noinspection PhpIncludeInspection */
|
59 |
+
include $view_path;
|
60 |
+
return ob_get_clean();
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @return string
|
65 |
+
*/
|
66 |
+
public function __toString() {
|
67 |
+
try {
|
68 |
+
return $this->render();
|
69 |
+
} catch (wfViewNotFoundException $e) {
|
70 |
+
return defined('WP_DEBUG') && WP_DEBUG ? $e->getMessage() : 'The view could not be loaded.';
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param $data
|
76 |
+
* @return $this
|
77 |
+
*/
|
78 |
+
public function addData($data) {
|
79 |
+
$this->data = array_merge($data, $this->data);
|
80 |
+
return $this;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @return array
|
85 |
+
*/
|
86 |
+
public function getData() {
|
87 |
+
return $this->data;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @param array $data
|
92 |
+
* @return $this
|
93 |
+
*/
|
94 |
+
public function setData($data) {
|
95 |
+
$this->data = $data;
|
96 |
+
return $this;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
public function getView() {
|
103 |
+
return $this->view;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @param string $view
|
108 |
+
* @return $this
|
109 |
+
*/
|
110 |
+
public function setView($view) {
|
111 |
+
$this->view = $view;
|
112 |
+
return $this;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Prevent POP
|
117 |
+
*/
|
118 |
+
public function __wakeup() {
|
119 |
+
$this->view_path = WP_PLUGIN_DIR . '/wordfence/views';
|
120 |
+
$this->view = null;
|
121 |
+
$this->data = array();
|
122 |
+
$this->view_file_extension = '.php';
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
class wfViewNotFoundException extends Exception {
|
127 |
+
}
|
lib/wordfenceClass.php
CHANGED
@@ -12,6 +12,13 @@ require_once('wfLog.php');
|
|
12 |
require_once('wfConfig.php');
|
13 |
require_once('wfSchema.php');
|
14 |
require_once('wfCache.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
class wordfence {
|
16 |
public static $printStatus = false;
|
17 |
public static $wordfence_wp_version = false;
|
@@ -34,32 +41,32 @@ class wordfence {
|
|
34 |
update_option('wordfenceActivated', 1);
|
35 |
}
|
36 |
public static function uninstallPlugin(){
|
37 |
-
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
|
38 |
$cacheType = wfConfig::get('cacheType', false);
|
39 |
if($cacheType == 'falcon'){
|
40 |
wfCache::addHtaccessCode('remove');
|
41 |
wfCache::updateBlockedIPs('remove');
|
42 |
wfConfig::set('cacheType', false);
|
43 |
-
|
44 |
-
//We currently don't clear the cache when plugin is disabled because it will take too long if done synchronously and won't work because plugin is disabled if done asynchronously.
|
45 |
//wfCache::scheduleCacheClear();
|
46 |
} else if($cacheType == 'php'){
|
47 |
wfConfig::set('cacheType', false);
|
48 |
}
|
49 |
-
|
50 |
|
51 |
//Used by MU code below
|
52 |
update_option('wordfenceActivated', 0);
|
53 |
wp_clear_scheduled_hook('wordfence_daily_cron');
|
54 |
wp_clear_scheduled_hook('wordfence_hourly_cron');
|
55 |
wp_clear_scheduled_hook('wordfence_daily_autoUpdate');
|
56 |
-
|
57 |
//Remove old legacy cron job if it exists
|
58 |
wp_clear_scheduled_hook('wordfence_scheduled_scan');
|
59 |
-
|
60 |
//Remove all scheduled scans.
|
61 |
self::unscheduleAllScans();
|
62 |
-
|
63 |
wfConfig::clearDiskCache();
|
64 |
if(wfConfig::get('deleteTablesOnDeact')){
|
65 |
$schema = new wfSchema();
|
@@ -113,7 +120,7 @@ class wordfence {
|
|
113 |
for($i = 0; $i < $len; $i += 4){
|
114 |
list($ipLong) = array_values(unpack('N', substr($resp['data'], $i, 4)));
|
115 |
$IPStr = long2ip($ipLong);
|
116 |
-
if(! self::getLog()->isWhitelisted($IPStr)){
|
117 |
self::getLog()->blockIP($IPStr, $reason, true);
|
118 |
}
|
119 |
}
|
@@ -173,7 +180,7 @@ class wordfence {
|
|
173 |
wordfence::status(4, 'error', "Could not fetch vulnerability patterns in scheduled job: " . $e->getMessage());
|
174 |
}
|
175 |
|
176 |
-
$wfdb->queryWrite("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
|
177 |
$wfdb->truncate($p . "wfBadLeechers"); //only uses date that's less than 1 minute old
|
178 |
$wfdb->queryWrite("delete from $p"."wfBlocks where (blockedTime + %s < unix_timestamp()) and permanent=0", wfConfig::get('blockedTime'));
|
179 |
$wfdb->queryWrite("delete from $p"."wfCrawlers where lastUpdate < unix_timestamp() - (86400 * 7)");
|
@@ -220,7 +227,7 @@ class wordfence {
|
|
220 |
$count4 = $wfdb->querySingle("select count(*) as cnt from $p"."wfStatus");
|
221 |
if($count4 > 100000){
|
222 |
$wfdb->truncate($p . "wfStatus");
|
223 |
-
} else if($count4 > 1000){ //max status events we keep. This determines how much gets emailed to us when users sends us a debug report.
|
224 |
$wfdb->queryWrite("delete from $p"."wfStatus where level != 10 order by ctime asc limit %d", ($count4 - 1000));
|
225 |
$count5 = $wfdb->querySingle("select count(*) as cnt from $p"."wfStatus where level=10");
|
226 |
if($count5 > 100){
|
@@ -228,6 +235,8 @@ class wordfence {
|
|
228 |
}
|
229 |
}
|
230 |
|
|
|
|
|
231 |
}
|
232 |
public static function runInstall(){
|
233 |
if(self::$runInstallCalled){ return; }
|
@@ -302,16 +311,16 @@ class wordfence {
|
|
302 |
$db->queryWriteIgnoreError("alter table $prefix"."wfLockedOut modify column blockedTime bigint signed NOT NULL");
|
303 |
$db->queryWriteIgnoreError("drop table if exists $prefix"."wfFileQueue");
|
304 |
$db->queryWriteIgnoreError("drop table if exists $prefix"."wfFileChanges");
|
305 |
-
//Adding primary key to this table because some backup apps use primary key during backup.
|
306 |
$db->queryWriteIgnoreError("alter table wp_wfStatus add id bigint UNSIGNED NOT NULL auto_increment PRIMARY KEY");
|
307 |
|
308 |
$optScanEnabled = $db->querySingle("select val from $prefix"."wfConfig where name='scansEnabled_options'");
|
309 |
if($optScanEnabled != '0' && $optScanEnabled != '1'){
|
310 |
$db->queryWrite("update $prefix"."wfConfig set val='1' where name='scansEnabled_options'");
|
311 |
}
|
312 |
-
|
313 |
$optScanEnabled = $db->querySingle("select val from $prefix"."wfConfig where name='scansEnabled_heartbleed'");
|
314 |
-
if($optScanEnabled != '0' && $optScanEnabled != '1'){ //Enable heartbleed if no value is set.
|
315 |
wfConfig::set('scansEnabled_heartbleed', 1);
|
316 |
}
|
317 |
|
@@ -325,7 +334,7 @@ class wordfence {
|
|
325 |
} else {
|
326 |
$wfLog->logLeechAndBlock('hit');
|
327 |
}
|
328 |
-
if(wfConfig::liveTrafficEnabled()){
|
329 |
self::$hitID = $wfLog->logHit();
|
330 |
add_action('wp_head', 'wordfence::wfLogHumanHeader');
|
331 |
}
|
@@ -376,10 +385,8 @@ class wordfence {
|
|
376 |
add_action('wp_ajax_wordfence_logHuman', 'wordfence::ajax_logHuman_callback');
|
377 |
add_action('wp_ajax_wordfence_doScan', 'wordfence::ajax_doScan_callback');
|
378 |
add_action('wp_ajax_wordfence_testAjax', 'wordfence::ajax_testAjax_callback');
|
379 |
-
/*
|
380 |
-
add_action('wp_dashboard_setup', 'wordfence::addDashboardWidget');
|
381 |
-
*/
|
382 |
|
|
|
383 |
}
|
384 |
|
385 |
|
@@ -391,7 +398,7 @@ class wordfence {
|
|
391 |
add_action('init', 'wordfence::initAction');
|
392 |
add_action('template_redirect', 'wordfence::templateRedir');
|
393 |
add_action('shutdown', 'wordfence::shutdownAction');
|
394 |
-
|
395 |
if(version_compare(PHP_VERSION, '5.4.0') >= 0){
|
396 |
add_action('wp_authenticate','wordfence::authActionNew', 1, 2);
|
397 |
} else {
|
@@ -411,9 +418,12 @@ class wordfence {
|
|
411 |
add_action('publish_future_post', 'wordfence::publishFuturePost');
|
412 |
add_action('mobile_setup', 'wordfence::jetpackMobileSetup'); //Action called in Jetpack Mobile Theme: modules/minileven/minileven.php
|
413 |
|
|
|
|
|
|
|
414 |
//For debugging
|
415 |
//add_filter( 'cron_schedules', 'wordfence::cronAddSchedules' );
|
416 |
-
|
417 |
add_filter('wp_redirect', 'wordfence::wpRedirectFilter', 99, 2);
|
418 |
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
|
419 |
//html|xhtml|atom|rss2|rdf|comment|export
|
@@ -460,7 +470,7 @@ class wordfence {
|
|
460 |
}
|
461 |
*/
|
462 |
public static function jetpackMobileSetup(){
|
463 |
-
define('WFDONOTCACHE', true); //Don't cache jetpack mobile theme pages.
|
464 |
}
|
465 |
public static function wpRedirectFilter($URL, $status){
|
466 |
if(isset($_GET['author']) && preg_match('/\/author\/.+/i', $URL) && wfConfig::get('loginSec_disableAuthorScan') ){ //author query variable is present and we're about to redirect to a URL that starts with http://blah/author/...
|
@@ -491,8 +501,8 @@ class wordfence {
|
|
491 |
}
|
492 |
$UA = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
493 |
$URL = $_POST['URL'];
|
494 |
-
$wfLog->logPerf(wfUtils::getIP(), $UA, $URL, $data);
|
495 |
-
die(json_encode(array('ok' => 1)));
|
496 |
}
|
497 |
public static function ajax_logHuman_callback(){
|
498 |
$browscap = new wfBrowscap();
|
@@ -506,7 +516,7 @@ class wordfence {
|
|
506 |
}
|
507 |
|
508 |
@ob_end_clean();
|
509 |
-
if(! headers_sent()){
|
510 |
header('Content-type: text/javascript');
|
511 |
header("Connection: close");
|
512 |
header("Content-Length: 0");
|
@@ -528,7 +538,7 @@ class wordfence {
|
|
528 |
}
|
529 |
$func = (isset($_POST['action']) && $_POST['action']) ? $_POST['action'] : $_GET['action'];
|
530 |
$nonce = (isset($_POST['nonce']) && $_POST['nonce']) ? $_POST['nonce'] : $_GET['nonce'];
|
531 |
-
if(! wp_verify_nonce($nonce, 'wp-ajax')){
|
532 |
die(json_encode(array('errorMsg' => "Your browser sent an invalid security token to Wordfence. Please try reloading this page or signing out and in again.")));
|
533 |
}
|
534 |
//func is e.g. wordfence_ticker so need to munge it
|
@@ -537,7 +547,7 @@ class wordfence {
|
|
537 |
if($returnArr === false){
|
538 |
$returnArr = array('errorMsg' => "Wordfence encountered an internal error executing that request.");
|
539 |
}
|
540 |
-
|
541 |
if(! is_array($returnArr)){
|
542 |
error_log("Function " . wp_kses($func, array()) . " did not return an array and did not generate an error.");
|
543 |
$returnArr = array();
|
@@ -584,7 +594,7 @@ class wordfence {
|
|
584 |
return $errors;
|
585 |
}
|
586 |
public static function isStrongPasswd($passwd, $username ) {
|
587 |
-
$strength = 0;
|
588 |
if(strlen( trim( $passwd ) ) < 5)
|
589 |
return false;
|
590 |
if(strtolower( $passwd ) == strtolower( $username ) )
|
@@ -601,7 +611,7 @@ class wordfence {
|
|
601 |
$strength += 26;
|
602 |
if ($num = preg_match_all( "/[^a-zA-Z0-9]/", $passwd, $matches)){
|
603 |
$strength += (31 * (int)$num);
|
604 |
-
|
605 |
}
|
606 |
if($strength > 60){
|
607 |
return true;
|
@@ -747,7 +757,7 @@ class wordfence {
|
|
747 |
public static function loginAction($username){
|
748 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
749 |
if(! $username){ return; }
|
750 |
-
wfConfig::inc('totalLogins');
|
751 |
$user = get_user_by('login', $username);
|
752 |
$userID = $user ? $user->ID : 0;
|
753 |
self::getLog()->logLogin('loginOK', 0, $username);
|
@@ -763,7 +773,7 @@ class wordfence {
|
|
763 |
}
|
764 |
|
765 |
if(user_can($userID, 'update_core')){
|
766 |
-
if(wfConfig::get('alertOn_adminLogin')){
|
767 |
wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
|
768 |
}
|
769 |
} else {
|
@@ -780,18 +790,18 @@ class wordfence {
|
|
780 |
}
|
781 |
public static function authenticateFilter($authUser, $username, $passwd){
|
782 |
wfConfig::inc('totalLoginHits'); //The total hits to wp-login.php including logins, logouts and just hits.
|
783 |
-
$IP = wfUtils::getIP();
|
784 |
$secEnabled = wfConfig::get('loginSecurityEnabled');
|
785 |
if($secEnabled && (! self::getLog()->isWhitelisted($IP)) && wfConfig::get('isPaid') ){
|
786 |
$twoFactorUsers = wfConfig::get_ser('twoFactorUsers', array());
|
787 |
if(isset($twoFactorUsers) && is_array($twoFactorUsers) && sizeof($twoFactorUsers) > 0){
|
788 |
$userDat = (isset($_POST['wordfence_userDat']) ? $_POST['wordfence_userDat'] : false);
|
789 |
-
if(is_object($userDat) && get_class($authUser) == 'WP_User'){ //Valid username and password either with or without the 'wf...' code. Users is now logged in at this point.
|
790 |
if(isset($_POST['wordfence_authFactor']) && $_POST['wordfence_authFactor']){ //user entered a valid user and password with ' wf....' appended
|
791 |
foreach($twoFactorUsers as &$t){
|
792 |
if($t[0] == $userDat->ID && $t[3] == 'activated'){
|
793 |
if($_POST['wordfence_authFactor'] == $t[2] && $t[4] > time()){
|
794 |
-
//Do nothing and allow user to sign in. Their passwd has already been modified to be the passwd without the code.
|
795 |
} else if($_POST['wordfence_authFactor'] == $t[2]){
|
796 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
797 |
$codeResult = $api->call('twoFactor_verification', array(), array('phone' => $t[1]) );
|
@@ -806,7 +816,7 @@ class wordfence {
|
|
806 |
} else {
|
807 |
break; //No new code was received. Let them sign in with the expired code.
|
808 |
}
|
809 |
-
} else { //Bad code, so cancel the login and return an error to user.
|
810 |
return new WP_Error( 'twofactor_required', __( '<strong>INVALID CODE</strong>: You need to enter your password followed by a space and the code we sent to your phone. The code should start with \'wf\' and should be four characters. e.g. wfAB12. In this case you would enter your password as: \'mypassword wfAB12\' without quotes.'));
|
811 |
}
|
812 |
} //No user matches and has TF activated so let user sign in.
|
@@ -825,7 +835,7 @@ class wordfence {
|
|
825 |
$t[4] = time() + 1800; //30 minutes until code expires
|
826 |
wfConfig::set_ser('twoFactorUsers', $twoFactorUsers); //save the code the user needs to enter and return an error.
|
827 |
return new WP_Error( 'twofactor_required', __( '<strong>CHECK YOUR PHONE</strong>: A code has been sent to your phone and will arrive within 30 seconds. Please sign in again and add a space and the code to the end of your password.' ) );
|
828 |
-
} else { //oops, our API returned an error.
|
829 |
break; //Let them sign in without two factor because the API is broken and we don't want to lock users out of their own systems.
|
830 |
}
|
831 |
} //User is not present in two factor list or is not activated. Sign in without twofactor.
|
@@ -842,7 +852,7 @@ class wordfence {
|
|
842 |
if($maxBlockTime = self::wfsnIsBlocked($IP, 'brute')){
|
843 |
self::getLog()->blockIP($IP, "Blocked by Wordfence Security Network", true, false, $maxBlockTime);
|
844 |
}
|
845 |
-
|
846 |
}
|
847 |
if($secEnabled){
|
848 |
if(is_wp_error($authUser) && $authUser->get_error_code() == 'invalid_username'){
|
@@ -883,9 +893,9 @@ class wordfence {
|
|
883 |
}
|
884 |
if(is_wp_error($authUser)){
|
885 |
if($authUser->get_error_code() == 'invalid_username'){
|
886 |
-
self::getLog()->logLogin('loginFailInvalidUsername', 1, $username);
|
887 |
} else {
|
888 |
-
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
|
889 |
}
|
890 |
}
|
891 |
|
@@ -948,7 +958,7 @@ class wordfence {
|
|
948 |
$userID = get_current_user_id();
|
949 |
$userDat = get_user_by('id', $userID);
|
950 |
if(is_object($userDat)){
|
951 |
-
self::getLog()->logLogin('logout', 0, $userDat->user_login);
|
952 |
}
|
953 |
}
|
954 |
public static function loginInitAction(){
|
@@ -960,10 +970,10 @@ class wordfence {
|
|
960 |
if(self::isLockedOut(wfUtils::getIP())){
|
961 |
require('wfLockedOut.php');
|
962 |
}
|
963 |
-
if(! $username){ return; }
|
964 |
$userDat = get_user_by('login', $username);
|
965 |
$_POST['wordfence_userDat'] = $userDat;
|
966 |
-
if(preg_match(self::$passwordCodePattern, $passwd, $matches)){
|
967 |
$_POST['wordfence_authFactor'] = $matches[1];
|
968 |
$passwd = preg_replace('/^(.+)\s+(wf[a-z0-9]+)$/i', '$1', $passwd);
|
969 |
$_POST['pwd'] = $passwd;
|
@@ -973,10 +983,10 @@ class wordfence {
|
|
973 |
if(self::isLockedOut(wfUtils::getIP())){
|
974 |
require('wfLockedOut.php');
|
975 |
}
|
976 |
-
if(! $username){ return; }
|
977 |
$userDat = get_user_by('login', $username);
|
978 |
$_POST['wordfence_userDat'] = $userDat;
|
979 |
-
if(preg_match(self::$passwordCodePattern, $passwd, $matches)){
|
980 |
$_POST['wordfence_authFactor'] = $matches[1];
|
981 |
$passwd = preg_replace('/^(.+)\s+(wf[a-z0-9]+)$/i', '$1', $passwd);
|
982 |
$_POST['pwd'] = $passwd;
|
@@ -1168,12 +1178,12 @@ class wordfence {
|
|
1168 |
$nextTime = self::getNextScanStartTime();
|
1169 |
return array(
|
1170 |
'ok' => 1,
|
1171 |
-
'nextStart' => ($nextTime ? $nextTime : '')
|
1172 |
);
|
1173 |
}
|
1174 |
public static function getNextScanStartTime(){
|
1175 |
$nextTime = false;
|
1176 |
-
$cron = _get_cron_array();
|
1177 |
foreach($cron as $key => $val){
|
1178 |
if(isset($val['wordfence_start_scheduled_scan'])){
|
1179 |
$nextTime = $key;
|
@@ -1183,7 +1193,7 @@ class wordfence {
|
|
1183 |
return ($nextTime ? date('l jS \of F Y H:i:s A', $nextTime + (3600 * get_option('gmt_offset'))) : '');
|
1184 |
}
|
1185 |
public static function wordfenceStartScheduledScan(){
|
1186 |
-
|
1187 |
//If scheduled scans are not enabled in the global config option, then don't run a scheduled scan.
|
1188 |
if(wfConfig::get('scheduledScansEnabled') != '1'){
|
1189 |
return;
|
@@ -1198,7 +1208,7 @@ class wordfence {
|
|
1198 |
}
|
1199 |
wfConfig::set('lastScheduledScanStart', time());
|
1200 |
wordfence::status(1, 'info', "Scheduled Wordfence scan starting at " . date('l jS \of F Y h:i:s A', current_time('timestamp')) );
|
1201 |
-
|
1202 |
//We call this before the scan actually starts to advance the schedule for the next week.
|
1203 |
//This ensures that if the scan crashes for some reason, the schedule will hold.
|
1204 |
wordfence::scheduleScans();
|
@@ -1210,7 +1220,7 @@ class wordfence {
|
|
1210 |
$sched = wfConfig::get_ser('scanSched', array());
|
1211 |
$mode = wfConfig::get('schedMode');
|
1212 |
if($mode == 'manual' && is_array($sched) && is_array($sched[0]) ){
|
1213 |
-
//Use sched as it is
|
1214 |
} else { //Default to setting scans to run once a day at a randomly selected time.
|
1215 |
$sched = array();
|
1216 |
$runAt = rand(0,23);
|
@@ -1283,15 +1293,15 @@ class wordfence {
|
|
1283 |
$content .= date(DATE_RFC822, $r['ctime'] + $timeOffset) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . wp_kses_data( (string) $r['msg']) . "\n";
|
1284 |
}
|
1285 |
$content .= "\n\n";
|
1286 |
-
|
1287 |
ob_start();
|
1288 |
phpinfo();
|
1289 |
$phpinfo = ob_get_contents();
|
1290 |
ob_get_clean();
|
1291 |
|
1292 |
$content .= $phpinfo;
|
1293 |
-
|
1294 |
-
wp_mail($_POST['email'], "Wordfence Activity Log", $content);
|
1295 |
return array('ok' => 1);
|
1296 |
}
|
1297 |
public static function ajax_startTourAgain_callback(){
|
@@ -1305,7 +1315,7 @@ class wordfence {
|
|
1305 |
if($keyData['ok'] && $keyData['apiKey']){
|
1306 |
wfConfig::set('apiKey', $keyData['apiKey']);
|
1307 |
wfConfig::set('isPaid', 0);
|
1308 |
-
//When downgrading we must disable all two factor authentication because it can lock an admin out if we don't.
|
1309 |
wfConfig::set_ser('twoFactorUsers', array());
|
1310 |
} else {
|
1311 |
throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free API key.");
|
@@ -1348,9 +1358,9 @@ class wordfence {
|
|
1348 |
public static function disablePermalinksFilter($newVal, $oldVal){
|
1349 |
if(wfConfig::get('cacheType', false) == 'falcon' && $oldVal && (! $newVal) ){ //Falcon is enabled and admin is disabling permalinks
|
1350 |
wfCache::addHtaccessCode('remove');
|
1351 |
-
//if($err){ return $oldVal; } //We might want to not allow the user to disable permalinks if we can't disable falcon. Allowing it for now.
|
1352 |
wfCache::updateBlockedIPs('remove');
|
1353 |
-
//if($err){ return $oldVal; } //We might want to not allow the user to disable permalinks if we can't disable falcon. Allowing it for now.
|
1354 |
wfConfig::set('cacheType', false);
|
1355 |
}
|
1356 |
return $newVal;
|
@@ -1447,12 +1457,12 @@ class wordfence {
|
|
1447 |
return array('ok' => 1, 'heading' => "Could not write to cache directory", 'body' => "To enable caching, Wordfence needs to be able to create and write to the /wp-content/wfcache/ directory. We did some tests that indicate this is not possible. You need to manually create the /wp-content/wfcache/ directory and make it writable by Wordfence. The error we encountered was during our tests was: $err");
|
1448 |
}
|
1449 |
}
|
1450 |
-
|
1451 |
-
//Mainly we clear the cache here so that any footer cache diagnostic comments are rebuilt. We could just leave it intact unless caching is being disabled.
|
1452 |
if($cacheType != wfConfig::get('cacheType', false)){
|
1453 |
wfCache::scheduleCacheClear();
|
1454 |
}
|
1455 |
-
$htMsg = "";
|
1456 |
if($warnHtaccess){
|
1457 |
$htMsg = " <strong style='color: #F00;'>Warning: We could not remove the caching code from your .htaccess file. you need to remove this manually yourself.</strong> ";
|
1458 |
}
|
@@ -1480,11 +1490,11 @@ class wordfence {
|
|
1480 |
if($s['files'] == 0){
|
1481 |
return array('ok' => 1, 'heading' => 'Cache Stats', 'body' => "The cache is currently empty. It may be disabled or it may have been recently cleared.");
|
1482 |
}
|
1483 |
-
$body = 'Total files in cache: ' . $s['files'] .
|
1484 |
-
'<br />Total directories in cache: ' . $s['dirs'] .
|
1485 |
'<br />Total data: ' . $s['data'] . 'KB';
|
1486 |
if($s['compressedFiles'] > 0){
|
1487 |
-
$body .= '<br />Files: ' . $s['uncompressedFiles'] .
|
1488 |
'<br />Data: ' . $s['uncompressedKBytes'] . 'KB' .
|
1489 |
'<br />Compressed files: ' . $s['compressedFiles'] .
|
1490 |
'<br />Compressed data: ' . $s['compressedKBytes'] . 'KB';
|
@@ -1585,7 +1595,7 @@ class wordfence {
|
|
1585 |
}
|
1586 |
$ex = unserialize($ex);
|
1587 |
$rewriteHtaccess = false;
|
1588 |
-
for($i = 0; $i < sizeof($ex); $i++){
|
1589 |
if((string)$ex[$i]['id'] == (string)$id){
|
1590 |
if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)$/', $ex[$i]['pt'])){
|
1591 |
$rewriteHtaccess = true;
|
@@ -1708,13 +1718,13 @@ class wordfence {
|
|
1708 |
if(sizeof($validIPs) > 0){
|
1709 |
$opts['liveTraf_ignoreIPs'] = implode(',', $validIPs);
|
1710 |
}
|
1711 |
-
|
1712 |
if(preg_match('/[a-zA-Z0-9\d]+/', $opts['liveTraf_ignoreUA'])){
|
1713 |
$opts['liveTraf_ignoreUA'] = trim($opts['liveTraf_ignoreUA']);
|
1714 |
} else {
|
1715 |
$opts['liveTraf_ignoreUA'] = '';
|
1716 |
}
|
1717 |
-
if(! $opts['other_WFNet']){
|
1718 |
$wfdb = new wfDB();
|
1719 |
global $wpdb;
|
1720 |
$p = $wpdb->base_prefix;
|
@@ -1742,7 +1752,7 @@ class wordfence {
|
|
1742 |
} else if($opts['autoUpdate'] == '0'){
|
1743 |
wfConfig::disableAutoUpdate();
|
1744 |
}
|
1745 |
-
|
1746 |
try {
|
1747 |
if ($opts['disableCodeExecutionUploads']) {
|
1748 |
wfConfig::disableCodeExecutionForUploads();
|
@@ -1752,6 +1762,17 @@ class wordfence {
|
|
1752 |
} catch (wfConfigException $e) {
|
1753 |
return array('errorMsg' => $e->getMessage());
|
1754 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1755 |
|
1756 |
$paidKeyMsg = false;
|
1757 |
|
@@ -1797,7 +1818,7 @@ class wordfence {
|
|
1797 |
$op = $_POST['op'];
|
1798 |
$wfLog = self::getLog();
|
1799 |
if($op == 'blocked'){
|
1800 |
-
wordfence::status(1, 'info', "Ajax request received to unblock All IP's including permanent blocks.");
|
1801 |
$wfLog->unblockAllIPs();
|
1802 |
} else if($op == 'locked'){
|
1803 |
$wfLog->unlockAllIPs();
|
@@ -1897,7 +1918,7 @@ class wordfence {
|
|
1897 |
if(self::getLog()->isWhitelisted($IP)){
|
1898 |
return array('err' => 1, 'errorMsg' => "The IP address " . wp_kses($IP, array()) . " is whitelisted and can't be blocked or it is in a range of internal IP addresses that Wordfence does not block. You can remove this IP from the whitelist on the Wordfence options page.");
|
1899 |
}
|
1900 |
-
if(wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers'){ //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
|
1901 |
if(wfCrawl::verifyCrawlerPTR('/\.googlebot\.com$/i', $IP)){
|
1902 |
return array('err' => 1, 'errorMsg' => "The IP address you're trying to block belongs to Google. Your options are currently set to not block these crawlers. Change this in Wordfence options if you want to manually block Google.");
|
1903 |
}
|
@@ -1923,7 +1944,7 @@ class wordfence {
|
|
1923 |
$op = $_POST['op'];
|
1924 |
$i = new wfIssues();
|
1925 |
if($op == 'deleteIgnored'){
|
1926 |
-
$i->deleteIgnored();
|
1927 |
} else if($op == 'deleteNew'){
|
1928 |
$i->deleteNew();
|
1929 |
} else if($op == 'ignoreAllNew'){
|
@@ -2021,7 +2042,7 @@ class wordfence {
|
|
2021 |
$errors = array();
|
2022 |
$issues = new wfIssues();
|
2023 |
foreach($ids as $id){
|
2024 |
-
$id = intval($id); //Make sure input is a number.
|
2025 |
$issue = $issues->getIssueByID($id);
|
2026 |
if(! $issue){
|
2027 |
$errors[] = "Could not delete one of the files because we could not find the issue. Perhaps it's been resolved?";
|
@@ -2043,7 +2064,7 @@ class wordfence {
|
|
2043 |
$errors[] = "Could not delete file " . wp_kses($file, array()) . ". Error was: " . wp_kses($err['message'], array());
|
2044 |
}
|
2045 |
} else if($op == 'repair'){
|
2046 |
-
$dat = $issue['data'];
|
2047 |
$result = self::getWPFileContent($dat['file'], $dat['cType'], $dat['cName'], $dat['cVersion']);
|
2048 |
if($result['cerrorMsg']){
|
2049 |
$errors[] = $result['cerrorMsg'];
|
@@ -2052,7 +2073,7 @@ class wordfence {
|
|
2052 |
$errors[] = "We could not get the original file of " . wp_kses($file, array()) . " to do a repair.";
|
2053 |
continue;
|
2054 |
}
|
2055 |
-
|
2056 |
if(preg_match('/\.\./', $file)){
|
2057 |
$errors[] = "An invalid file " . wp_kses($file, array()) . " was specified for repair.";
|
2058 |
continue;
|
@@ -2136,7 +2157,7 @@ class wordfence {
|
|
2136 |
if(! $issue){
|
2137 |
return array('cerrorMsg' => "We could not find that issue in our database.");
|
2138 |
}
|
2139 |
-
$dat = $issue['data'];
|
2140 |
$result = self::getWPFileContent($dat['file'], $dat['cType'], (isset($dat['cName']) ? $dat['cName'] : ''), (isset($dat['cVersion']) ? $dat['cVersion'] : ''));
|
2141 |
$file = $dat['file'];
|
2142 |
if(isset($result['cerrorMsg']) && $result['cerrorMsg']){
|
@@ -2144,7 +2165,7 @@ class wordfence {
|
|
2144 |
} else if(! $result['fileContent']){
|
2145 |
return array('cerrorMsg' => "We could not get the original file to do a repair.");
|
2146 |
}
|
2147 |
-
|
2148 |
if(preg_match('/\.\./', $file)){
|
2149 |
return array('cerrorMsg' => "An invalid file was specified for repair.");
|
2150 |
}
|
@@ -2202,7 +2223,7 @@ class wordfence {
|
|
2202 |
throw new Exception("Invalid response: " . var_export($res, true));
|
2203 |
}
|
2204 |
} catch(Exception $e){
|
2205 |
-
return array('err' => "An error occurred: " . $e->getMessage());
|
2206 |
}
|
2207 |
}
|
2208 |
public static function importSettings($token){
|
@@ -2229,7 +2250,205 @@ class wordfence {
|
|
2229 |
} else {
|
2230 |
throw new Exception("Invalid response from Wordfence servers during import.");
|
2231 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2232 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2233 |
public static function ajax_importSettings_callback(){
|
2234 |
$token = $_POST['token'];
|
2235 |
try {
|
@@ -2246,8 +2465,8 @@ class wordfence {
|
|
2246 |
wfScanEngine::startScan();
|
2247 |
}
|
2248 |
public static function templateRedir(){
|
2249 |
-
$wfFunc = get_query_var('_wfsf');
|
2250 |
-
|
2251 |
//Logging
|
2252 |
self::doEarlyAccessLogging();
|
2253 |
//End logging
|
@@ -2287,7 +2506,7 @@ class wordfence {
|
|
2287 |
self::wfFunc_testmem();
|
2288 |
} else if($wfFunc == 'testtime'){
|
2289 |
self::wfFunc_testtime();
|
2290 |
-
}
|
2291 |
exit(0);
|
2292 |
}
|
2293 |
public static function memtest_error_handler($errno, $errstr, $errfile, $errline){
|
@@ -2365,7 +2584,7 @@ wfscr.type = 'text/javascript';
|
|
2365 |
wfscr.async = true;
|
2366 |
wfscr.src = url;
|
2367 |
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(wfscr);
|
2368 |
-
})('$scriptURL');
|
2369 |
</script>
|
2370 |
EOL;
|
2371 |
}
|
@@ -2382,7 +2601,7 @@ wfscr.type = 'text/javascript';
|
|
2382 |
wfscr.async = true;
|
2383 |
wfscr.src = url + '&r=' + Math.random();
|
2384 |
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(wfscr);
|
2385 |
-
})('$URL');
|
2386 |
</script>
|
2387 |
EOL;
|
2388 |
}
|
@@ -2401,7 +2620,7 @@ EOL;
|
|
2401 |
$reverseLookup = wfUtils::reverseLookup($IP);
|
2402 |
$wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2403 |
$results = array_merge(
|
2404 |
-
$wfLog->getHits('hits', 'hit', 0, 10000, $IP),
|
2405 |
$wfLog->getHits('hits', '404', 0, 10000, $IP)
|
2406 |
);
|
2407 |
usort($results, 'wordfence::iptrafsort');
|
@@ -2443,7 +2662,7 @@ EOL;
|
|
2443 |
$fileMTime = @filemtime($localFile);
|
2444 |
$fileMTime = date('l jS \of F Y h:i:s A', $fileMTime);
|
2445 |
try {
|
2446 |
-
if(wfUtils::fileOver2Gigs($localFile)){
|
2447 |
$fileSize = "Greater than 2 Gigs";
|
2448 |
} else {
|
2449 |
$fileSize = @filesize($localFile); //Checked if over 2 gigs above
|
@@ -2476,8 +2695,8 @@ EOL;
|
|
2476 |
} else {
|
2477 |
$diff = new Diff(
|
2478 |
//Treat DOS and Unix files the same
|
2479 |
-
preg_split("/(?:\r\n|\n)/", $result['fileContent']),
|
2480 |
-
preg_split("/(?:\r\n|\n)/", $localContents),
|
2481 |
array()
|
2482 |
);
|
2483 |
$renderer = new Diff_Renderer_Html_SideBySide;
|
@@ -2507,7 +2726,7 @@ EOL;
|
|
2507 |
}
|
2508 |
public static function admin_init(){
|
2509 |
if(! wfUtils::isAdmin()){ return; }
|
2510 |
-
foreach(array('activate', 'scan', 'updateAlertEmail', 'sendActivityLog', 'restoreFile', 'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'removeExclusion', 'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues', 'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP', 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'checkFalconHtaccess', 'updateConfig', 'saveCacheConfig', 'removeFromCache', 'autoUpdateChoice', 'saveCacheOptions', 'clearPageCache', 'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed', 'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel', 'loadTwoFactor', 'loadAvgSitePerf', 'sendTestEmail', 'addCacheExclusion', 'removeCacheExclusion', 'loadCacheExclusions') as $func){
|
2511 |
add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
|
2512 |
}
|
2513 |
|
@@ -2612,13 +2831,15 @@ EOL;
|
|
2612 |
}
|
2613 |
}
|
2614 |
}
|
2615 |
-
|
2616 |
add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "Wordfence", 'wordfence::menu_scan');
|
2617 |
-
add_menu_page('Wordfence', 'Wordfence', 'activate_plugins', 'Wordfence', 'wordfence::menu_scan', wfUtils::getBaseURL() . 'images/wordfence-logo-16x16.png');
|
2618 |
add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
|
2619 |
/* add_submenu_page('Wordfence', 'Site Performance', 'Site Performance', 'activate_plugins', 'WordfenceSitePerfStats', 'wordfence::menu_sitePerfStats'); */
|
2620 |
add_submenu_page('Wordfence', 'Performance Setup', 'Performance Setup', 'activate_plugins', 'WordfenceSitePerf', 'wordfence::menu_sitePerf');
|
2621 |
add_submenu_page('Wordfence', 'Blocked IPs', 'Blocked IPs', 'activate_plugins', 'WordfenceBlockedIPs', 'wordfence::menu_blockedIPs');
|
|
|
|
|
2622 |
add_submenu_page("Wordfence", "Cellphone Sign-in", "Cellphone Sign-in", "activate_plugins", "WordfenceTwoFactor", 'wordfence::menu_twoFactor');
|
2623 |
add_submenu_page("Wordfence", "Country Blocking", "Country Blocking", "activate_plugins", "WordfenceCountryBlocking", 'wordfence::menu_countryBlocking');
|
2624 |
add_submenu_page("Wordfence", "Scan Schedule", "Scan Schedule", "activate_plugins", "WordfenceScanSchedule", 'wordfence::menu_scanSchedule');
|
@@ -2638,6 +2859,10 @@ EOL;
|
|
2638 |
public static function menu_blockedIPs(){
|
2639 |
require 'menu_blockedIPs.php';
|
2640 |
}
|
|
|
|
|
|
|
|
|
2641 |
public static function menu_scanSchedule(){
|
2642 |
require 'menu_scanSchedule.php';
|
2643 |
}
|
@@ -2684,7 +2909,7 @@ EOL;
|
|
2684 |
if(wfConfig::get('other_pwStrengthOnUpdate')){
|
2685 |
$oldDat = get_userdata($userID);
|
2686 |
if($newDat->user_pass != $oldDat->user_pass){
|
2687 |
-
$wf = new wfScanEngine();
|
2688 |
$wf->scanUserPassword($userID);
|
2689 |
$wf->emailNewIssues();
|
2690 |
}
|
@@ -2709,16 +2934,16 @@ EOL;
|
|
2709 |
if( $approved == 1 && (! is_user_logged_in()) && wfConfig::get('other_noAnonMemberComments') ){
|
2710 |
$user = get_user_by('email', trim($cData['comment_author_email']));
|
2711 |
if($user){
|
2712 |
-
wfConfig::inc('totalSpamStopped');
|
2713 |
return 0; //hold for moderation if the user is not signed in but used a members email
|
2714 |
}
|
2715 |
}
|
2716 |
-
|
2717 |
if(($approved == 1 || $approved == 0) && wfConfig::get('other_scanComments')){
|
2718 |
$wf = new wfScanEngine();
|
2719 |
try {
|
2720 |
if($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])){
|
2721 |
-
wfConfig::inc('totalSpamStopped');
|
2722 |
return 'spam';
|
2723 |
}
|
2724 |
} catch(Exception $e){
|
@@ -2733,7 +2958,7 @@ EOL;
|
|
2733 |
preg_replace_callback('/https?:\/\/([a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+[a-zA-Z0-9])/i', 'wordfence::pushCommentSpamHost', $cData['comment_content']);
|
2734 |
$hosts = self::$commentSpamItems;
|
2735 |
self::$commentSpamItems = array();
|
2736 |
-
try {
|
2737 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2738 |
$res = $api->call('advanced_comment_scan', array(), array(
|
2739 |
'author' => $cData['comment_author'],
|
@@ -2745,14 +2970,14 @@ EOL;
|
|
2745 |
'IPs' => (sizeof($IPs) > 0 ? implode(',', $IPs) : '')
|
2746 |
));
|
2747 |
if(is_array($res) && isset($res['spam']) && $res['spam'] == 1){
|
2748 |
-
wfConfig::inc('totalSpamStopped');
|
2749 |
return 'spam';
|
2750 |
}
|
2751 |
} catch(Exception $e){
|
2752 |
//API server is probably down
|
2753 |
}
|
2754 |
}
|
2755 |
-
wfConfig::inc('totalCommentsFiltered');
|
2756 |
return $approved;
|
2757 |
}
|
2758 |
public static function getMyHomeURL(){
|
@@ -2763,7 +2988,7 @@ EOL;
|
|
2763 |
}
|
2764 |
|
2765 |
public static function alert($subject, $alertMsg, $IP){
|
2766 |
-
wfConfig::inc('totalAlertsSent');
|
2767 |
$emails = wfConfig::getAlertEmails();
|
2768 |
if(sizeof($emails) < 1){ return; }
|
2769 |
|
@@ -2782,7 +3007,7 @@ EOL;
|
|
2782 |
}
|
2783 |
$IPMsg .= $userLoc['countryName'] . "\n";
|
2784 |
}
|
2785 |
-
}
|
2786 |
$content = wfUtils::tmpl('email_genericAlert.php', array(
|
2787 |
'isPaid' => wfConfig::get('isPaid'),
|
2788 |
'subject' => $subject,
|
@@ -2825,7 +3050,7 @@ EOL;
|
|
2825 |
}
|
2826 |
}
|
2827 |
}
|
2828 |
-
wfConfig::set('lastEmailHash', time() . ':' . $hash);
|
2829 |
wp_mail(implode(',', $emails), $subject, $content);
|
2830 |
}
|
2831 |
public static function getLog(){
|
@@ -2897,7 +3122,7 @@ EOL;
|
|
2897 |
return self::$debugOn;
|
2898 |
}
|
2899 |
//PUBLIC API
|
2900 |
-
public static function doNotCache(){ //Call this to prevent Wordfence from caching the current page.
|
2901 |
wfCache::doNotCache();
|
2902 |
return true;
|
2903 |
}
|
@@ -2919,5 +3144,34 @@ EOL;
|
|
2919 |
wfConfig::set('whitelisted', implode(',', $arr2));
|
2920 |
return true;
|
2921 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2922 |
}
|
2923 |
?>
|
12 |
require_once('wfConfig.php');
|
13 |
require_once('wfSchema.php');
|
14 |
require_once('wfCache.php');
|
15 |
+
require_once('wfCrypt.php');
|
16 |
+
require_once 'wfView.php';
|
17 |
+
require_once 'wfHelperString.php';
|
18 |
+
require_once 'wfDirectoryIterator.php';
|
19 |
+
require_once 'wfUpdateCheck.php';
|
20 |
+
require_once 'wfActivityReport.php';
|
21 |
+
|
22 |
class wordfence {
|
23 |
public static $printStatus = false;
|
24 |
public static $wordfence_wp_version = false;
|
41 |
update_option('wordfenceActivated', 1);
|
42 |
}
|
43 |
public static function uninstallPlugin(){
|
44 |
+
//Check if caching is enabled and if it is, disable it and fix the .htaccess file.
|
45 |
$cacheType = wfConfig::get('cacheType', false);
|
46 |
if($cacheType == 'falcon'){
|
47 |
wfCache::addHtaccessCode('remove');
|
48 |
wfCache::updateBlockedIPs('remove');
|
49 |
wfConfig::set('cacheType', false);
|
50 |
+
|
51 |
+
//We currently don't clear the cache when plugin is disabled because it will take too long if done synchronously and won't work because plugin is disabled if done asynchronously.
|
52 |
//wfCache::scheduleCacheClear();
|
53 |
} else if($cacheType == 'php'){
|
54 |
wfConfig::set('cacheType', false);
|
55 |
}
|
56 |
+
|
57 |
|
58 |
//Used by MU code below
|
59 |
update_option('wordfenceActivated', 0);
|
60 |
wp_clear_scheduled_hook('wordfence_daily_cron');
|
61 |
wp_clear_scheduled_hook('wordfence_hourly_cron');
|
62 |
wp_clear_scheduled_hook('wordfence_daily_autoUpdate');
|
63 |
+
|
64 |
//Remove old legacy cron job if it exists
|
65 |
wp_clear_scheduled_hook('wordfence_scheduled_scan');
|
66 |
+
|
67 |
//Remove all scheduled scans.
|
68 |
self::unscheduleAllScans();
|
69 |
+
|
70 |
wfConfig::clearDiskCache();
|
71 |
if(wfConfig::get('deleteTablesOnDeact')){
|
72 |
$schema = new wfSchema();
|
120 |
for($i = 0; $i < $len; $i += 4){
|
121 |
list($ipLong) = array_values(unpack('N', substr($resp['data'], $i, 4)));
|
122 |
$IPStr = long2ip($ipLong);
|
123 |
+
if(! self::getLog()->isWhitelisted($IPStr)){
|
124 |
self::getLog()->blockIP($IPStr, $reason, true);
|
125 |
}
|
126 |
}
|
180 |
wordfence::status(4, 'error', "Could not fetch vulnerability patterns in scheduled job: " . $e->getMessage());
|
181 |
}
|
182 |
|
183 |
+
$wfdb->queryWrite("delete from $p"."wfLocs where ctime < unix_timestamp() - %d", WORDFENCE_MAX_IPLOC_AGE);
|
184 |
$wfdb->truncate($p . "wfBadLeechers"); //only uses date that's less than 1 minute old
|
185 |
$wfdb->queryWrite("delete from $p"."wfBlocks where (blockedTime + %s < unix_timestamp()) and permanent=0", wfConfig::get('blockedTime'));
|
186 |
$wfdb->queryWrite("delete from $p"."wfCrawlers where lastUpdate < unix_timestamp() - (86400 * 7)");
|
227 |
$count4 = $wfdb->querySingle("select count(*) as cnt from $p"."wfStatus");
|
228 |
if($count4 > 100000){
|
229 |
$wfdb->truncate($p . "wfStatus");
|
230 |
+
} else if($count4 > 1000){ //max status events we keep. This determines how much gets emailed to us when users sends us a debug report.
|
231 |
$wfdb->queryWrite("delete from $p"."wfStatus where level != 10 order by ctime asc limit %d", ($count4 - 1000));
|
232 |
$count5 = $wfdb->querySingle("select count(*) as cnt from $p"."wfStatus where level=10");
|
233 |
if($count5 > 100){
|
235 |
}
|
236 |
}
|
237 |
|
238 |
+
$report = new wfActivityReport();
|
239 |
+
$report->rotateIPLog();
|
240 |
}
|
241 |
public static function runInstall(){
|
242 |
if(self::$runInstallCalled){ return; }
|
311 |
$db->queryWriteIgnoreError("alter table $prefix"."wfLockedOut modify column blockedTime bigint signed NOT NULL");
|
312 |
$db->queryWriteIgnoreError("drop table if exists $prefix"."wfFileQueue");
|
313 |
$db->queryWriteIgnoreError("drop table if exists $prefix"."wfFileChanges");
|
314 |
+
//Adding primary key to this table because some backup apps use primary key during backup.
|
315 |
$db->queryWriteIgnoreError("alter table wp_wfStatus add id bigint UNSIGNED NOT NULL auto_increment PRIMARY KEY");
|
316 |
|
317 |
$optScanEnabled = $db->querySingle("select val from $prefix"."wfConfig where name='scansEnabled_options'");
|
318 |
if($optScanEnabled != '0' && $optScanEnabled != '1'){
|
319 |
$db->queryWrite("update $prefix"."wfConfig set val='1' where name='scansEnabled_options'");
|
320 |
}
|
321 |
+
|
322 |
$optScanEnabled = $db->querySingle("select val from $prefix"."wfConfig where name='scansEnabled_heartbleed'");
|
323 |
+
if($optScanEnabled != '0' && $optScanEnabled != '1'){ //Enable heartbleed if no value is set.
|
324 |
wfConfig::set('scansEnabled_heartbleed', 1);
|
325 |
}
|
326 |
|
334 |
} else {
|
335 |
$wfLog->logLeechAndBlock('hit');
|
336 |
}
|
337 |
+
if(wfConfig::liveTrafficEnabled()){
|
338 |
self::$hitID = $wfLog->logHit();
|
339 |
add_action('wp_head', 'wordfence::wfLogHumanHeader');
|
340 |
}
|
385 |
add_action('wp_ajax_wordfence_logHuman', 'wordfence::ajax_logHuman_callback');
|
386 |
add_action('wp_ajax_wordfence_doScan', 'wordfence::ajax_doScan_callback');
|
387 |
add_action('wp_ajax_wordfence_testAjax', 'wordfence::ajax_testAjax_callback');
|
|
|
|
|
|
|
388 |
|
389 |
+
add_action('wp_dashboard_setup', 'wordfence::addDashboardWidget');
|
390 |
}
|
391 |
|
392 |
|
398 |
add_action('init', 'wordfence::initAction');
|
399 |
add_action('template_redirect', 'wordfence::templateRedir');
|
400 |
add_action('shutdown', 'wordfence::shutdownAction');
|
401 |
+
|
402 |
if(version_compare(PHP_VERSION, '5.4.0') >= 0){
|
403 |
add_action('wp_authenticate','wordfence::authActionNew', 1, 2);
|
404 |
} else {
|
418 |
add_action('publish_future_post', 'wordfence::publishFuturePost');
|
419 |
add_action('mobile_setup', 'wordfence::jetpackMobileSetup'); //Action called in Jetpack Mobile Theme: modules/minileven/minileven.php
|
420 |
|
421 |
+
// Add actions for the email summary
|
422 |
+
add_action('wordfence_email_activity_report', array('wfActivityReport', 'executeCronJob'));
|
423 |
+
|
424 |
//For debugging
|
425 |
//add_filter( 'cron_schedules', 'wordfence::cronAddSchedules' );
|
426 |
+
|
427 |
add_filter('wp_redirect', 'wordfence::wpRedirectFilter', 99, 2);
|
428 |
add_filter('pre_comment_approved', 'wordfence::preCommentApprovedFilter', '99', 2);
|
429 |
//html|xhtml|atom|rss2|rdf|comment|export
|
470 |
}
|
471 |
*/
|
472 |
public static function jetpackMobileSetup(){
|
473 |
+
define('WFDONOTCACHE', true); //Don't cache jetpack mobile theme pages.
|
474 |
}
|
475 |
public static function wpRedirectFilter($URL, $status){
|
476 |
if(isset($_GET['author']) && preg_match('/\/author\/.+/i', $URL) && wfConfig::get('loginSec_disableAuthorScan') ){ //author query variable is present and we're about to redirect to a URL that starts with http://blah/author/...
|
501 |
}
|
502 |
$UA = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
503 |
$URL = $_POST['URL'];
|
504 |
+
$wfLog->logPerf(wfUtils::getIP(), $UA, $URL, $data);
|
505 |
+
die(json_encode(array('ok' => 1)));
|
506 |
}
|
507 |
public static function ajax_logHuman_callback(){
|
508 |
$browscap = new wfBrowscap();
|
516 |
}
|
517 |
|
518 |
@ob_end_clean();
|
519 |
+
if(! headers_sent()){
|
520 |
header('Content-type: text/javascript');
|
521 |
header("Connection: close");
|
522 |
header("Content-Length: 0");
|
538 |
}
|
539 |
$func = (isset($_POST['action']) && $_POST['action']) ? $_POST['action'] : $_GET['action'];
|
540 |
$nonce = (isset($_POST['nonce']) && $_POST['nonce']) ? $_POST['nonce'] : $_GET['nonce'];
|
541 |
+
if(! wp_verify_nonce($nonce, 'wp-ajax')){
|
542 |
die(json_encode(array('errorMsg' => "Your browser sent an invalid security token to Wordfence. Please try reloading this page or signing out and in again.")));
|
543 |
}
|
544 |
//func is e.g. wordfence_ticker so need to munge it
|
547 |
if($returnArr === false){
|
548 |
$returnArr = array('errorMsg' => "Wordfence encountered an internal error executing that request.");
|
549 |
}
|
550 |
+
|
551 |
if(! is_array($returnArr)){
|
552 |
error_log("Function " . wp_kses($func, array()) . " did not return an array and did not generate an error.");
|
553 |
$returnArr = array();
|
594 |
return $errors;
|
595 |
}
|
596 |
public static function isStrongPasswd($passwd, $username ) {
|
597 |
+
$strength = 0;
|
598 |
if(strlen( trim( $passwd ) ) < 5)
|
599 |
return false;
|
600 |
if(strtolower( $passwd ) == strtolower( $username ) )
|
611 |
$strength += 26;
|
612 |
if ($num = preg_match_all( "/[^a-zA-Z0-9]/", $passwd, $matches)){
|
613 |
$strength += (31 * (int)$num);
|
614 |
+
|
615 |
}
|
616 |
if($strength > 60){
|
617 |
return true;
|
757 |
public static function loginAction($username){
|
758 |
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
|
759 |
if(! $username){ return; }
|
760 |
+
wfConfig::inc('totalLogins');
|
761 |
$user = get_user_by('login', $username);
|
762 |
$userID = $user ? $user->ID : 0;
|
763 |
self::getLog()->logLogin('loginOK', 0, $username);
|
773 |
}
|
774 |
|
775 |
if(user_can($userID, 'update_core')){
|
776 |
+
if(wfConfig::get('alertOn_adminLogin')){
|
777 |
wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
|
778 |
}
|
779 |
} else {
|
790 |
}
|
791 |
public static function authenticateFilter($authUser, $username, $passwd){
|
792 |
wfConfig::inc('totalLoginHits'); //The total hits to wp-login.php including logins, logouts and just hits.
|
793 |
+
$IP = wfUtils::getIP();
|
794 |
$secEnabled = wfConfig::get('loginSecurityEnabled');
|
795 |
if($secEnabled && (! self::getLog()->isWhitelisted($IP)) && wfConfig::get('isPaid') ){
|
796 |
$twoFactorUsers = wfConfig::get_ser('twoFactorUsers', array());
|
797 |
if(isset($twoFactorUsers) && is_array($twoFactorUsers) && sizeof($twoFactorUsers) > 0){
|
798 |
$userDat = (isset($_POST['wordfence_userDat']) ? $_POST['wordfence_userDat'] : false);
|
799 |
+
if(is_object($userDat) && get_class($authUser) == 'WP_User'){ //Valid username and password either with or without the 'wf...' code. Users is now logged in at this point.
|
800 |
if(isset($_POST['wordfence_authFactor']) && $_POST['wordfence_authFactor']){ //user entered a valid user and password with ' wf....' appended
|
801 |
foreach($twoFactorUsers as &$t){
|
802 |
if($t[0] == $userDat->ID && $t[3] == 'activated'){
|
803 |
if($_POST['wordfence_authFactor'] == $t[2] && $t[4] > time()){
|
804 |
+
//Do nothing and allow user to sign in. Their passwd has already been modified to be the passwd without the code.
|
805 |
} else if($_POST['wordfence_authFactor'] == $t[2]){
|
806 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
807 |
$codeResult = $api->call('twoFactor_verification', array(), array('phone' => $t[1]) );
|
816 |
} else {
|
817 |
break; //No new code was received. Let them sign in with the expired code.
|
818 |
}
|
819 |
+
} else { //Bad code, so cancel the login and return an error to user.
|
820 |
return new WP_Error( 'twofactor_required', __( '<strong>INVALID CODE</strong>: You need to enter your password followed by a space and the code we sent to your phone. The code should start with \'wf\' and should be four characters. e.g. wfAB12. In this case you would enter your password as: \'mypassword wfAB12\' without quotes.'));
|
821 |
}
|
822 |
} //No user matches and has TF activated so let user sign in.
|
835 |
$t[4] = time() + 1800; //30 minutes until code expires
|
836 |
wfConfig::set_ser('twoFactorUsers', $twoFactorUsers); //save the code the user needs to enter and return an error.
|
837 |
return new WP_Error( 'twofactor_required', __( '<strong>CHECK YOUR PHONE</strong>: A code has been sent to your phone and will arrive within 30 seconds. Please sign in again and add a space and the code to the end of your password.' ) );
|
838 |
+
} else { //oops, our API returned an error.
|
839 |
break; //Let them sign in without two factor because the API is broken and we don't want to lock users out of their own systems.
|
840 |
}
|
841 |
} //User is not present in two factor list or is not activated. Sign in without twofactor.
|
852 |
if($maxBlockTime = self::wfsnIsBlocked($IP, 'brute')){
|
853 |
self::getLog()->blockIP($IP, "Blocked by Wordfence Security Network", true, false, $maxBlockTime);
|
854 |
}
|
855 |
+
|
856 |
}
|
857 |
if($secEnabled){
|
858 |
if(is_wp_error($authUser) && $authUser->get_error_code() == 'invalid_username'){
|
893 |
}
|
894 |
if(is_wp_error($authUser)){
|
895 |
if($authUser->get_error_code() == 'invalid_username'){
|
896 |
+
self::getLog()->logLogin('loginFailInvalidUsername', 1, $username);
|
897 |
} else {
|
898 |
+
self::getLog()->logLogin('loginFailValidUsername', 1, $username);
|
899 |
}
|
900 |
}
|
901 |
|
958 |
$userID = get_current_user_id();
|
959 |
$userDat = get_user_by('id', $userID);
|
960 |
if(is_object($userDat)){
|
961 |
+
self::getLog()->logLogin('logout', 0, $userDat->user_login);
|
962 |
}
|
963 |
}
|
964 |
public static function loginInitAction(){
|
970 |
if(self::isLockedOut(wfUtils::getIP())){
|
971 |
require('wfLockedOut.php');
|
972 |
}
|
973 |
+
if(! $username){ return; }
|
974 |
$userDat = get_user_by('login', $username);
|
975 |
$_POST['wordfence_userDat'] = $userDat;
|
976 |
+
if(preg_match(self::$passwordCodePattern, $passwd, $matches)){
|
977 |
$_POST['wordfence_authFactor'] = $matches[1];
|
978 |
$passwd = preg_replace('/^(.+)\s+(wf[a-z0-9]+)$/i', '$1', $passwd);
|
979 |
$_POST['pwd'] = $passwd;
|
983 |
if(self::isLockedOut(wfUtils::getIP())){
|
984 |
require('wfLockedOut.php');
|
985 |
}
|
986 |
+
if(! $username){ return; }
|
987 |
$userDat = get_user_by('login', $username);
|
988 |
$_POST['wordfence_userDat'] = $userDat;
|
989 |
+
if(preg_match(self::$passwordCodePattern, $passwd, $matches)){
|
990 |
$_POST['wordfence_authFactor'] = $matches[1];
|
991 |
$passwd = preg_replace('/^(.+)\s+(wf[a-z0-9]+)$/i', '$1', $passwd);
|
992 |
$_POST['pwd'] = $passwd;
|
1178 |
$nextTime = self::getNextScanStartTime();
|
1179 |
return array(
|
1180 |
'ok' => 1,
|
1181 |
+
'nextStart' => ($nextTime ? $nextTime : '')
|
1182 |
);
|
1183 |
}
|
1184 |
public static function getNextScanStartTime(){
|
1185 |
$nextTime = false;
|
1186 |
+
$cron = _get_cron_array();
|
1187 |
foreach($cron as $key => $val){
|
1188 |
if(isset($val['wordfence_start_scheduled_scan'])){
|
1189 |
$nextTime = $key;
|
1193 |
return ($nextTime ? date('l jS \of F Y H:i:s A', $nextTime + (3600 * get_option('gmt_offset'))) : '');
|
1194 |
}
|
1195 |
public static function wordfenceStartScheduledScan(){
|
1196 |
+
|
1197 |
//If scheduled scans are not enabled in the global config option, then don't run a scheduled scan.
|
1198 |
if(wfConfig::get('scheduledScansEnabled') != '1'){
|
1199 |
return;
|
1208 |
}
|
1209 |
wfConfig::set('lastScheduledScanStart', time());
|
1210 |
wordfence::status(1, 'info', "Scheduled Wordfence scan starting at " . date('l jS \of F Y h:i:s A', current_time('timestamp')) );
|
1211 |
+
|
1212 |
//We call this before the scan actually starts to advance the schedule for the next week.
|
1213 |
//This ensures that if the scan crashes for some reason, the schedule will hold.
|
1214 |
wordfence::scheduleScans();
|
1220 |
$sched = wfConfig::get_ser('scanSched', array());
|
1221 |
$mode = wfConfig::get('schedMode');
|
1222 |
if($mode == 'manual' && is_array($sched) && is_array($sched[0]) ){
|
1223 |
+
//Use sched as it is
|
1224 |
} else { //Default to setting scans to run once a day at a randomly selected time.
|
1225 |
$sched = array();
|
1226 |
$runAt = rand(0,23);
|
1293 |
$content .= date(DATE_RFC822, $r['ctime'] + $timeOffset) . '::' . sprintf('%.4f', $r['ctime']) . ':' . $r['level'] . ':' . $r['type'] . '::' . wp_kses_data( (string) $r['msg']) . "\n";
|
1294 |
}
|
1295 |
$content .= "\n\n";
|
1296 |
+
|
1297 |
ob_start();
|
1298 |
phpinfo();
|
1299 |
$phpinfo = ob_get_contents();
|
1300 |
ob_get_clean();
|
1301 |
|
1302 |
$content .= $phpinfo;
|
1303 |
+
|
1304 |
+
wp_mail($_POST['email'], "Wordfence Activity Log", $content);
|
1305 |
return array('ok' => 1);
|
1306 |
}
|
1307 |
public static function ajax_startTourAgain_callback(){
|
1315 |
if($keyData['ok'] && $keyData['apiKey']){
|
1316 |
wfConfig::set('apiKey', $keyData['apiKey']);
|
1317 |
wfConfig::set('isPaid', 0);
|
1318 |
+
//When downgrading we must disable all two factor authentication because it can lock an admin out if we don't.
|
1319 |
wfConfig::set_ser('twoFactorUsers', array());
|
1320 |
} else {
|
1321 |
throw new Exception("Could not understand the response we received from the Wordfence servers when applying for a free API key.");
|
1358 |
public static function disablePermalinksFilter($newVal, $oldVal){
|
1359 |
if(wfConfig::get('cacheType', false) == 'falcon' && $oldVal && (! $newVal) ){ //Falcon is enabled and admin is disabling permalinks
|
1360 |
wfCache::addHtaccessCode('remove');
|
1361 |
+
//if($err){ return $oldVal; } //We might want to not allow the user to disable permalinks if we can't disable falcon. Allowing it for now.
|
1362 |
wfCache::updateBlockedIPs('remove');
|
1363 |
+
//if($err){ return $oldVal; } //We might want to not allow the user to disable permalinks if we can't disable falcon. Allowing it for now.
|
1364 |
wfConfig::set('cacheType', false);
|
1365 |
}
|
1366 |
return $newVal;
|
1457 |
return array('ok' => 1, 'heading' => "Could not write to cache directory", 'body' => "To enable caching, Wordfence needs to be able to create and write to the /wp-content/wfcache/ directory. We did some tests that indicate this is not possible. You need to manually create the /wp-content/wfcache/ directory and make it writable by Wordfence. The error we encountered was during our tests was: $err");
|
1458 |
}
|
1459 |
}
|
1460 |
+
|
1461 |
+
//Mainly we clear the cache here so that any footer cache diagnostic comments are rebuilt. We could just leave it intact unless caching is being disabled.
|
1462 |
if($cacheType != wfConfig::get('cacheType', false)){
|
1463 |
wfCache::scheduleCacheClear();
|
1464 |
}
|
1465 |
+
$htMsg = "";
|
1466 |
if($warnHtaccess){
|
1467 |
$htMsg = " <strong style='color: #F00;'>Warning: We could not remove the caching code from your .htaccess file. you need to remove this manually yourself.</strong> ";
|
1468 |
}
|
1490 |
if($s['files'] == 0){
|
1491 |
return array('ok' => 1, 'heading' => 'Cache Stats', 'body' => "The cache is currently empty. It may be disabled or it may have been recently cleared.");
|
1492 |
}
|
1493 |
+
$body = 'Total files in cache: ' . $s['files'] .
|
1494 |
+
'<br />Total directories in cache: ' . $s['dirs'] .
|
1495 |
'<br />Total data: ' . $s['data'] . 'KB';
|
1496 |
if($s['compressedFiles'] > 0){
|
1497 |
+
$body .= '<br />Files: ' . $s['uncompressedFiles'] .
|
1498 |
'<br />Data: ' . $s['uncompressedKBytes'] . 'KB' .
|
1499 |
'<br />Compressed files: ' . $s['compressedFiles'] .
|
1500 |
'<br />Compressed data: ' . $s['compressedKBytes'] . 'KB';
|
1595 |
}
|
1596 |
$ex = unserialize($ex);
|
1597 |
$rewriteHtaccess = false;
|
1598 |
+
for($i = 0; $i < sizeof($ex); $i++){
|
1599 |
if((string)$ex[$i]['id'] == (string)$id){
|
1600 |
if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)$/', $ex[$i]['pt'])){
|
1601 |
$rewriteHtaccess = true;
|
1718 |
if(sizeof($validIPs) > 0){
|
1719 |
$opts['liveTraf_ignoreIPs'] = implode(',', $validIPs);
|
1720 |
}
|
1721 |
+
|
1722 |
if(preg_match('/[a-zA-Z0-9\d]+/', $opts['liveTraf_ignoreUA'])){
|
1723 |
$opts['liveTraf_ignoreUA'] = trim($opts['liveTraf_ignoreUA']);
|
1724 |
} else {
|
1725 |
$opts['liveTraf_ignoreUA'] = '';
|
1726 |
}
|
1727 |
+
if(! $opts['other_WFNet']){
|
1728 |
$wfdb = new wfDB();
|
1729 |
global $wpdb;
|
1730 |
$p = $wpdb->base_prefix;
|
1752 |
} else if($opts['autoUpdate'] == '0'){
|
1753 |
wfConfig::disableAutoUpdate();
|
1754 |
}
|
1755 |
+
|
1756 |
try {
|
1757 |
if ($opts['disableCodeExecutionUploads']) {
|
1758 |
wfConfig::disableCodeExecutionForUploads();
|
1762 |
} catch (wfConfigException $e) {
|
1763 |
return array('errorMsg' => $e->getMessage());
|
1764 |
}
|
1765 |
+
|
1766 |
+
if (!empty($opts['email_summary_enabled'])) {
|
1767 |
+
wfConfig::set('email_summary_enabled', 1);
|
1768 |
+
wfConfig::set('email_summary_interval', $opts['email_summary_interval']);
|
1769 |
+
wfConfig::set('email_summary_excluded_directories', $opts['email_summary_excluded_directories']);
|
1770 |
+
wfActivityReport::scheduleCronJob();
|
1771 |
+
} else {
|
1772 |
+
wfConfig::set('email_summary_enabled', 0);
|
1773 |
+
wfActivityReport::disableCronJob();
|
1774 |
+
}
|
1775 |
+
|
1776 |
|
1777 |
$paidKeyMsg = false;
|
1778 |
|
1818 |
$op = $_POST['op'];
|
1819 |
$wfLog = self::getLog();
|
1820 |
if($op == 'blocked'){
|
1821 |
+
wordfence::status(1, 'info', "Ajax request received to unblock All IP's including permanent blocks.");
|
1822 |
$wfLog->unblockAllIPs();
|
1823 |
} else if($op == 'locked'){
|
1824 |
$wfLog->unlockAllIPs();
|
1918 |
if(self::getLog()->isWhitelisted($IP)){
|
1919 |
return array('err' => 1, 'errorMsg' => "The IP address " . wp_kses($IP, array()) . " is whitelisted and can't be blocked or it is in a range of internal IP addresses that Wordfence does not block. You can remove this IP from the whitelist on the Wordfence options page.");
|
1920 |
}
|
1921 |
+
if(wfConfig::get('neverBlockBG') != 'treatAsOtherCrawlers'){ //Either neverBlockVerified or neverBlockUA is selected which means the user doesn't want to block google
|
1922 |
if(wfCrawl::verifyCrawlerPTR('/\.googlebot\.com$/i', $IP)){
|
1923 |
return array('err' => 1, 'errorMsg' => "The IP address you're trying to block belongs to Google. Your options are currently set to not block these crawlers. Change this in Wordfence options if you want to manually block Google.");
|
1924 |
}
|
1944 |
$op = $_POST['op'];
|
1945 |
$i = new wfIssues();
|
1946 |
if($op == 'deleteIgnored'){
|
1947 |
+
$i->deleteIgnored();
|
1948 |
} else if($op == 'deleteNew'){
|
1949 |
$i->deleteNew();
|
1950 |
} else if($op == 'ignoreAllNew'){
|
2042 |
$errors = array();
|
2043 |
$issues = new wfIssues();
|
2044 |
foreach($ids as $id){
|
2045 |
+
$id = intval($id); //Make sure input is a number.
|
2046 |
$issue = $issues->getIssueByID($id);
|
2047 |
if(! $issue){
|
2048 |
$errors[] = "Could not delete one of the files because we could not find the issue. Perhaps it's been resolved?";
|
2064 |
$errors[] = "Could not delete file " . wp_kses($file, array()) . ". Error was: " . wp_kses($err['message'], array());
|
2065 |
}
|
2066 |
} else if($op == 'repair'){
|
2067 |
+
$dat = $issue['data'];
|
2068 |
$result = self::getWPFileContent($dat['file'], $dat['cType'], $dat['cName'], $dat['cVersion']);
|
2069 |
if($result['cerrorMsg']){
|
2070 |
$errors[] = $result['cerrorMsg'];
|
2073 |
$errors[] = "We could not get the original file of " . wp_kses($file, array()) . " to do a repair.";
|
2074 |
continue;
|
2075 |
}
|
2076 |
+
|
2077 |
if(preg_match('/\.\./', $file)){
|
2078 |
$errors[] = "An invalid file " . wp_kses($file, array()) . " was specified for repair.";
|
2079 |
continue;
|
2157 |
if(! $issue){
|
2158 |
return array('cerrorMsg' => "We could not find that issue in our database.");
|
2159 |
}
|
2160 |
+
$dat = $issue['data'];
|
2161 |
$result = self::getWPFileContent($dat['file'], $dat['cType'], (isset($dat['cName']) ? $dat['cName'] : ''), (isset($dat['cVersion']) ? $dat['cVersion'] : ''));
|
2162 |
$file = $dat['file'];
|
2163 |
if(isset($result['cerrorMsg']) && $result['cerrorMsg']){
|
2165 |
} else if(! $result['fileContent']){
|
2166 |
return array('cerrorMsg' => "We could not get the original file to do a repair.");
|
2167 |
}
|
2168 |
+
|
2169 |
if(preg_match('/\.\./', $file)){
|
2170 |
return array('cerrorMsg' => "An invalid file was specified for repair.");
|
2171 |
}
|
2223 |
throw new Exception("Invalid response: " . var_export($res, true));
|
2224 |
}
|
2225 |
} catch(Exception $e){
|
2226 |
+
return array('err' => "An error occurred: " . $e->getMessage());
|
2227 |
}
|
2228 |
}
|
2229 |
public static function importSettings($token){
|
2250 |
} else {
|
2251 |
throw new Exception("Invalid response from Wordfence servers during import.");
|
2252 |
}
|
2253 |
+
}
|
2254 |
+
public static function ajax_startPasswdAudit_callback(){
|
2255 |
+
if(! wfAPI::SSLEnabled()){
|
2256 |
+
return array('errorMsg' => "Your server does not support SSL via cURL. To use this feature you need to make sure you have the PHP cURL library installed and enabled and have openSSL enabled so that you can communicate securely with our servers. This ensures that your password hashes remain secure and are double-encrypted when this feature is used. To fix this, please contact your hosting provider or site admin and ask him or her to install and enable cURL and openssl.");
|
2257 |
+
}
|
2258 |
+
if(! function_exists('openssl_public_encrypt')){
|
2259 |
+
return array('errorMsg' => "Your server does not have openssl installed. Specifically we require the openssl_public_encrypt() function to use this feature. Please ask your site admin or hosting provider to install 'openssl' and the openssl PHP libraries. We use these for public key encryption to securely send your password hashes to our server for auditing.");
|
2260 |
+
}
|
2261 |
+
global $wpdb; $p = $wpdb->base_prefix;
|
2262 |
+
$email = $_POST['emailAddr'];
|
2263 |
+
if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
|
2264 |
+
return array(
|
2265 |
+
'errorMsg' => "Please enter a valid email address.",
|
2266 |
+
);
|
2267 |
+
}
|
2268 |
+
$auditType = $_POST['auditType'];
|
2269 |
+
$symKey = wfCrypt::makeSymHexKey(32); #hex digits which is 128 bits
|
2270 |
+
$wfdb = new wfDB();
|
2271 |
+
$q1 = $wfdb->querySelect("select ID, AES_ENCRYPT(user_pass, '%s') as crypt_pass from $p"."users", $symKey);
|
2272 |
+
$admins = "";
|
2273 |
+
$users = "";
|
2274 |
+
foreach($q1 as $rec) {
|
2275 |
+
$isAdmin = user_can($rec['ID'], 'manage_options');
|
2276 |
+
if($isAdmin && ($auditType == 'admin' || $auditType == 'both') ) {
|
2277 |
+
$admins .= $rec['ID'] . ':' . base64_encode($rec['crypt_pass']) . '|';
|
2278 |
+
} else if($auditType == 'user' || $auditType == 'both') {
|
2279 |
+
$users .= $rec['ID'] . ':' . base64_encode($rec['crypt_pass']) . '|';
|
2280 |
+
}
|
2281 |
+
|
2282 |
+
}
|
2283 |
+
$admins = rtrim($admins,'|');
|
2284 |
+
$users = rtrim($users,'|');
|
2285 |
+
//error_log($admins);
|
2286 |
+
//error_log($users);
|
2287 |
+
|
2288 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2289 |
+
try {
|
2290 |
+
$res = $api->call('password_audit', array(), array(
|
2291 |
+
'auditType' => $auditType,
|
2292 |
+
'email' => $email,
|
2293 |
+
'pubCryptSymKey' => wfCrypt::pubCrypt($symKey),
|
2294 |
+
'users' => $users,
|
2295 |
+
'admins' => $admins
|
2296 |
+
), true); //Force SSL
|
2297 |
+
if(is_array($res)){
|
2298 |
+
if(isset($res['ok']) && $res['ok'] == '1'){
|
2299 |
+
return array(
|
2300 |
+
'ok' => 1
|
2301 |
+
);
|
2302 |
+
} else if(isset($res['notPaid']) && $res['notPaid'] == '1'){
|
2303 |
+
return array(
|
2304 |
+
'errorMsg' => "You are not using a Premium version of Wordfence. This feature is available to Premium Wordfence members only.",
|
2305 |
+
);
|
2306 |
+
} else if(isset($res['tooManyJobs']) && $res['tooManyJobs'] == '1'){
|
2307 |
+
return array(
|
2308 |
+
'errorMsg' => "You already have a password audit running. Please wait until it finishes before starting another.",
|
2309 |
+
);
|
2310 |
+
} else {
|
2311 |
+
throw new Exception("An unrecognized response was received from the Wordfence servers.");
|
2312 |
+
}
|
2313 |
+
} else {
|
2314 |
+
return array(
|
2315 |
+
'errorMsg' => "We received an invalid response when trying to submit your password audit.",
|
2316 |
+
);
|
2317 |
+
}
|
2318 |
+
} catch(Exception $e){
|
2319 |
+
return array(
|
2320 |
+
'errMsg' => "We could not submit your password audit: " . $e,
|
2321 |
+
);
|
2322 |
+
}
|
2323 |
+
}
|
2324 |
+
public static function ajax_weakPasswordsFix_callback(){
|
2325 |
+
$mode = $_POST['mode'];
|
2326 |
+
$ids = explode(',', $_POST['ids']);
|
2327 |
+
$homeURL = home_url();
|
2328 |
+
$count = 0;
|
2329 |
+
if($mode == 'fix'){
|
2330 |
+
foreach($ids as $userID){
|
2331 |
+
$user = get_user_by('id', $userID);
|
2332 |
+
if($user){
|
2333 |
+
$passwd = wp_generate_password();
|
2334 |
+
$count++;
|
2335 |
+
wp_set_password($passwd, $userID);
|
2336 |
+
wp_mail($user->user_email, "Your Password on $homeURL Has Been Changed.", wfUtils::tmpl('email_passwdChanged.php', array(
|
2337 |
+
'siteURL' => site_url(),
|
2338 |
+
'homeURL' => home_url(),
|
2339 |
+
'loginURL' => wp_login_url(),
|
2340 |
+
'username' => $user->user_login,
|
2341 |
+
'passwd' => $passwd,
|
2342 |
+
)));
|
2343 |
+
}
|
2344 |
+
}
|
2345 |
+
return array(
|
2346 |
+
'ok' => 1,
|
2347 |
+
'title' => "Fixed $count Weak Passwords",
|
2348 |
+
'msg' => "We created new passwords for $count site members and emailed them the new password with instructions."
|
2349 |
+
);
|
2350 |
+
|
2351 |
+
} else if($mode == 'email'){
|
2352 |
+
foreach($ids as $userID){
|
2353 |
+
$user = get_user_by('id', $userID);
|
2354 |
+
if($user){
|
2355 |
+
$count++;
|
2356 |
+
wp_mail($user->user_email, "Please Change Your Password on $homeURL", wfUtils::tmpl('email_pleaseChangePasswd.php', array(
|
2357 |
+
'siteURL' => site_url(),
|
2358 |
+
'homeURL' => home_url(),
|
2359 |
+
'username' => $user->user_login,
|
2360 |
+
'loginURL' => wp_login_url()
|
2361 |
+
)));
|
2362 |
+
}
|
2363 |
+
}
|
2364 |
+
return array(
|
2365 |
+
'ok' => 1,
|
2366 |
+
'title' => "Notified $count Users",
|
2367 |
+
'msg' => "We sent an email to $count site members letting them know that they have a weak password and suggesting that they sign in and change their password to a stronger one."
|
2368 |
+
);
|
2369 |
+
}
|
2370 |
+
}
|
2371 |
+
public static function ajax_passwdLoadResults_callback(){
|
2372 |
+
if(! wfAPI::SSLEnabled()){ return array('ok' => 1); } //If user hits start passwd audit they will get a helpful message. We don't want an error popping up for every ajax call if SSL is not supported.
|
2373 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2374 |
+
try {
|
2375 |
+
$res = $api->call('password_load_results', array(), array(), true);
|
2376 |
+
} catch(Exception $e){
|
2377 |
+
return array('errorMsg' => "Could not load password audit results: " . $e);
|
2378 |
+
}
|
2379 |
+
$finalResults = array();
|
2380 |
+
if(is_array($res) && $res['ok']){
|
2381 |
+
if(is_array($res['results'])){
|
2382 |
+
for($i = 0; $i < sizeof($res['results']); $i++){
|
2383 |
+
//$meta = get_user_meta($res['results'][$i]['userID'], 'wp_capabilities', true);
|
2384 |
+
//$res['results'][$i]['isAdmin'] = (isset($meta['administrator']) && $meta['administrator']) ? '1' : '';
|
2385 |
+
$user = new WP_User($res['results'][$i]['wpUserID']);
|
2386 |
+
if(is_object($user)){
|
2387 |
+
$passMD5 = strtoupper(md5($user->user_pass));
|
2388 |
+
if($passMD5 != $res['results'][$i]['hashMD5']){ //Password has changed, so exclude this result
|
2389 |
+
continue;
|
2390 |
+
}
|
2391 |
+
$item = $res['results'][$i];
|
2392 |
+
$item['username'] = $user->user_login;
|
2393 |
+
$item['email'] = $user->user_email;
|
2394 |
+
$item['firstName'] = $user->first_name;
|
2395 |
+
$item['lastName'] = $user->last_name;
|
2396 |
+
$item['starredPassword'] = $res['results'][$i]['pwFirstLetter'] . str_repeat('*', $res['results'][$i]['pwLength'] - 1);
|
2397 |
+
//crackTime and crackDifficulty are fields too.
|
2398 |
+
$finalResults[] = $item;
|
2399 |
+
}
|
2400 |
+
}
|
2401 |
+
}
|
2402 |
+
|
2403 |
+
return array(
|
2404 |
+
'ok' => 1,
|
2405 |
+
'results' => $finalResults,
|
2406 |
+
);
|
2407 |
+
} else {
|
2408 |
+
return array('ok' => 1); //fail silently
|
2409 |
+
}
|
2410 |
}
|
2411 |
+
public static function ajax_passwdLoadJobs_callback(){
|
2412 |
+
if(! wfAPI::SSLEnabled()){ return array('ok' => 1); } //If user hits start passwd audit they will get a helpful message. We don't want an error popping up for every ajax call if SSL is not supported.
|
2413 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2414 |
+
try {
|
2415 |
+
$res = $api->call('password_load_jobs', array(), array(), true);
|
2416 |
+
} catch(Exception $e){
|
2417 |
+
return array('errorMsg' => "Could not load password audit jobs: " . $e);
|
2418 |
+
}
|
2419 |
+
if(is_array($res) && $res['ok']){
|
2420 |
+
return array(
|
2421 |
+
'ok' => 1,
|
2422 |
+
'results' => $res['results'],
|
2423 |
+
);
|
2424 |
+
} else {
|
2425 |
+
return array('ok' => 1); //fail silently
|
2426 |
+
}
|
2427 |
+
}
|
2428 |
+
public static function ajax_killPasswdAudit_callback(){
|
2429 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2430 |
+
try {
|
2431 |
+
$res = $api->call('password_kill_job', array(), array( 'jobID' => $_POST['jobID'] ), true);
|
2432 |
+
} catch(Exception $e){
|
2433 |
+
return array('errorMsg' => "Could not stop requested audit: " . $e);
|
2434 |
+
}
|
2435 |
+
if(is_array($res) && $res['ok']){
|
2436 |
+
return array(
|
2437 |
+
'ok' => 1,
|
2438 |
+
);
|
2439 |
+
} else {
|
2440 |
+
return array('errorMsg' => "We could not stop the requested password audit."); //fail silently
|
2441 |
+
}
|
2442 |
+
}
|
2443 |
+
public static function ajax_deletePasswdAudit_callback(){
|
2444 |
+
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2445 |
+
try {
|
2446 |
+
$res = $api->call('password_delete_job', array(), array( 'jobID' => $_POST['jobID']));
|
2447 |
+
} catch(Exception $e){
|
2448 |
+
return array('errorMsg' => "Could not delete the job you specified: " . $e);
|
2449 |
+
}
|
2450 |
+
return array('ok' => 1);
|
2451 |
+
}
|
2452 |
public static function ajax_importSettings_callback(){
|
2453 |
$token = $_POST['token'];
|
2454 |
try {
|
2465 |
wfScanEngine::startScan();
|
2466 |
}
|
2467 |
public static function templateRedir(){
|
2468 |
+
$wfFunc = get_query_var('_wfsf');
|
2469 |
+
|
2470 |
//Logging
|
2471 |
self::doEarlyAccessLogging();
|
2472 |
//End logging
|
2506 |
self::wfFunc_testmem();
|
2507 |
} else if($wfFunc == 'testtime'){
|
2508 |
self::wfFunc_testtime();
|
2509 |
+
}
|
2510 |
exit(0);
|
2511 |
}
|
2512 |
public static function memtest_error_handler($errno, $errstr, $errfile, $errline){
|
2584 |
wfscr.async = true;
|
2585 |
wfscr.src = url;
|
2586 |
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(wfscr);
|
2587 |
+
})('$scriptURL');
|
2588 |
</script>
|
2589 |
EOL;
|
2590 |
}
|
2601 |
wfscr.async = true;
|
2602 |
wfscr.src = url + '&r=' + Math.random();
|
2603 |
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(wfscr);
|
2604 |
+
})('$URL');
|
2605 |
</script>
|
2606 |
EOL;
|
2607 |
}
|
2620 |
$reverseLookup = wfUtils::reverseLookup($IP);
|
2621 |
$wfLog = new wfLog(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2622 |
$results = array_merge(
|
2623 |
+
$wfLog->getHits('hits', 'hit', 0, 10000, $IP),
|
2624 |
$wfLog->getHits('hits', '404', 0, 10000, $IP)
|
2625 |
);
|
2626 |
usort($results, 'wordfence::iptrafsort');
|
2662 |
$fileMTime = @filemtime($localFile);
|
2663 |
$fileMTime = date('l jS \of F Y h:i:s A', $fileMTime);
|
2664 |
try {
|
2665 |
+
if(wfUtils::fileOver2Gigs($localFile)){
|
2666 |
$fileSize = "Greater than 2 Gigs";
|
2667 |
} else {
|
2668 |
$fileSize = @filesize($localFile); //Checked if over 2 gigs above
|
2695 |
} else {
|
2696 |
$diff = new Diff(
|
2697 |
//Treat DOS and Unix files the same
|
2698 |
+
preg_split("/(?:\r\n|\n)/", $result['fileContent']),
|
2699 |
+
preg_split("/(?:\r\n|\n)/", $localContents),
|
2700 |
array()
|
2701 |
);
|
2702 |
$renderer = new Diff_Renderer_Html_SideBySide;
|
2726 |
}
|
2727 |
public static function admin_init(){
|
2728 |
if(! wfUtils::isAdmin()){ return; }
|
2729 |
+
foreach(array('activate', 'scan', 'updateAlertEmail', 'sendActivityLog', 'restoreFile', 'startPasswdAudit', 'deletePasswdAudit', 'weakPasswordsFix', 'passwdLoadResults', 'killPasswdAudit', 'passwdLoadJobs', 'exportSettings', 'importSettings', 'bulkOperation', 'deleteFile', 'removeExclusion', 'activityLogUpdate', 'ticker', 'loadIssues', 'updateIssueStatus', 'deleteIssue', 'updateAllIssues', 'reverseLookup', 'unlockOutIP', 'loadBlockRanges', 'unblockRange', 'blockIPUARange', 'whois', 'unblockIP', 'blockIP', 'permBlockIP', 'loadStaticPanel', 'saveConfig', 'downloadHtaccess', 'checkFalconHtaccess', 'updateConfig', 'saveCacheConfig', 'removeFromCache', 'autoUpdateChoice', 'saveCacheOptions', 'clearPageCache', 'getCacheStats', 'clearAllBlocked', 'killScan', 'saveCountryBlocking', 'saveScanSchedule', 'tourClosed', 'welcomeClosed', 'startTourAgain', 'downgradeLicense', 'addTwoFactor', 'twoFacActivate', 'twoFacDel', 'loadTwoFactor', 'loadAvgSitePerf', 'sendTestEmail', 'addCacheExclusion', 'removeCacheExclusion', 'loadCacheExclusions', 'email_summary_email_address_debug') as $func){
|
2730 |
add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
|
2731 |
}
|
2732 |
|
2831 |
}
|
2832 |
}
|
2833 |
}
|
2834 |
+
|
2835 |
add_submenu_page("Wordfence", "Scan", "Scan", "activate_plugins", "Wordfence", 'wordfence::menu_scan');
|
2836 |
+
add_menu_page('Wordfence', 'Wordfence', 'activate_plugins', 'Wordfence', 'wordfence::menu_scan', wfUtils::getBaseURL() . 'images/wordfence-logo-16x16.png');
|
2837 |
add_submenu_page("Wordfence", "Live Traffic", "Live Traffic", "activate_plugins", "WordfenceActivity", 'wordfence::menu_activity');
|
2838 |
/* add_submenu_page('Wordfence', 'Site Performance', 'Site Performance', 'activate_plugins', 'WordfenceSitePerfStats', 'wordfence::menu_sitePerfStats'); */
|
2839 |
add_submenu_page('Wordfence', 'Performance Setup', 'Performance Setup', 'activate_plugins', 'WordfenceSitePerf', 'wordfence::menu_sitePerf');
|
2840 |
add_submenu_page('Wordfence', 'Blocked IPs', 'Blocked IPs', 'activate_plugins', 'WordfenceBlockedIPs', 'wordfence::menu_blockedIPs');
|
2841 |
+
add_submenu_page('Wordfence', 'Password Audit', 'Password Audit', 'activate_plugins', 'WordfencePasswdAudit', 'wordfence::menu_passwd');
|
2842 |
+
|
2843 |
add_submenu_page("Wordfence", "Cellphone Sign-in", "Cellphone Sign-in", "activate_plugins", "WordfenceTwoFactor", 'wordfence::menu_twoFactor');
|
2844 |
add_submenu_page("Wordfence", "Country Blocking", "Country Blocking", "activate_plugins", "WordfenceCountryBlocking", 'wordfence::menu_countryBlocking');
|
2845 |
add_submenu_page("Wordfence", "Scan Schedule", "Scan Schedule", "activate_plugins", "WordfenceScanSchedule", 'wordfence::menu_scanSchedule');
|
2859 |
public static function menu_blockedIPs(){
|
2860 |
require 'menu_blockedIPs.php';
|
2861 |
}
|
2862 |
+
public static function menu_passwd()
|
2863 |
+
{
|
2864 |
+
require 'menu_passwd.php';
|
2865 |
+
}
|
2866 |
public static function menu_scanSchedule(){
|
2867 |
require 'menu_scanSchedule.php';
|
2868 |
}
|
2909 |
if(wfConfig::get('other_pwStrengthOnUpdate')){
|
2910 |
$oldDat = get_userdata($userID);
|
2911 |
if($newDat->user_pass != $oldDat->user_pass){
|
2912 |
+
$wf = new wfScanEngine();
|
2913 |
$wf->scanUserPassword($userID);
|
2914 |
$wf->emailNewIssues();
|
2915 |
}
|
2934 |
if( $approved == 1 && (! is_user_logged_in()) && wfConfig::get('other_noAnonMemberComments') ){
|
2935 |
$user = get_user_by('email', trim($cData['comment_author_email']));
|
2936 |
if($user){
|
2937 |
+
wfConfig::inc('totalSpamStopped');
|
2938 |
return 0; //hold for moderation if the user is not signed in but used a members email
|
2939 |
}
|
2940 |
}
|
2941 |
+
|
2942 |
if(($approved == 1 || $approved == 0) && wfConfig::get('other_scanComments')){
|
2943 |
$wf = new wfScanEngine();
|
2944 |
try {
|
2945 |
if($wf->isBadComment($cData['comment_author'], $cData['comment_author_email'], $cData['comment_author_url'], $cData['comment_author_IP'], $cData['comment_content'])){
|
2946 |
+
wfConfig::inc('totalSpamStopped');
|
2947 |
return 'spam';
|
2948 |
}
|
2949 |
} catch(Exception $e){
|
2958 |
preg_replace_callback('/https?:\/\/([a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+[a-zA-Z0-9])/i', 'wordfence::pushCommentSpamHost', $cData['comment_content']);
|
2959 |
$hosts = self::$commentSpamItems;
|
2960 |
self::$commentSpamItems = array();
|
2961 |
+
try {
|
2962 |
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
|
2963 |
$res = $api->call('advanced_comment_scan', array(), array(
|
2964 |
'author' => $cData['comment_author'],
|
2970 |
'IPs' => (sizeof($IPs) > 0 ? implode(',', $IPs) : '')
|
2971 |
));
|
2972 |
if(is_array($res) && isset($res['spam']) && $res['spam'] == 1){
|
2973 |
+
wfConfig::inc('totalSpamStopped');
|
2974 |
return 'spam';
|
2975 |
}
|
2976 |
} catch(Exception $e){
|
2977 |
//API server is probably down
|
2978 |
}
|
2979 |
}
|
2980 |
+
wfConfig::inc('totalCommentsFiltered');
|
2981 |
return $approved;
|
2982 |
}
|
2983 |
public static function getMyHomeURL(){
|
2988 |
}
|
2989 |
|
2990 |
public static function alert($subject, $alertMsg, $IP){
|
2991 |
+
wfConfig::inc('totalAlertsSent');
|
2992 |
$emails = wfConfig::getAlertEmails();
|
2993 |
if(sizeof($emails) < 1){ return; }
|
2994 |
|
3007 |
}
|
3008 |
$IPMsg .= $userLoc['countryName'] . "\n";
|
3009 |
}
|
3010 |
+
}
|
3011 |
$content = wfUtils::tmpl('email_genericAlert.php', array(
|
3012 |
'isPaid' => wfConfig::get('isPaid'),
|
3013 |
'subject' => $subject,
|
3050 |
}
|
3051 |
}
|
3052 |
}
|
3053 |
+
wfConfig::set('lastEmailHash', time() . ':' . $hash);
|
3054 |
wp_mail(implode(',', $emails), $subject, $content);
|
3055 |
}
|
3056 |
public static function getLog(){
|
3122 |
return self::$debugOn;
|
3123 |
}
|
3124 |
//PUBLIC API
|
3125 |
+
public static function doNotCache(){ //Call this to prevent Wordfence from caching the current page.
|
3126 |
wfCache::doNotCache();
|
3127 |
return true;
|
3128 |
}
|
3144 |
wfConfig::set('whitelisted', implode(',', $arr2));
|
3145 |
return true;
|
3146 |
}
|
3147 |
+
|
3148 |
+
public static function ajax_email_summary_email_address_debug_callback() {
|
3149 |
+
$email = !empty($_REQUEST['email']) ? $_REQUEST['email'] : null;
|
3150 |
+
$report = new wfActivityReport();
|
3151 |
+
return $report->sendReportViaEmail($email) ?
|
3152 |
+
array('ok' => 1, 'result' => 'Test email sent successfully') :
|
3153 |
+
array('err' => "Test email failed to send.");
|
3154 |
+
}
|
3155 |
+
|
3156 |
+
public static function addDashboardWidget() {
|
3157 |
+
if (wfConfig::get('email_summary_dashboard_widget_enabled')) {
|
3158 |
+
wp_enqueue_style('wordfence-activity-report-widget', wfUtils::getBaseURL() . 'css/activity-report-widget.css', '', WORDFENCE_VERSION);
|
3159 |
+
$report_date_range = 'week';
|
3160 |
+
switch (wfConfig::get('email_summary_interval')) {
|
3161 |
+
case 'biweekly':
|
3162 |
+
$report_date_range = '2 weeks';
|
3163 |
+
break;
|
3164 |
+
|
3165 |
+
case 'monthly':
|
3166 |
+
$report_date_range = 'month';
|
3167 |
+
break;
|
3168 |
+
}
|
3169 |
+
wp_add_dashboard_widget(
|
3170 |
+
'wordfence_activity_report_widget',
|
3171 |
+
'Wordfence activity in the past ' . $report_date_range,
|
3172 |
+
array('wfActivityReport', 'outputDashboardWidget')
|
3173 |
+
);
|
3174 |
+
}
|
3175 |
+
}
|
3176 |
}
|
3177 |
?>
|
lib/wordfenceConstants.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
define('WORDFENCE_API_VERSION', '2.
|
3 |
define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
|
4 |
define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
|
5 |
define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
1 |
<?php
|
2 |
+
define('WORDFENCE_API_VERSION', '2.15');
|
3 |
define('WORDFENCE_API_URL_SEC', 'https://noc1.wordfence.com/');
|
4 |
define('WORDFENCE_API_URL_NONSEC', 'http://noc1.wordfence.com/');
|
5 |
define('WORDFENCE_MAX_SCAN_TIME', 86400); //Increased this from 10 mins to 1 day because very big scans run for a long time. Users can use kill.
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: mmaunder
|
|
3 |
Tags: wordpress, security, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm, woocommerce support, woocommerce caching
|
4 |
Requires at least: 3.9
|
5 |
Tested up to: 4.1.1
|
6 |
-
Stable tag: 5.3.
|
7 |
|
8 |
Wordfence Security is a free enterprise class security and performance plugin that makes your site up to 50 times faster and more secure.
|
9 |
|
@@ -165,6 +165,14 @@ cause a security hole on your site.
|
|
165 |
|
166 |
== Changelog ==
|
167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
= 5.3.8 =
|
169 |
* Customers running WP versions older than 3.9 don't support wp_normalize_path(). Added support for older WP versions to fix an error being thrown.
|
170 |
|
@@ -1099,3 +1107,4 @@ Wordfence Security to zero (we simply reuse the WordPress DB handle), reduces th
|
|
1099 |
about 1% of the previous version by removing unneeded status messages and fixes a bug that
|
1100 |
could cause Wordfence Security to launch multiple concurrent scans that can put high load on your system.
|
1101 |
This is a critical release. Upgrade immediately.
|
|
3 |
Tags: wordpress, security, performance, speed, caching, cache, caching plugin, wordpress cache, wordpress caching, wordpress security, security plugin, secure, anti-virus, malware, firewall, antivirus, virus, google safe browsing, phishing, scrapers, hacking, wordfence, securty, secrity, secure, two factor, cellphone sign-in, cellphone signin, cellphone, twofactor, security, secure, htaccess, login, log, users, login alerts, lock, chmod, maintenance, plugin, private, privacy, protection, permissions, 503, base64, injection, code, encode, script, attack, hack, hackers, block, blocked, prevent, prevention, RFI, XSS, CRLF, CSRF, SQL Injection, vulnerability, website security, WordPress security, security log, logging, HTTP log, error log, login security, personal security, infrastructure security, firewall security, front-end security, web server security, proxy security, reverse proxy security, secure website, secure login, two factor security, maximum login security, heartbleed, heart bleed, heartbleed vulnerability, openssl vulnerability, nginx, litespeed, php5-fpm, woocommerce support, woocommerce caching
|
4 |
Requires at least: 3.9
|
5 |
Tested up to: 4.1.1
|
6 |
+
Stable tag: 5.3.9
|
7 |
|
8 |
Wordfence Security is a free enterprise class security and performance plugin that makes your site up to 50 times faster and more secure.
|
9 |
|
165 |
|
166 |
== Changelog ==
|
167 |
|
168 |
+
= 5.3.9 =
|
169 |
+
* Premium Feature: Password Auditing. Audit the strength of your admin and user-level passwords against our GPU based auditing cluster. Easily alert users to weak passwords or force a password change.
|
170 |
+
* Feature: Activity email summary. See options page to enable a weekly, bi-weekly or monthly activity summary.
|
171 |
+
* Feature: Activity summary dashboard widget.
|
172 |
+
* Fix: Fixed bug on plugin activation where the configuration table was being queried before it was created.
|
173 |
+
* Improvement: Added .htaccess to wfcache directory.
|
174 |
+
* Improvement: Switched to using wp_remote_post for Wordfence cloud API calls to improved SSL support and a more standards based approach.
|
175 |
+
|
176 |
= 5.3.8 =
|
177 |
* Customers running WP versions older than 3.9 don't support wp_normalize_path(). Added support for older WP versions to fix an error being thrown.
|
178 |
|
1107 |
about 1% of the previous version by removing unneeded status messages and fixes a bug that
|
1108 |
could cause Wordfence Security to launch multiple concurrent scans that can put high load on your system.
|
1109 |
This is a critical release. Upgrade immediately.
|
1110 |
+
|
views/reports/activity-report-email-inline.php
ADDED
@@ -0,0 +1,330 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var wfActivityReportView $this
|
4 |
+
*/
|
5 |
+
list($start_time, $end_time) = wfActivityReport::getReportDateRange();
|
6 |
+
$title = 'Wordfence activity from<br><strong>' . date_i18n(get_option('date_format'), $start_time) . '</strong> to <strong>' . date_i18n(get_option('date_format'), $end_time) . '</strong>';
|
7 |
+
$bg_colors = array(
|
8 |
+
'even' => 'background-color: #eeeeee;',
|
9 |
+
'odd' => '',
|
10 |
+
);
|
11 |
+
?>
|
12 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
13 |
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
14 |
+
<head>
|
15 |
+
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo get_option('blog_charset') ?>"/>
|
16 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
17 |
+
<title><?php echo esc_html(strip_tags($title)) ?></title>
|
18 |
+
<!-- Targeting Windows Mobile -->
|
19 |
+
<!--[if IEMobile 7]>
|
20 |
+
<style type="text/css">
|
21 |
+
|
22 |
+
</style>
|
23 |
+
<![endif]-->
|
24 |
+
|
25 |
+
<!-- ***********************************************
|
26 |
+
****************************************************
|
27 |
+
END MOBILE TARGETING
|
28 |
+
****************************************************
|
29 |
+
************************************************ -->
|
30 |
+
|
31 |
+
<!--[if gte mso 9]>
|
32 |
+
<style>
|
33 |
+
/* Target Outlook 2007 and 2010 */
|
34 |
+
</style>
|
35 |
+
<![endif]-->
|
36 |
+
</head>
|
37 |
+
<body style="font-size: 10pt; vertical-align: baseline; line-height: 1; font-family: Helvetica, Arial, sans-serif; text-rendering: optimizeLegibility; color: #000; background-image: none !important; width: 100% !important; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; background-color: #e6e6e6; margin: 0; padding: 0; border: 0;" bgcolor="#e6e6e6"><style type="text/css">
|
38 |
+
blockquote:before { content: none !important; }
|
39 |
+
blockquote:after { content: none !important; }
|
40 |
+
q:before { content: none !important; }
|
41 |
+
q:after { content: none !important; }
|
42 |
+
a:focus { outline: thin dotted !important; }
|
43 |
+
.clear:after { clear: both !important; }
|
44 |
+
.wrapper:after { clear: both !important; }
|
45 |
+
.format-status .entry-header:after { clear: both !important; }
|
46 |
+
.clear:before { display: table !important; content: "" !important; }
|
47 |
+
.clear:after { display: table !important; content: "" !important; }
|
48 |
+
.wrapper:before { display: table !important; content: "" !important; }
|
49 |
+
.wrapper:after { display: table !important; content: "" !important; }
|
50 |
+
.format-status .entry-header:before { display: table !important; content: "" !important; }
|
51 |
+
.format-status .entry-header:after { display: table !important; content: "" !important; }
|
52 |
+
.menu-toggle:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
53 |
+
.menu-toggle:focus { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
54 |
+
button:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
55 |
+
input[type="submit"]:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
56 |
+
input[type="button"]:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
57 |
+
input[type="reset"]:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
58 |
+
article.post-password-required input[type=submit]:hover { color: #5e5e5e !important; background-color: #ebebeb !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #f9f9f9, #ebebeb) !important; }
|
59 |
+
.menu-toggle:active { color: #757575 !important; background-color: #e1e1e1 !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #ebebeb, #e1e1e1) !important; box-shadow: inset 0 0 8px 2px #c6c6c6, 0 1px 0 0 #f4f4f4 !important; border-color: transparent !important; }
|
60 |
+
button:active { color: #757575 !important; background-color: #e1e1e1 !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #ebebeb, #e1e1e1) !important; box-shadow: inset 0 0 8px 2px #c6c6c6, 0 1px 0 0 #f4f4f4 !important; border-color: transparent !important; }
|
61 |
+
input[type="submit"]:active { color: #757575 !important; background-color: #e1e1e1 !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #ebebeb, #e1e1e1) !important; box-shadow: inset 0 0 8px 2px #c6c6c6, 0 1px 0 0 #f4f4f4 !important; border-color: transparent !important; }
|
62 |
+
input[type="button"]:active { color: #757575 !important; background-color: #e1e1e1 !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #ebebeb, #e1e1e1) !important; box-shadow: inset 0 0 8px 2px #c6c6c6, 0 1px 0 0 #f4f4f4 !important; border-color: transparent !important; }
|
63 |
+
input[type="reset"]:active { color: #757575 !important; background-color: #e1e1e1 !important; background-repeat: repeat-x !important; background-image: linear-gradient(top, #ebebeb, #e1e1e1) !important; box-shadow: inset 0 0 8px 2px #c6c6c6, 0 1px 0 0 #f4f4f4 !important; border-color: transparent !important; }
|
64 |
+
a:hover { color: #0f3647 !important; }
|
65 |
+
.main-navigation .assistive-text:focus { background: #fff !important; border: 2px solid #333 !important; border-radius: 3px !important; clip: auto !important; color: #000 !important; display: block !important; font-size: 12px !important; padding: 12px !important; position: absolute !important; top: 5px !important; left: 5px !important; z-index: 100000 !important; }
|
66 |
+
.site-header h1 a:hover { color: #21759b !important; }
|
67 |
+
.site-header h2 a:hover { color: #21759b !important; }
|
68 |
+
.main-navigation a:hover { color: #21759b !important; }
|
69 |
+
.main-navigation a:focus { color: #21759b !important; }
|
70 |
+
.widget-area .widget a:hover { color: #21759b !important; }
|
71 |
+
.widget-area .widget a:visited { color: #9f9f9f !important; }
|
72 |
+
footer[role="contentinfo"] a:hover { color: #21759b !important; }
|
73 |
+
.comments-link a:hover { color: #21759b !important; }
|
74 |
+
.entry-meta a:hover { color: #21759b !important; }
|
75 |
+
.entry-content a:visited { color: #9f9f9f !important; }
|
76 |
+
.comment-content a:visited { color: #9f9f9f !important; }
|
77 |
+
article.format-aside h1 a:hover { color: #2e3542 !important; }
|
78 |
+
.format-status .entry-header header a:hover { color: #21759b !important; }
|
79 |
+
.comments-area article header a:hover { color: #21759b !important; }
|
80 |
+
.comments-area article header cite a:hover { text-decoration: underline !important; }
|
81 |
+
a.comment-reply-link:hover { color: #21759b !important; }
|
82 |
+
a.comment-edit-link:hover { color: #21759b !important; }
|
83 |
+
.template-front-page .widget-area .widget li a:hover { color: #21759b !important; }
|
84 |
+
@-ms-viewport { width: device-width !important; }
|
85 |
+
@viewport { width: device-width !important; }
|
86 |
+
.main-navigation li a:hover { color: #000 !important; }
|
87 |
+
.main-navigation li a:focus { color: #000 !important; }
|
88 |
+
.main-navigation ul li:hover > ul { border-left: 0 !important; clip: inherit !important; overflow: inherit !important; height: inherit !important; width: inherit !important; }
|
89 |
+
.main-navigation ul li:focus > ul { border-left: 0 !important; clip: inherit !important; overflow: inherit !important; height: inherit !important; width: inherit !important; }
|
90 |
+
.main-navigation li ul li a:hover { background: #e3e3e3 !important; color: #444 !important; }
|
91 |
+
.main-navigation li ul li a:focus { background: #e3e3e3 !important; color: #444 !important; }
|
92 |
+
footer a[rel=bookmark]:after { content: " [" attr(href) "] " !important; }
|
93 |
+
footer a[rel=bookmark]:visited:after { content: " [" attr(href) "] " !important; }
|
94 |
+
h1 a:active { color: red !important; }
|
95 |
+
h2 a:active { color: red !important; }
|
96 |
+
h3 a:active { color: red !important; }
|
97 |
+
h4 a:active { color: red !important; }
|
98 |
+
h5 a:active { color: red !important; }
|
99 |
+
h6 a:active { color: red !important; }
|
100 |
+
h1 a:visited { color: purple !important; }
|
101 |
+
h2 a:visited { color: purple !important; }
|
102 |
+
h3 a:visited { color: purple !important; }
|
103 |
+
h4 a:visited { color: purple !important; }
|
104 |
+
h5 a:visited { color: purple !important; }
|
105 |
+
h6 a:visited { color: purple !important; }
|
106 |
+
.button:hover { background: none repeat scroll 0 0 #1E8CBE !important; border-color: #0074A2 !important; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.6) inset !important; color: #FFF !important; }
|
107 |
+
.button:active { background: none repeat scroll 0 0 #1E8CBE !important; border-color: #0074A2 !important; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.6) inset !important; color: #FFF !important; }
|
108 |
+
.button:focus { background: none repeat scroll 0 0 #1E8CBE !important; border-color: #0074A2 !important; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.6) inset !important; color: #FFF !important; }
|
109 |
+
</style>
|
110 |
+
<!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. -->
|
111 |
+
<table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" style="font-size: 100%; vertical-align: baseline; border-collapse: collapse; border-spacing: 0; width: 100% !important; line-height: 100% !important; mso-table-lspace: 0pt; mso-table-rspace: 0pt; margin: 0 auto; padding: 0; border: 0;">
|
112 |
+
<tr style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
113 |
+
<td valign="top" style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 0; border: 0;" align="left">
|
114 |
+
<div class="wrapper wp-core-ui" style="font-size: 100%; vertical-align: baseline; border-top-style: none; box-shadow: none; line-height: 1.4; width: 600px; background-color: #FFFFFF; margin: 0 auto; padding: 20px; border: 0;">
|
115 |
+
<div style="float: right; text-align: right; line-height: 1.1; color: #666666; font-size: 100%; vertical-align: baseline; margin: 20px 0 0; padding: 0; border: 0;" align="right">
|
116 |
+
<?php echo $title ?>
|
117 |
+
</div>
|
118 |
+
<a href="http://www.wordfence.com/" style="font-size: 100%; vertical-align: baseline; outline: none; color: orange; text-decoration: none; margin: 0; padding: 0; border: 0;"><img src="http://www.wordfence.com/wp-content/themes/parallelus-salutation/wfCustomHome/images/wordfenceLogo.png" alt="" style="font-size: 100%; vertical-align: baseline; -ms-interpolation-mode: bicubic; outline: none; text-decoration: none; margin: 0; padding: 0; border: 0 none;" /></a>
|
119 |
+
|
120 |
+
<?php if (!wfConfig::get('isPaid')): ?>
|
121 |
+
<p>For access to Premium features like Country Blocking, Password Auditing, Cellphone Sign-in and more, <a href="http://www.wordfence.com/?utm_source=plugin&utm_medium=UI&utm_campaign=summaryEmail">click here to upgrade to Wordfence Premium now</a>.</p>
|
122 |
+
<?php endif ?>
|
123 |
+
|
124 |
+
<h2 style="font-size: 20px; vertical-align: baseline; clear: both; color: #222 !important; margin: 20px 0 4px; padding: 0; border: 0;">
|
125 |
+
Top 10 IP's Blocked
|
126 |
+
</h2>
|
127 |
+
|
128 |
+
<?php wfHelperString::cycle(); ?>
|
129 |
+
|
130 |
+
<table class="activity-table" style="font-size: 100%; vertical-align: baseline; border-collapse: collapse; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; max-width: 100%; margin: 0; padding: 0; border: 0;">
|
131 |
+
<thead style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
132 |
+
<tr style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
133 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">IP</th>
|
134 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Country</th>
|
135 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Block Count</th>
|
136 |
+
</tr>
|
137 |
+
</thead>
|
138 |
+
<tbody style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
139 |
+
<?php if ($top_ips_blocked): ?>
|
140 |
+
<?php foreach ($top_ips_blocked as $row): ?>
|
141 |
+
<?php
|
142 |
+
$stripe = wfHelperString::cycle('odd', 'even');
|
143 |
+
?>
|
144 |
+
<tr class="<?php echo $stripe ?>" style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
145 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><code style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;"><?php echo wfUtils::inet_ntoa($row->IP) ?></code></td>
|
146 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline">
|
147 |
+
<?php if ($row->countryCode): ?>
|
148 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo esc_attr(strtolower($row->countryCode)) ?>.png" class="wfFlag" height="11" width="16" style="font-size: 100%; vertical-align: baseline; -ms-interpolation-mode: bicubic; outline: none; text-decoration: none; margin: 0; padding: 0; border: 0;">
|
149 |
+
|
150 |
+
<?php echo esc_html($row->countryCode) ?>
|
151 |
+
<?php else: ?>
|
152 |
+
(Unknown)
|
153 |
+
<?php endif ?>
|
154 |
+
</td>
|
155 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo (int)$row->blockCount ?></td>
|
156 |
+
</tr>
|
157 |
+
<?php endforeach ?>
|
158 |
+
<?php else: ?>
|
159 |
+
<tr>
|
160 |
+
<td colspan="3">
|
161 |
+
No data currently.
|
162 |
+
</td>
|
163 |
+
</tr>
|
164 |
+
<?php endif ?>
|
165 |
+
</tbody>
|
166 |
+
</table>
|
167 |
+
|
168 |
+
<p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
|
169 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceBlockedIPs') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked IPs</a>
|
170 |
+
</p>
|
171 |
+
|
172 |
+
<?php wfHelperString::cycle(); ?>
|
173 |
+
|
174 |
+
<h2 style="font-size: 20px; vertical-align: baseline; clear: both; color: #222 !important; margin: 20px 0 4px; padding: 0; border: 0;">Top 10 Countries Blocked</h2>
|
175 |
+
|
176 |
+
<table class="activity-table" style="font-size: 100%; vertical-align: baseline; border-collapse: collapse; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; max-width: 100%; margin: 0; padding: 0; border: 0;">
|
177 |
+
<thead style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
178 |
+
<tr style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
179 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Country</th>
|
180 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Total IPs Blocked</th>
|
181 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Block Count</th>
|
182 |
+
</tr>
|
183 |
+
</thead>
|
184 |
+
<tbody style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
185 |
+
<?php if ($top_countries_blocked): ?>
|
186 |
+
<?php foreach ($top_countries_blocked as $row): ?>
|
187 |
+
<?php
|
188 |
+
$stripe = wfHelperString::cycle('odd', 'even');
|
189 |
+
?>
|
190 |
+
<tr class="<?php echo $stripe ?>" style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
191 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline">
|
192 |
+
<?php if ($row->countryCode): ?>
|
193 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo strtolower($row->countryCode) ?>.png" class="wfFlag" height="11" width="16" style="font-size: 100%; vertical-align: baseline; -ms-interpolation-mode: bicubic; outline: none; text-decoration: none; margin: 0; padding: 0; border: 0;">
|
194 |
+
|
195 |
+
<?php echo esc_html($row->countryCode) ?>
|
196 |
+
<?php else: ?>
|
197 |
+
(Unknown)
|
198 |
+
<?php endif ?>
|
199 |
+
</td>
|
200 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo esc_html($row->totalIPs) ?></td>
|
201 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo (int)$row->totalBlockCount ?></td>
|
202 |
+
</tr>
|
203 |
+
<?php endforeach ?>
|
204 |
+
<?php else: ?>
|
205 |
+
<tr>
|
206 |
+
<td colspan="3">
|
207 |
+
No data currently.
|
208 |
+
</td>
|
209 |
+
</tr>
|
210 |
+
<?php endif ?>
|
211 |
+
</tbody>
|
212 |
+
</table>
|
213 |
+
|
214 |
+
<p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
|
215 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceCountryBlocking') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Blocked Countries</a>
|
216 |
+
</p>
|
217 |
+
|
218 |
+
<?php wfHelperString::cycle(); ?>
|
219 |
+
|
220 |
+
<h2 style="font-size: 20px; vertical-align: baseline; clear: both; color: #222 !important; margin: 20px 0 4px; padding: 0; border: 0;">Top 10 Failed Logins</h2>
|
221 |
+
|
222 |
+
<table class="activity-table" style="font-size: 100%; vertical-align: baseline; border-collapse: collapse; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; max-width: 100%; margin: 0; padding: 0; border: 0;">
|
223 |
+
<thead style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
224 |
+
<tr style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
225 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Username</th>
|
226 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Login Attempts</th>
|
227 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Existing User</th>
|
228 |
+
</tr>
|
229 |
+
</thead>
|
230 |
+
<tbody style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
231 |
+
<?php if ($top_failed_logins): ?>
|
232 |
+
<?php foreach ($top_failed_logins as $row): ?>
|
233 |
+
<?php
|
234 |
+
$stripe = wfHelperString::cycle('odd', 'even');
|
235 |
+
?>
|
236 |
+
<tr class="<?php echo $stripe ?>" style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
237 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo esc_html($row->username) ?></td>
|
238 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo esc_html($row->fail_count) ?></td>
|
239 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline" class="<?php echo sanitize_html_class($row->action) ?>"><?php echo $row->action == 'loginFailValidUsername' ? 'Yes' : 'No' ?></td>
|
240 |
+
</tr>
|
241 |
+
<?php endforeach ?>
|
242 |
+
<?php else: ?>
|
243 |
+
<tr>
|
244 |
+
<td colspan="3">
|
245 |
+
No failed logins yet.
|
246 |
+
</td>
|
247 |
+
</tr>
|
248 |
+
<?php endif ?>
|
249 |
+
</tbody>
|
250 |
+
</table>
|
251 |
+
|
252 |
+
<p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
|
253 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceSecOpt#wfMarkerLoginSecurity') ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Login Security Options</a>
|
254 |
+
</p>
|
255 |
+
|
256 |
+
<?php wfHelperString::cycle(); ?>
|
257 |
+
|
258 |
+
<h2 style="font-size: 20px; vertical-align: baseline; clear: both; color: #222 !important; margin: 20px 0 4px; padding: 0; border: 0;">Recently Modified Files</h2>
|
259 |
+
|
260 |
+
<table class="activity-table" style="font-size: 100%; vertical-align: baseline; border-collapse: collapse; border-spacing: 0; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; max-width: 100%; margin: 0; padding: 0; border: 0;">
|
261 |
+
<thead style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
262 |
+
<tr style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
263 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">Modified</th>
|
264 |
+
<th style="font-size: 100%; vertical-align: baseline; font-weight: bold; text-align: left; color: #FFFFFF; background-color: #222; margin: 0; padding: 6px 4px; border: 1px solid #474747;" align="left" bgcolor="#222" valign="baseline">File</th>
|
265 |
+
</tr>
|
266 |
+
</thead>
|
267 |
+
<tbody style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
268 |
+
<?php foreach ($recently_modified_files as $file_row):
|
269 |
+
list($file, $mod_time) = $file_row;
|
270 |
+
?>
|
271 |
+
<?php
|
272 |
+
$stripe = wfHelperString::cycle('odd', 'even');
|
273 |
+
?>
|
274 |
+
<tr class="<?php echo $stripe ?>" style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
275 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;white-space: nowrap;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline"><?php echo $this->modTime($mod_time) ?></td>
|
276 |
+
<td style="font-size: 100%; vertical-align: baseline; font-weight: normal; text-align: left; border-collapse: collapse; margin: 0; padding: 6px 4px; border: 1px solid #cccccc;<?php echo $bg_colors[$stripe] ?>" align="left" valign="baseline">
|
277 |
+
<pre class="display-file" style="font-size: 12px; vertical-align: baseline; width: 420px; overflow: auto; margin: 0; padding: 0; border: 0;"><?php echo esc_html($this->displayFile($file)) ?></pre>
|
278 |
+
</td>
|
279 |
+
</tr>
|
280 |
+
<?php endforeach ?>
|
281 |
+
</tbody>
|
282 |
+
</table>
|
283 |
+
|
284 |
+
<?php wfHelperString::cycle(); ?>
|
285 |
+
|
286 |
+
<h2 style="font-size: 20px; vertical-align: baseline; clear: both; color: #222 !important; margin: 20px 0 4px; padding: 0; border: 0;">Updates Needed</h2>
|
287 |
+
|
288 |
+
<?php if ($updates_needed['core']): ?>
|
289 |
+
<h4 style="font-size: 16px; vertical-align: baseline; clear: both; color: #666666 !important; margin: 20px 0 4px; padding: 0; border: 0;">Core</h4>
|
290 |
+
<ul style="font-size: 100%; vertical-align: baseline; list-style-type: none; margin: 0; padding: 0; border: 0;">
|
291 |
+
<li style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">A new version of WordPress (v<?php echo esc_html($updates_needed['core']) ?>) is available.</li>
|
292 |
+
</ul>
|
293 |
+
<?php endif ?>
|
294 |
+
<?php if ($updates_needed['plugins']): ?>
|
295 |
+
<h4 style="font-size: 16px; vertical-align: baseline; clear: both; color: #666666 !important; margin: 20px 0 4px; padding: 0; border: 0;">Plugins</h4>
|
296 |
+
<ul style="font-size: 100%; vertical-align: baseline; list-style-type: none; margin: 0; padding: 0; border: 0;">
|
297 |
+
<?php foreach ($updates_needed['plugins'] as $plugin): ?>
|
298 |
+
<li style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
299 |
+
A new version of the plugin "<?php echo esc_html("{$plugin['Name']} (v{$plugin['newVersion']})") ?>" is available.
|
300 |
+
</li>
|
301 |
+
<?php endforeach ?>
|
302 |
+
</ul>
|
303 |
+
<?php endif ?>
|
304 |
+
<?php if ($updates_needed['themes']): ?>
|
305 |
+
<h4 style="font-size: 16px; vertical-align: baseline; clear: both; color: #666666 !important; margin: 20px 0 4px; padding: 0; border: 0;">Themes</h4>
|
306 |
+
<ul style="font-size: 100%; vertical-align: baseline; list-style-type: none; margin: 0; padding: 0; border: 0;">
|
307 |
+
<?php foreach ($updates_needed['themes'] as $theme): ?>
|
308 |
+
<li style="font-size: 100%; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
309 |
+
A new version of the theme "<?php echo esc_html("{$theme['name']} (v{$theme['newVersion']})") ?>" is available.
|
310 |
+
</li>
|
311 |
+
<?php endforeach ?>
|
312 |
+
</ul>
|
313 |
+
<?php endif ?>
|
314 |
+
|
315 |
+
<?php if ($updates_needed['core'] || $updates_needed['plugins'] || $updates_needed['themes']): ?>
|
316 |
+
<p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
|
317 |
+
<a class="button" href="<?php echo esc_attr(admin_url('update-core.php')) ?>" style="font-size: 13px; vertical-align: baseline; outline: none; color: #FFF; text-decoration: none; display: inline-block; line-height: 26px; height: 28px; cursor: pointer; border-radius: 3px; white-space: nowrap; box-sizing: border-box; box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15); background-image: none; background-attachment: scroll; background-repeat: repeat; background-color: #2EA2CC; margin: 0; padding: 0 10px 1px; border: 1px solid #0074a2;">Update Now</a>
|
318 |
+
</p>
|
319 |
+
<?php else: ?>
|
320 |
+
<p style="font-size: 100%; vertical-align: baseline; margin: 1em 0; padding: 0; border: 0;">
|
321 |
+
No updates are available at this time.
|
322 |
+
</p>
|
323 |
+
<?php endif ?>
|
324 |
+
</div>
|
325 |
+
</td>
|
326 |
+
</tr>
|
327 |
+
</table>
|
328 |
+
<!-- End of wrapper table -->
|
329 |
+
</body>
|
330 |
+
</html>
|
views/reports/activity-report-email.php
ADDED
@@ -0,0 +1,465 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var wfActivityReportView $this
|
4 |
+
*/
|
5 |
+
$title = 'Wordfence Activity for the week of ' . date_i18n(get_option('date_format'));
|
6 |
+
?>
|
7 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
8 |
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
9 |
+
<head>
|
10 |
+
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo get_option('blog_charset') ?>"/>
|
11 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
12 |
+
<title><?php echo esc_html($title) ?></title>
|
13 |
+
<link rel="stylesheet" href="http://www.wordfence.com/blog/wp-content/themes/twentytwelve/style.css?ver=4.1.1" title=""/>
|
14 |
+
|
15 |
+
<style type="text/css">
|
16 |
+
/* Based on The MailChimp Reset INLINE: Yes. */
|
17 |
+
/* Client-specific Styles */
|
18 |
+
#outlook a {
|
19 |
+
padding: 0;
|
20 |
+
}
|
21 |
+
|
22 |
+
/* Force Outlook to provide a "view in browser" menu link. */
|
23 |
+
body {
|
24 |
+
width: 100% !important;
|
25 |
+
-webkit-text-size-adjust: 100%;
|
26 |
+
-ms-text-size-adjust: 100%;
|
27 |
+
margin: 0;
|
28 |
+
padding: 0;
|
29 |
+
}
|
30 |
+
|
31 |
+
/* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/
|
32 |
+
.ExternalClass {
|
33 |
+
width: 100%;
|
34 |
+
}
|
35 |
+
|
36 |
+
/* Force Hotmail to display emails at full width */
|
37 |
+
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {
|
38 |
+
line-height: 100%;
|
39 |
+
}
|
40 |
+
|
41 |
+
/* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */
|
42 |
+
#backgroundTable {
|
43 |
+
margin: 0 auto;
|
44 |
+
padding: 0;
|
45 |
+
width: 100% !important;
|
46 |
+
line-height: 100% !important;
|
47 |
+
}
|
48 |
+
|
49 |
+
/* End reset */
|
50 |
+
|
51 |
+
/* Some sensible defaults for images
|
52 |
+
Bring inline: Yes. */
|
53 |
+
img {
|
54 |
+
outline: none;
|
55 |
+
text-decoration: none;
|
56 |
+
-ms-interpolation-mode: bicubic;
|
57 |
+
}
|
58 |
+
|
59 |
+
a img {
|
60 |
+
border: none;
|
61 |
+
}
|
62 |
+
|
63 |
+
.image_fix {
|
64 |
+
display: block;
|
65 |
+
}
|
66 |
+
|
67 |
+
/* Yahoo paragraph fix
|
68 |
+
Bring inline: Yes. */
|
69 |
+
p {
|
70 |
+
margin: 1em 0;
|
71 |
+
}
|
72 |
+
|
73 |
+
/* Hotmail header color reset
|
74 |
+
Bring inline: Yes. */
|
75 |
+
h1, h2, h3, h4, h5, h6 {
|
76 |
+
color: black !important;
|
77 |
+
}
|
78 |
+
|
79 |
+
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
|
80 |
+
color: blue !important;
|
81 |
+
}
|
82 |
+
|
83 |
+
h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {
|
84 |
+
color: red !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
|
85 |
+
}
|
86 |
+
|
87 |
+
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {
|
88 |
+
color: purple !important; /* Preferably not the same color as the normal header link color. There is limited support for psuedo classes in email clients, this was added just for good measure. */
|
89 |
+
}
|
90 |
+
|
91 |
+
/* Outlook 07, 10 Padding issue fix
|
92 |
+
Bring inline: No.*/
|
93 |
+
table td {
|
94 |
+
border-collapse: collapse;
|
95 |
+
}
|
96 |
+
|
97 |
+
/* Remove spacing around Outlook 07, 10 tables
|
98 |
+
Bring inline: Yes */
|
99 |
+
table {
|
100 |
+
border-collapse: collapse;
|
101 |
+
mso-table-lspace: 0pt;
|
102 |
+
mso-table-rspace: 0pt;
|
103 |
+
}
|
104 |
+
|
105 |
+
/* Styling your links has become much simpler with the new Yahoo. In fact, it falls in line with the main credo of styling in email and make sure to bring your styles inline. Your link colors will be uniform across clients when brought inline.
|
106 |
+
Bring inline: Yes. */
|
107 |
+
a {
|
108 |
+
color: orange;
|
109 |
+
}
|
110 |
+
|
111 |
+
.wrapper {
|
112 |
+
line-height: 1.4;
|
113 |
+
width: 600px;
|
114 |
+
padding: 20px;
|
115 |
+
margin: 0 auto;
|
116 |
+
background-color: #FFFFFF;
|
117 |
+
}
|
118 |
+
|
119 |
+
h1, h2, h3, h4 {
|
120 |
+
margin: 20px 0 4px;
|
121 |
+
color: #222 !important;
|
122 |
+
}
|
123 |
+
|
124 |
+
h1 {
|
125 |
+
float: right;
|
126 |
+
text-align: right;
|
127 |
+
font-size: 30px;
|
128 |
+
color: #444444 !important;
|
129 |
+
line-height: 1.1;
|
130 |
+
}
|
131 |
+
|
132 |
+
h2 {
|
133 |
+
font-size: 20px;
|
134 |
+
}
|
135 |
+
|
136 |
+
h4 {
|
137 |
+
font-size: 16px;
|
138 |
+
color:#666666 !important;
|
139 |
+
}
|
140 |
+
|
141 |
+
table.wf-table {
|
142 |
+
width: 100%;
|
143 |
+
max-width: 100%;
|
144 |
+
}
|
145 |
+
|
146 |
+
table.wf-table th,
|
147 |
+
table.wf-table td {
|
148 |
+
padding: 6px 4px;
|
149 |
+
border: 1px solid #cccccc;
|
150 |
+
}
|
151 |
+
|
152 |
+
table.wf-table thead th,
|
153 |
+
table.wf-table thead td {
|
154 |
+
background-color: #222;
|
155 |
+
color: #FFFFFF;
|
156 |
+
font-weight: bold;
|
157 |
+
border-color: #474747;
|
158 |
+
}
|
159 |
+
|
160 |
+
table.wf-table tbody tr.even td {
|
161 |
+
background-color: #eeeeee;
|
162 |
+
}
|
163 |
+
|
164 |
+
.loginFailValidUsername {
|
165 |
+
color: #00c000;
|
166 |
+
font-weight: bold;
|
167 |
+
}
|
168 |
+
|
169 |
+
.loginFailInvalidUsername {
|
170 |
+
color: #e74a2a;
|
171 |
+
font-weight: bold;
|
172 |
+
}
|
173 |
+
|
174 |
+
.display-file {
|
175 |
+
font-size: 12px;
|
176 |
+
width: 420px;
|
177 |
+
overflow: auto;
|
178 |
+
}
|
179 |
+
|
180 |
+
.button {
|
181 |
+
display: inline-block;
|
182 |
+
font-size: 13px;
|
183 |
+
line-height: 26px;
|
184 |
+
height: 28px;
|
185 |
+
margin: 0;
|
186 |
+
padding: 0 10px 1px;
|
187 |
+
cursor: pointer;
|
188 |
+
border-radius: 3px;
|
189 |
+
white-space: nowrap;
|
190 |
+
box-sizing: border-box;
|
191 |
+
background: none repeat scroll 0 0 #2EA2CC;
|
192 |
+
border: 1px solid #0074A2;
|
193 |
+
box-shadow: 0 1px 0 rgba(120, 200, 230, 0.5) inset, 0 1px 0 rgba(0, 0, 0, 0.15);
|
194 |
+
color: #FFF;
|
195 |
+
text-decoration: none;
|
196 |
+
}
|
197 |
+
.button:hover,
|
198 |
+
.button:active,
|
199 |
+
.button:focus {
|
200 |
+
background: none repeat scroll 0 0 #1E8CBE;
|
201 |
+
border-color: #0074A2;
|
202 |
+
box-shadow: 0 1px 0 rgba(120, 200, 230, 0.6) inset;
|
203 |
+
color: #FFF;
|
204 |
+
}
|
205 |
+
|
206 |
+
/***************************************************
|
207 |
+
****************************************************
|
208 |
+
MOBILE TARGETING
|
209 |
+
****************************************************
|
210 |
+
***************************************************/
|
211 |
+
@media only screen and (max-device-width: 480px) {
|
212 |
+
/* Part one of controlling phone number linking for mobile. */
|
213 |
+
a[href^="tel"], a[href^="sms"] {
|
214 |
+
text-decoration: none;
|
215 |
+
color: blue; /* or whatever your want */
|
216 |
+
pointer-events: none;
|
217 |
+
cursor: default;
|
218 |
+
}
|
219 |
+
|
220 |
+
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
|
221 |
+
text-decoration: default;
|
222 |
+
color: orange !important;
|
223 |
+
pointer-events: auto;
|
224 |
+
cursor: default;
|
225 |
+
}
|
226 |
+
|
227 |
+
}
|
228 |
+
|
229 |
+
/* More Specific Targeting */
|
230 |
+
|
231 |
+
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
|
232 |
+
/* You guessed it, ipad (tablets, smaller screens, etc) */
|
233 |
+
/* repeating for the ipad */
|
234 |
+
a[href^="tel"], a[href^="sms"] {
|
235 |
+
text-decoration: none;
|
236 |
+
color: blue; /* or whatever your want */
|
237 |
+
pointer-events: none;
|
238 |
+
cursor: default;
|
239 |
+
}
|
240 |
+
|
241 |
+
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
|
242 |
+
text-decoration: default;
|
243 |
+
color: orange !important;
|
244 |
+
pointer-events: auto;
|
245 |
+
cursor: default;
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
|
250 |
+
/* Put your iPhone 4g styles in here */
|
251 |
+
}
|
252 |
+
|
253 |
+
/* Android targeting */
|
254 |
+
@media only screen and (-webkit-device-pixel-ratio: .75) {
|
255 |
+
/* Put CSS for low density (ldpi) Android layouts in here */
|
256 |
+
}
|
257 |
+
|
258 |
+
@media only screen and (-webkit-device-pixel-ratio: 1) {
|
259 |
+
/* Put CSS for medium density (mdpi) Android layouts in here */
|
260 |
+
}
|
261 |
+
|
262 |
+
@media only screen and (-webkit-device-pixel-ratio: 1.5) {
|
263 |
+
/* Put CSS for high density (hdpi) Android layouts in here */
|
264 |
+
}
|
265 |
+
|
266 |
+
/* end Android targeting */
|
267 |
+
|
268 |
+
</style>
|
269 |
+
|
270 |
+
<!-- Targeting Windows Mobile -->
|
271 |
+
<!--[if IEMobile 7]>
|
272 |
+
<style type="text/css">
|
273 |
+
|
274 |
+
</style>
|
275 |
+
<![endif]-->
|
276 |
+
|
277 |
+
<!-- ***********************************************
|
278 |
+
****************************************************
|
279 |
+
END MOBILE TARGETING
|
280 |
+
****************************************************
|
281 |
+
************************************************ -->
|
282 |
+
|
283 |
+
<!--[if gte mso 9]>
|
284 |
+
<style>
|
285 |
+
/* Target Outlook 2007 and 2010 */
|
286 |
+
</style>
|
287 |
+
<![endif]-->
|
288 |
+
</head>
|
289 |
+
<body>
|
290 |
+
<!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. -->
|
291 |
+
<table cellpadding="0" cellspacing="0" border="0" id="backgroundTable">
|
292 |
+
<tr>
|
293 |
+
<td valign="top">
|
294 |
+
<div class="wrapper wp-core-ui">
|
295 |
+
<div style="float: right;text-align: right;line-height:1.1;color: #666666;margin:20px 0 0;">
|
296 |
+
Activity for week of<br> <strong><?php echo date_i18n(get_option('date_format')) ?></strong>
|
297 |
+
</div>
|
298 |
+
<a href="http://www.wordfence.com/"><img src="http://www.wordfence.com/wp-content/themes/parallelus-salutation/wfCustomHome/images/wordfenceLogo.png" alt=""/></a>
|
299 |
+
|
300 |
+
<h2>Top 10 IP's Blocked</h2>
|
301 |
+
|
302 |
+
<?php wfHelperString::cycle(); ?>
|
303 |
+
|
304 |
+
<table class="wf-table">
|
305 |
+
<thead>
|
306 |
+
<tr>
|
307 |
+
<th>IP</th>
|
308 |
+
<th>Country</th>
|
309 |
+
<th>Block Count</th>
|
310 |
+
</tr>
|
311 |
+
</thead>
|
312 |
+
<tbody>
|
313 |
+
<?php foreach ($top_ips_blocked as $row): ?>
|
314 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
315 |
+
<td><code><?php echo wfUtils::inet_ntoa($row->IP) ?></code></td>
|
316 |
+
<td>
|
317 |
+
<?php if ($row->countryCode): ?>
|
318 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo esc_attr(strtolower($row->countryCode)) ?>.png" class="wfFlag" height="11" width="16">
|
319 |
+
|
320 |
+
<?php echo esc_html($row->countryCode) ?>
|
321 |
+
<?php else: ?>
|
322 |
+
(Unknown)
|
323 |
+
<?php endif ?>
|
324 |
+
</td>
|
325 |
+
<td><?php echo (int)$row->blockCount ?></td>
|
326 |
+
</tr>
|
327 |
+
<?php endforeach ?>
|
328 |
+
</tbody>
|
329 |
+
</table>
|
330 |
+
|
331 |
+
<p>
|
332 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceBlockedIPs') ?>">Update Blocked IPs</a>
|
333 |
+
</p>
|
334 |
+
|
335 |
+
<?php wfHelperString::cycle(); ?>
|
336 |
+
|
337 |
+
<h2>Top 10 Countries Blocked</h2>
|
338 |
+
|
339 |
+
<table class="wf-table">
|
340 |
+
<thead>
|
341 |
+
<tr>
|
342 |
+
<th>Country</th>
|
343 |
+
<th>Total IPs Blocked</th>
|
344 |
+
<th>Block Count</th>
|
345 |
+
</tr>
|
346 |
+
</thead>
|
347 |
+
<tbody>
|
348 |
+
<?php foreach ($top_countries_blocked as $row): ?>
|
349 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
350 |
+
<td>
|
351 |
+
<?php if ($row->countryCode): ?>
|
352 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo strtolower($row->countryCode) ?>.png" class="wfFlag" height="11" width="16">
|
353 |
+
|
354 |
+
<?php echo esc_html($row->countryCode) ?>
|
355 |
+
<?php else: ?>
|
356 |
+
(Unknown)
|
357 |
+
<?php endif ?>
|
358 |
+
</td>
|
359 |
+
<td><?php echo esc_html($row->totalIPs) ?></td>
|
360 |
+
<td><?php echo (int)$row->totalBlockCount ?></td>
|
361 |
+
</tr>
|
362 |
+
<?php endforeach ?>
|
363 |
+
</tbody>
|
364 |
+
</table>
|
365 |
+
|
366 |
+
<p>
|
367 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceCountryBlocking') ?>">Update Blocked Countries</a>
|
368 |
+
</p>
|
369 |
+
|
370 |
+
<?php wfHelperString::cycle(); ?>
|
371 |
+
|
372 |
+
<h2>Top 10 Failed Logins</h2>
|
373 |
+
|
374 |
+
<table class="wf-table">
|
375 |
+
<thead>
|
376 |
+
<tr>
|
377 |
+
<th>Username</th>
|
378 |
+
<th>Login Attempts</th>
|
379 |
+
<th>Existing User</th>
|
380 |
+
</tr>
|
381 |
+
</thead>
|
382 |
+
<tbody>
|
383 |
+
<?php foreach ($top_failed_logins as $row): ?>
|
384 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
385 |
+
<td><?php echo esc_html($row->username) ?></td>
|
386 |
+
<td><?php echo esc_html($row->fail_count) ?></td>
|
387 |
+
<td class="<?php echo sanitize_html_class($row->action) ?>"><?php echo $row->action == 'loginFailValidUsername' ? 'Yes' : 'No' ?></td>
|
388 |
+
</tr>
|
389 |
+
<?php endforeach ?>
|
390 |
+
</tbody>
|
391 |
+
</table>
|
392 |
+
|
393 |
+
<p>
|
394 |
+
<a class="button" href="<?php echo admin_url('admin.php?page=WordfenceSecOpt#wfMarkerLoginSecurity') ?>">Update Login Security Options</a>
|
395 |
+
</p>
|
396 |
+
|
397 |
+
<?php wfHelperString::cycle(); ?>
|
398 |
+
|
399 |
+
<h2>Recently Modified Files</h2>
|
400 |
+
|
401 |
+
<table class="wf-table">
|
402 |
+
<thead>
|
403 |
+
<tr>
|
404 |
+
<th>Modified</th>
|
405 |
+
<th>File</th>
|
406 |
+
</tr>
|
407 |
+
</thead>
|
408 |
+
<tbody>
|
409 |
+
<?php foreach ($recently_modified_files as $file_row):
|
410 |
+
list($file, $mod_time) = $file_row;
|
411 |
+
?>
|
412 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
413 |
+
<td style="white-space: nowrap;"><?php echo $this->modTime($mod_time) ?></td>
|
414 |
+
<td>
|
415 |
+
<pre class="display-file"><?php echo esc_html($this->displayFile($file)) ?></pre>
|
416 |
+
</td>
|
417 |
+
</tr>
|
418 |
+
<?php endforeach ?>
|
419 |
+
</tbody>
|
420 |
+
</table>
|
421 |
+
|
422 |
+
<?php wfHelperString::cycle(); ?>
|
423 |
+
|
424 |
+
<h2>Updates Needed</h2>
|
425 |
+
|
426 |
+
<?php if ($updates_needed['core']): ?>
|
427 |
+
<h4>Core</h4>
|
428 |
+
<ul>
|
429 |
+
<li>A new version of WordPress (v<?php echo esc_html($updates_needed['core']) ?>) is available.</li>
|
430 |
+
</ul>
|
431 |
+
<?php endif ?>
|
432 |
+
<?php if ($updates_needed['plugins']): ?>
|
433 |
+
<h4>Plugins</h4>
|
434 |
+
<ul>
|
435 |
+
<?php foreach ($updates_needed['plugins'] as $plugin): ?>
|
436 |
+
<li>
|
437 |
+
A new version of the plugin "<?php echo esc_html("{$plugin['Name']} (v{$plugin['newVersion']})") ?>" is available.
|
438 |
+
</li>
|
439 |
+
<?php endforeach ?>
|
440 |
+
</ul>
|
441 |
+
<?php endif ?>
|
442 |
+
<?php if ($updates_needed['themes']): ?>
|
443 |
+
<h4>Themes</h4>
|
444 |
+
<ul>
|
445 |
+
<?php foreach ($updates_needed['themes'] as $theme): ?>
|
446 |
+
<li>
|
447 |
+
A new version of the theme "<?php echo esc_html("{$theme['name']} (v{$theme['newVersion']})") ?>" is available.
|
448 |
+
</li>
|
449 |
+
<?php endforeach ?>
|
450 |
+
</ul>
|
451 |
+
<?php endif ?>
|
452 |
+
|
453 |
+
<?php if ($updates_needed['core'] || $updates_needed['plugins'] || $updates_needed['themes']): ?>
|
454 |
+
<p><a class="button" href="<?php echo esc_attr(admin_url('update-core.php')) ?>">Update Now</a></p>
|
455 |
+
<?php endif ?>
|
456 |
+
|
457 |
+
<!-- <p>Generated in --><?php //printf('%.4f seconds', $microseconds) ?><!--</p>-->
|
458 |
+
|
459 |
+
</div>
|
460 |
+
</td>
|
461 |
+
</tr>
|
462 |
+
</table>
|
463 |
+
<!-- End of wrapper table -->
|
464 |
+
</body>
|
465 |
+
</html>
|
views/reports/activity-report.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var wfActivityReportView $this
|
4 |
+
*/
|
5 |
+
?>
|
6 |
+
<a href="http://www.wordfence.com/"><img src="http://www.wordfence.com/wp-content/themes/parallelus-salutation/wfCustomHome/images/wordfenceLogo.png" alt=""/></a>
|
7 |
+
|
8 |
+
<h2>Top <?php echo (int) $limit; ?> IP's Blocked</h2>
|
9 |
+
|
10 |
+
<?php wfHelperString::cycle(); ?>
|
11 |
+
|
12 |
+
<table class="wf-table">
|
13 |
+
<thead>
|
14 |
+
<tr>
|
15 |
+
<th>IP</th>
|
16 |
+
<th>Country</th>
|
17 |
+
<th>Block Count</th>
|
18 |
+
</tr>
|
19 |
+
</thead>
|
20 |
+
<tbody>
|
21 |
+
<?php if ($top_ips_blocked): ?>
|
22 |
+
<?php foreach ($top_ips_blocked as $row): ?>
|
23 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
24 |
+
<td><code><?php echo wfUtils::inet_ntoa($row->IP) ?></code></td>
|
25 |
+
<td>
|
26 |
+
<?php if ($row->countryCode): ?>
|
27 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo esc_attr(strtolower($row->countryCode)) ?>.png" class="wfFlag" height="11" width="16">
|
28 |
+
|
29 |
+
<?php echo esc_html($row->countryCode) ?>
|
30 |
+
<?php else: ?>
|
31 |
+
(Unknown)
|
32 |
+
<?php endif ?>
|
33 |
+
</td>
|
34 |
+
<td><?php echo (int) $row->blockCount ?></td>
|
35 |
+
</tr>
|
36 |
+
<?php endforeach ?>
|
37 |
+
<?php else: ?>
|
38 |
+
<tr>
|
39 |
+
<td colspan="3">
|
40 |
+
We're collecting data, please check back soon.
|
41 |
+
</td>
|
42 |
+
</tr>
|
43 |
+
<?php endif ?>
|
44 |
+
</tbody>
|
45 |
+
</table>
|
46 |
+
|
47 |
+
<p>
|
48 |
+
<a class="button button-primary" href="<?php echo admin_url('admin.php?page=WordfenceBlockedIPs') ?>">Update Blocked IPs</a>
|
49 |
+
</p>
|
50 |
+
|
51 |
+
<?php wfHelperString::cycle(); ?>
|
52 |
+
|
53 |
+
<h2>Top <?php echo (int) $limit; ?> Countries Blocked</h2>
|
54 |
+
|
55 |
+
<table class="wf-table">
|
56 |
+
<thead>
|
57 |
+
<tr>
|
58 |
+
<th>Country</th>
|
59 |
+
<th>Total IPs Blocked</th>
|
60 |
+
<th>Block Count</th>
|
61 |
+
</tr>
|
62 |
+
</thead>
|
63 |
+
<tbody>
|
64 |
+
<?php if ($top_countries_blocked): ?>
|
65 |
+
<?php foreach ($top_countries_blocked as $row): ?>
|
66 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
67 |
+
<td>
|
68 |
+
<?php if ($row->countryCode): ?>
|
69 |
+
<img src="http://www.wordfence.com/images/flags/<?php echo strtolower($row->countryCode) ?>.png" class="wfFlag" height="11" width="16">
|
70 |
+
|
71 |
+
<?php echo esc_html($row->countryCode) ?>
|
72 |
+
<?php else: ?>
|
73 |
+
(Unknown)
|
74 |
+
<?php endif ?>
|
75 |
+
</td>
|
76 |
+
<td><?php echo esc_html($row->totalIPs) ?></td>
|
77 |
+
<td><?php echo (int) $row->totalBlockCount ?></td>
|
78 |
+
</tr>
|
79 |
+
<?php endforeach ?>
|
80 |
+
<?php else: ?>
|
81 |
+
<tr>
|
82 |
+
<td colspan="3">
|
83 |
+
We're collecting data, please check back soon.
|
84 |
+
</td>
|
85 |
+
</tr>
|
86 |
+
<?php endif ?>
|
87 |
+
</tbody>
|
88 |
+
</table>
|
89 |
+
|
90 |
+
<p>
|
91 |
+
<a class="button button-primary" href="<?php echo admin_url('admin.php?page=WordfenceCountryBlocking') ?>">Update Blocked Countries</a>
|
92 |
+
</p>
|
93 |
+
|
94 |
+
<?php wfHelperString::cycle(); ?>
|
95 |
+
|
96 |
+
<h2>Top <?php echo (int) $limit; ?> Failed Logins</h2>
|
97 |
+
|
98 |
+
<table class="wf-table">
|
99 |
+
<thead>
|
100 |
+
<tr>
|
101 |
+
<th>Username</th>
|
102 |
+
<th>Login Attempts</th>
|
103 |
+
<th>Existing User</th>
|
104 |
+
</tr>
|
105 |
+
</thead>
|
106 |
+
<tbody>
|
107 |
+
<?php if ($top_failed_logins): ?>
|
108 |
+
<?php foreach ($top_failed_logins as $row): ?>
|
109 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
110 |
+
<td><?php echo esc_html($row->username) ?></td>
|
111 |
+
<td><?php echo esc_html($row->fail_count) ?></td>
|
112 |
+
<td class="<?php echo sanitize_html_class($row->action) ?>"><?php echo $row->action == 'loginFailValidUsername' ? 'Yes' : 'No' ?></td>
|
113 |
+
</tr>
|
114 |
+
<?php endforeach ?>
|
115 |
+
<?php else: ?>
|
116 |
+
<tr>
|
117 |
+
<td colspan="3">
|
118 |
+
We're collecting data, please check back soon.
|
119 |
+
</td>
|
120 |
+
</tr>
|
121 |
+
<?php endif ?>
|
122 |
+
</tbody>
|
123 |
+
</table>
|
124 |
+
|
125 |
+
<p>
|
126 |
+
<a class="button button-primary" href="<?php echo admin_url('admin.php?page=WordfenceSecOpt#wfMarkerLoginSecurity') ?>">Update Login Security Options</a>
|
127 |
+
</p>
|
128 |
+
|
129 |
+
<?php wfHelperString::cycle(); ?>
|
130 |
+
|
131 |
+
<?php /*?>
|
132 |
+
<h2>Recently Modified Files</h2>
|
133 |
+
|
134 |
+
<table class="activity-table recently-modified-files">
|
135 |
+
<thead>
|
136 |
+
<tr>
|
137 |
+
<th>Modified</th>
|
138 |
+
<th>File</th>
|
139 |
+
</tr>
|
140 |
+
</thead>
|
141 |
+
<tbody>
|
142 |
+
<?php foreach ($recently_modified_files as $file_row):
|
143 |
+
list($file, $mod_time) = $file_row;
|
144 |
+
?>
|
145 |
+
<tr class="<?php echo wfHelperString::cycle('odd', 'even') ?>">
|
146 |
+
<td style="white-space: nowrap;"><?php echo $this->modTime($mod_time) ?></td>
|
147 |
+
<td class="display-file-table-cell">
|
148 |
+
<pre class="display-file"><?php echo esc_html($this->displayFile($file)) ?></pre>
|
149 |
+
</td>
|
150 |
+
</tr>
|
151 |
+
<?php endforeach ?>
|
152 |
+
</tbody>
|
153 |
+
</table>
|
154 |
+
<?php */ ?>
|
155 |
+
|
156 |
+
|
157 |
+
<?php wfHelperString::cycle(); ?>
|
158 |
+
|
159 |
+
<h2>Updates Needed</h2>
|
160 |
+
|
161 |
+
<?php if ($updates_needed['core']): ?>
|
162 |
+
<h4>Core</h4>
|
163 |
+
<ul>
|
164 |
+
<li>A new version of WordPress (v<?php echo esc_html($updates_needed['core']) ?>) is available.</li>
|
165 |
+
</ul>
|
166 |
+
<?php endif ?>
|
167 |
+
<?php if ($updates_needed['plugins']): ?>
|
168 |
+
<h4>Plugins</h4>
|
169 |
+
<ul>
|
170 |
+
<?php foreach ($updates_needed['plugins'] as $plugin): ?>
|
171 |
+
<li>
|
172 |
+
A new version of the plugin "<?php echo esc_html("{$plugin['Name']} (v{$plugin['newVersion']})") ?>" is available.
|
173 |
+
</li>
|
174 |
+
<?php endforeach ?>
|
175 |
+
</ul>
|
176 |
+
<?php endif ?>
|
177 |
+
<?php if ($updates_needed['themes']): ?>
|
178 |
+
<h4>Themes</h4>
|
179 |
+
<ul>
|
180 |
+
<?php foreach ($updates_needed['themes'] as $theme): ?>
|
181 |
+
<li>
|
182 |
+
A new version of the theme "<?php echo esc_html("{$theme['name']} (v{$theme['newVersion']})") ?>" is available.
|
183 |
+
</li>
|
184 |
+
<?php endforeach ?>
|
185 |
+
</ul>
|
186 |
+
<?php endif ?>
|
187 |
+
|
188 |
+
<?php if ($updates_needed['core'] || $updates_needed['plugins'] || $updates_needed['themes']): ?>
|
189 |
+
<p><a class="button button-primary" href="<?php echo esc_attr(admin_url('update-core.php')) ?>">Update Now</a></p>
|
190 |
+
<?php else: ?>
|
191 |
+
<p>No updates are available at this time.</p>
|
192 |
+
<?php endif ?>
|
193 |
+
<?php if ((defined('WP_DEBUG') && WP_DEBUG) || wfConfig::get('debugOn')): ?>
|
194 |
+
<p>Generated in <?php printf('%.4f seconds', $microseconds) ?></p>
|
195 |
+
<?php endif ?>
|
wordfence.php
CHANGED
@@ -4,13 +4,13 @@ Plugin Name: Wordfence Security
|
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and High Speed Cache
|
6 |
Author: Wordfence
|
7 |
-
Version: 5.3.
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
*/
|
10 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
11 |
return;
|
12 |
}
|
13 |
-
define('WORDFENCE_VERSION', '5.3.
|
14 |
if(get_option('wordfenceActivated') != 1){
|
15 |
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
|
16 |
}
|
4 |
Plugin URI: http://www.wordfence.com/
|
5 |
Description: Wordfence Security - Anti-virus, Firewall and High Speed Cache
|
6 |
Author: Wordfence
|
7 |
+
Version: 5.3.9
|
8 |
Author URI: http://www.wordfence.com/
|
9 |
*/
|
10 |
if(defined('WP_INSTALLING') && WP_INSTALLING){
|
11 |
return;
|
12 |
}
|
13 |
+
define('WORDFENCE_VERSION', '5.3.9');
|
14 |
if(get_option('wordfenceActivated') != 1){
|
15 |
add_action('activated_plugin','wordfence_save_activation_error'); function wordfence_save_activation_error(){ update_option('wf_plugin_act_error', ob_get_contents()); }
|
16 |
}
|