Sucuri Security – Auditing, Malware Scanner and Security Hardening - Version 1.6.4

Version Description

  • Fixed API generation bug.
Download this release

Release Info

Developer dd@sucuri.net
Plugin Icon 128x128 Sucuri Security – Auditing, Malware Scanner and Security Hardening
Version 1.6.4
Comparing to
See all releases

Code changes from version 1.6.1 to 1.6.4

Files changed (33) hide show
  1. .htaccess +14 -0
  2. inc/css/sucuriscan-default-css.css +28 -3
  3. inc/tpl/base.html.tpl +1 -1
  4. inc/tpl/infosys-htaccess.html.tpl +1 -1
  5. inc/tpl/infosys.html.tpl +1 -8
  6. inc/tpl/integrity-auditlogs.html.tpl +7 -15
  7. inc/tpl/integrity-wpoutdate.html.tpl +15 -0
  8. inc/tpl/lastlogins-admins-lastlogin.snippet.tpl +1 -1
  9. inc/tpl/lastlogins-admins.html.tpl +2 -2
  10. inc/tpl/lastlogins-admins.snippet.tpl +3 -3
  11. inc/tpl/lastlogins-all.html.tpl +18 -2
  12. inc/tpl/lastlogins-all.snippet.tpl +2 -1
  13. inc/tpl/lastlogins-failedlogins.html.tpl +48 -0
  14. inc/tpl/lastlogins-failedlogins.snippet.tpl +8 -0
  15. inc/tpl/{infosys-loggedin.html.tpl → lastlogins-loggedin.html.tpl} +1 -1
  16. inc/tpl/{infosys-loggedin.snippet.tpl → lastlogins-loggedin.snippet.tpl} +1 -0
  17. inc/tpl/lastlogins.html.tpl +14 -0
  18. inc/tpl/monitoring-settings.html.tpl +2 -2
  19. inc/tpl/posthack-databasebackups.html.tpl +0 -41
  20. inc/tpl/posthack-databasebackups.snippet.tpl +0 -10
  21. inc/tpl/posthack-resetpassword.html.tpl +1 -1
  22. inc/tpl/{resetpassword.snippet.tpl → posthack-resetpassword.snippet.tpl} +2 -1
  23. inc/tpl/posthack-resetplugins.html.tpl +49 -0
  24. inc/tpl/posthack-resetplugins.snippet.tpl +10 -0
  25. inc/tpl/posthack.html.tpl +3 -4
  26. inc/tpl/settings-general.html.tpl +149 -0
  27. inc/tpl/settings-ignorerules.html.tpl +59 -0
  28. inc/tpl/settings-ignorerules.snippet.tpl +15 -0
  29. inc/tpl/settings-notifications.html.tpl +22 -0
  30. inc/tpl/{settings-notification.snippet.tpl → settings-notifications.snippet.tpl} +0 -0
  31. inc/tpl/settings.html.tpl +27 -117
  32. readme.txt +15 -1
  33. sucuri.php +1696 -897
.htaccess ADDED
@@ -0,0 +1,14 @@
1
+
2
+ Order Deny,Allow
3
+ Deny from all
4
+ Allow from 127.0.0.1
5
+
6
+ <Files index.php>
7
+ Order Allow,Deny
8
+ Allow from all
9
+ </Files>
10
+
11
+ <FilesMatch "\.(gif|jpe?g|png|css|js)quot;>
12
+ Order Allow,Deny
13
+ Allow from all
14
+ </FilesMatch>
inc/css/sucuriscan-default-css.css CHANGED
@@ -32,6 +32,14 @@
32
.sucuriscan-modal-close{display:inline-block;position:absolute;top:0;right:0;font-size:16px;font-weight:bold;text-decoration:none;line-height:39px;padding:0 15px;border-left:1px solid #ddd}
33
.sucuriscan-modal-inside p:first-child{margin-top:0}
34
.sucuriscan-modal-inside p:last-child{margin-bottom:0}
35
/* Interface Wrapper */
36
.sucuriscan-wrap{margin-top:20px}
37
.sucuriscan-wrap .sucuriscan-maincontent{margin:20px 0}
@@ -63,6 +71,8 @@
63
.sucuriscan-table-double-title tr:first-child th{border-bottom:0}
64
.sucuriscan-table-triple-title tr:first-child th, .sucuriscan-table-triple-title tr:first-child + tr th{border-bottom:0}
65
.sucuriscan-table-quad-title tr:first-child th, .sucuriscan-table-quad-title tr:first-child + tr th, .sucuriscan-table-quad-title tr:first-child + tr + tr th{border-bottom:0}
66
.sucuriscan-maincontent .sucuriscan-lastmodified td{font-family:Monospace, Courier, serif;font-weight:bold}
67
.widefat td.td-with-button{text-align:right;padding:3px 10px}
68
.widefat td.td-with-button button{min-width:90px}
@@ -87,6 +97,10 @@
87
/* WordPress Alerts */
88
div.sucuriscan-alert{position:relative;margin:0 0 20px 0}
89
div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:18px;font-weight:bold;text-decoration:none}
90
/* Tabulation Panels */
91
.sucuriscan-tabs{}
92
.sucuriscan-tabs > ul{margin:0}
@@ -165,6 +179,11 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
165
.sucuriscan-hstatus-1{background-color:#dff0d8;color:#3c763d;border-color:#d6e9c6}
166
.sucuriscan-hstatus-0{background-color:#f2dede;color:#a94442;border-color:#ebccd1}
167
.sucuriscan-hstatus .button-primary, .sucuriscan-hstatus .button-secondary{position:absolute;top:5px;right:5px}
168
/* About Page */
169
.sucuriscan-about ul{margin-left:20px}
170
.sucuriscan-about ul li{list-style:initial}
@@ -173,6 +192,13 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
173
.sucuriscan-apikey-registered{}
174
.sucuriscan-apikey-registered .sucuriscan-pull-right{width:400px;margin-left:20px}
175
.sucuriscan-apikey-registered .sucuriscan-sitelogo{background-position:0 -17px;height:83px}
176
/* Resetter Styles */
177
.sucuriscan_wpconfig_keys_updated textarea{width:100%;height:250px;background:#f5f5f5;font-family:monospace;font-size:12px;resize:vertical;margin:20px 0 0 0}
178
.sucuriscan-maincontent .sucuriscan-last-logins{margin-top:0}
@@ -184,8 +210,8 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
184
.sucuriscan-maincontent .sucuriscan-auditlogs .sucuriscan-maxper-page{text-align:right}
185
.sucuriscan-maincontent .sucuriscan-settings{margin-top:0}
186
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
187
- .sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{min-width:245px}
188
- .sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:20px}
189
.sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;font-size:12px;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
190
/* Responsive Styles */
191
@media (max-width: 620px) {
@@ -210,7 +236,6 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
210
.sucuriscan-maincontent #poststuff{min-width:initial;padding-top:0}
211
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
212
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
213
- .sucuriscan-maincontent a.lastlogins-showall{display:inline-block;float:right}
214
.sucuri-inline-error{font-weight:bold;color:red}
215
.sucuriscan-maincontent .alternate{background:#f5f5f5}
216
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
32
.sucuriscan-modal-close{display:inline-block;position:absolute;top:0;right:0;font-size:16px;font-weight:bold;text-decoration:none;line-height:39px;padding:0 15px;border-left:1px solid #ddd}
33
.sucuriscan-modal-inside p:first-child{margin-top:0}
34
.sucuriscan-modal-inside p:last-child{margin-bottom:0}
35
+ /* Label and Tags */
36
+ .sucuriscan-label, .sucuriscan-label-default, .sucuriscan-label-primary, .sucuriscan-label-success, .sucuriscan-label-info, .sucuriscan-label-warning, .sucuriscan-label-danger{display:inline;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;padding:0.2em 0.6em 0.3em;border-radius:0.25em}
37
+ .sucuriscan-label-default{background:#777}
38
+ .sucuriscan-label-primary{background:#428bca}
39
+ .sucuriscan-label-success{background:#5cb85c}
40
+ .sucuriscan-label-info{background:#5bc0de}
41
+ .sucuriscan-label-warning{background:#f0ad4e}
42
+ .sucuriscan-label-danger{background:#d9534f}
43
/* Interface Wrapper */
44
.sucuriscan-wrap{margin-top:20px}
45
.sucuriscan-wrap .sucuriscan-maincontent{margin:20px 0}
71
.sucuriscan-table-double-title tr:first-child th{border-bottom:0}
72
.sucuriscan-table-triple-title tr:first-child th, .sucuriscan-table-triple-title tr:first-child + tr th{border-bottom:0}
73
.sucuriscan-table-quad-title tr:first-child th, .sucuriscan-table-quad-title tr:first-child + tr th, .sucuriscan-table-quad-title tr:first-child + tr + tr th{border-bottom:0}
74
+ .sucuriscan-table-description{border-left-width:1px !important;box-shadow:none}
75
+ .sucuriscan-table-description .inside{border-bottom:0 !important}
76
.sucuriscan-maincontent .sucuriscan-lastmodified td{font-family:Monospace, Courier, serif;font-weight:bold}
77
.widefat td.td-with-button{text-align:right;padding:3px 10px}
78
.widefat td.td-with-button button{min-width:90px}
97
/* WordPress Alerts */
98
div.sucuriscan-alert{position:relative;margin:0 0 20px 0}
99
div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:18px;font-weight:bold;text-decoration:none}
100
+ .sucuriscan-inline-alert, .sucuriscan-inline-alert-updated, .sucuriscan-inline-alert-error{background:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:0;border-left:4px solid #ddd}
101
+ .sucuriscan-inline-alert > p, .sucuriscan-inline-alert-updated > p, .sucuriscan-inline-alert-error > p{margin:0;padding:8px 12px;border:1px solid #ddd;border-left:0}
102
+ .sucuriscan-inline-alert-updated{border-left-color:#7ad03a}
103
+ .sucuriscan-inline-alert-error{border-left-color:#dd3d36}
104
/* Tabulation Panels */
105
.sucuriscan-tabs{}
106
.sucuriscan-tabs > ul{margin:0}
179
.sucuriscan-hstatus-1{background-color:#dff0d8;color:#3c763d;border-color:#d6e9c6}
180
.sucuriscan-hstatus-0{background-color:#f2dede;color:#a94442;border-color:#ebccd1}
181
.sucuriscan-hstatus .button-primary, .sucuriscan-hstatus .button-secondary{position:absolute;top:5px;right:5px}
182
+ /* Last Logins Styles */
183
+ .sucuriscan-lastlogin-outof{font-style:italic;color:#999;margin-right:10px}
184
+ .sucuriscan-admins-lastlogins .sucuriscan-ellipsis{width:170px}
185
+ .sucuriscan-admins-lastlogins td{padding:4px 8px}
186
+ .sucuriscan-lastlogins-failed{}
187
/* About Page */
188
.sucuriscan-about ul{margin-left:20px}
189
.sucuriscan-about ul li{list-style:initial}
192
.sucuriscan-apikey-registered{}
193
.sucuriscan-apikey-registered .sucuriscan-pull-right{width:400px;margin-left:20px}
194
.sucuriscan-apikey-registered .sucuriscan-sitelogo{background-position:0 -17px;height:83px}
195
+ /* Pagination Styles */
196
+ .sucuriscan-pagination{display:inline-block;margin:0;padding:0;border-radius:4px}
197
+ .sucuriscan-pagination>li{display:inline}
198
+ .sucuriscan-pagination>li>a, .sucuriscan-pagination>li>span{position:relative;background:#fff;color:#428bca;line-height:1.42857143;text-decoration: none;float:left;margin-left:-1px;padding:6px 12px;border:1px solid #ddd}
199
+ .sucuriscan-pagination>li:first-child>a, .sucuriscan-pagination>li:first-child>span{margin-left:0;border-radius:4px 0 0 4px}
200
+ .sucuriscan-pagination>li:last-child>a, .sucuriscan-pagination>li:last-child>span{border-radius:0 4px 4px 0}
201
+ .sucuriscan-pagination>li>a.sucuriscan-pagination-active, .sucuriscan-pagination>li>a:hover{background:#0074a2;color:#fff}
202
/* Resetter Styles */
203
.sucuriscan_wpconfig_keys_updated textarea{width:100%;height:250px;background:#f5f5f5;font-family:monospace;font-size:12px;resize:vertical;margin:20px 0 0 0}
204
.sucuriscan-maincontent .sucuriscan-last-logins{margin-top:0}
210
.sucuriscan-maincontent .sucuriscan-auditlogs .sucuriscan-maxper-page{text-align:right}
211
.sucuriscan-maincontent .sucuriscan-settings{margin-top:0}
212
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
213
+ .sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{min-width:220px}
214
+ .sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0}
215
.sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;font-size:12px;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
216
/* Responsive Styles */
217
@media (max-width: 620px) {
236
.sucuriscan-maincontent #poststuff{min-width:initial;padding-top:0}
237
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
238
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
239
.sucuri-inline-error{font-weight:bold;color:red}
240
.sucuriscan-maincontent .alternate{background:#f5f5f5}
241
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
inc/tpl/base.html.tpl CHANGED
@@ -26,7 +26,7 @@
26
27
<div class="sucuriscan-ad">
28
<h2>Is your website infected with malware? Blacklisted by Google?</h2>
29
- <p>Don't know where to start? Get cleared today by <a href="http://sucuri.net/signup">Sucuri Security</a>!</p>
30
<p><a href="http://sucuri.net/tour" target="_blank" class="button-primary">Read more</a></p>
31
</div>
32
26
27
<div class="sucuriscan-ad">
28
<h2>Is your website infected with malware? Blacklisted by Google?</h2>
29
+ <p>Don't know where to start? Get cleared today by <a href="http://sucuri.net/signup" target="_blank">Sucuri Security</a>!</p>
30
<p><a href="http://sucuri.net/tour" target="_blank" class="button-primary">Read more</a></p>
31
</div>
32
inc/tpl/infosys-htaccess.html.tpl CHANGED
@@ -11,7 +11,7 @@
11
modifies this file to be able to handle pretty permalinks.
12
</p>
13
14
- <div class="sucuriscan-alert-%%SUCURI.HTAccess.MessageType%% %%SUCURI.HTAccess.MessageVisible%%">
15
<p>%%SUCURI.HTAccess.Message%%</p>
16
</div>
17
11
modifies this file to be able to handle pretty permalinks.
12
</p>
13
14
+ <div class="sucuriscan-inline-alert-%%SUCURI.HTAccess.MessageType%% sucuriscan-%%SUCURI.HTAccess.MessageVisible%%">
15
<p>%%SUCURI.HTAccess.Message%%</p>
16
</div>
17
inc/tpl/infosys.html.tpl CHANGED
@@ -2,10 +2,7 @@
2
<div class="sucuriscan-tabs">
3
<ul>
4
<li>
5
- <a href="#" data-tabname="server-info">Plugin & Server Info</a>
6
- </li>
7
- <li>
8
- <a href="#" data-tabname="loggedin-users">Logged In Users</a>
9
</li>
10
<li>
11
<a href="#" data-tabname="wordpress-cronjobs">WordPress Cronjobs</a>
@@ -23,10 +20,6 @@
23
%%SUCURI.ServerInfo%%
24
</div>
25
26
- <div id="sucuriscan-loggedin-users">
27
- %%SUCURI.LoggedInUsers%%
28
- </div>
29
-
30
<div id="sucuriscan-wordpress-cronjobs">
31
%%SUCURI.Cronjobs%%
32
</div>
2
<div class="sucuriscan-tabs">
3
<ul>
4
<li>
5
+ <a href="#" data-tabname="server-info">Plugin &amp; Server Info</a>
6
</li>
7
<li>
8
<a href="#" data-tabname="wordpress-cronjobs">WordPress Cronjobs</a>
20
%%SUCURI.ServerInfo%%
21
</div>
22
23
<div id="sucuriscan-wordpress-cronjobs">
24
%%SUCURI.Cronjobs%%
25
</div>
inc/tpl/integrity-auditlogs.html.tpl CHANGED
@@ -2,13 +2,7 @@
2
<table class="wp-list-table widefat sucuriscan-table sucuriscan-table-double-title sucuriscan-auditlogs">
3
<thead>
4
<tr>
5
- <th colspan="2" class="thead-with-button">
6
- <span>Audit Logs (%%SUCURI.AuditLogs.Count%% logs)</span>
7
- <form action="%%SUCURI.URL.Home%%" method="post" class="thead-topright-action">
8
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
9
- <button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
10
- </form>
11
- </th>
12
</tr>
13
<tr>
14
<th width="150">Date &amp; Time</th>
@@ -19,19 +13,17 @@
19
<tbody>
20
%%SUCURI.AuditLogs.List%%
21
22
- <tr class="sucuriscan-%%SUCURI.AuditLogs.MaxItemsVisibility%%">
23
<td colspan="2">
24
- <div class="sucuriscan-maxper-page">
25
- Showing <b>%%SUCURI.AuditLogs.MaxPerPage%%</b> out of <b>%%SUCURI.AuditLogs.Count%%</b>
26
- &nbsp;-&nbsp;
27
- <a href="%%SUCURI.URL.Core_integrity%%&show_all=1">Show all</a>
28
- </div>
29
</td>
30
</tr>
31
32
- <tr class="sucuriscan-%%SUCURI.AuditLogs.NoItemsVisibility%%">
33
<td colspan="2">
34
- <em>No logs so far.</em>
35
</td>
36
</tr>
37
</tbody>
2
<table class="wp-list-table widefat sucuriscan-table sucuriscan-table-double-title sucuriscan-auditlogs">
3
<thead>
4
<tr>
5
+ <th colspan="2">Audit Logs (%%SUCURI.AuditLogs.Count%% latest logs)</th>
6
</tr>
7
<tr>
8
<th width="150">Date &amp; Time</th>
13
<tbody>
14
%%SUCURI.AuditLogs.List%%
15
16
+ <tr class="sucuriscan-%%SUCURI.AuditLogs.NoItemsVisibility%%">
17
<td colspan="2">
18
+ <em>No logs so far.</em>
19
</td>
20
</tr>
21
22
+ <tr class="sucuriscan-%%SUCURI.AuditLogs.PaginationVisibility%%">
23
<td colspan="2">
24
+ <ul class="sucuriscan-pagination">
25
+ %%SUCURI.AuditLogs.PaginationLinks%%
26
+ </ul>
27
</td>
28
</tr>
29
</tbody>
inc/tpl/integrity-wpoutdate.html.tpl CHANGED
@@ -12,3 +12,18 @@
12
</p>
13
</div>
14
</div>
12
</p>
13
</div>
14
</div>
15
+
16
+ <div class="postbox sucuriscan-wordpress-beta sucuriscan-border sucuriscan-border-info sucuriscan-%%SUCURI.WordPressBeta.Visibility%%">
17
+ <h3>WordPress beta version</h3>
18
+
19
+ <div class="inside">
20
+ <p>
21
+ You are using a development version of WordPress. Beta testers will have a set up to
22
+ install updates of future beta versions automatically. You can update to the latest
23
+ nightly build <code>%%SUCURI.WordPressBeta.Version%%</code> automatically from
24
+ <a href="%%SUCURI.WordPressBeta.UpdateURL%%" target="_blank">here</a> or download the
25
+ nightly build from <a href="%%SUCURI.WordPressBeta.DownloadURL%%" target="_blank">here</a>
26
+ and install it manually.
27
+ </p>
28
+ </div>
29
+ </div>
inc/tpl/lastlogins-admins-lastlogin.snippet.tpl CHANGED
@@ -1,5 +1,5 @@
1
2
<tr class="%%SUCURI.AdminUsers.CssClass%%">
3
- <td><span class="sucuriscan-monospace">%%SUCURI.AdminUsers.RemoteAddr%%</span></td>
4
<td><span class="sucuriscan-monospace">%%SUCURI.AdminUsers.Datetime%%</span></td>
5
</tr>
1
2
<tr class="%%SUCURI.AdminUsers.CssClass%%">
3
+ <td><span class="sucuriscan-monospace sucuriscan-ellipsis">%%SUCURI.AdminUsers.RemoteAddr%%</span></td>
4
<td><span class="sucuriscan-monospace">%%SUCURI.AdminUsers.Datetime%%</span></td>
5
</tr>
inc/tpl/lastlogins-admins.html.tpl CHANGED
@@ -2,8 +2,8 @@
2
<table class="wp-list-table widefat sucuriscan-table sucuriscan-table-double-title sucuriscan-adminusers">
3
<thead>
4
<tr>
5
- <th class="manage-column">Username</th>
6
- <th class="manage-column">Email</th>
7
<th class="manage-column">Last Logins (newest to oldest)</th>
8
<th class="manage-column">&nbsp;</th>
9
</tr>
2
<table class="wp-list-table widefat sucuriscan-table sucuriscan-table-double-title sucuriscan-adminusers">
3
<thead>
4
<tr>
5
+ <th class="manage-column">User</th>
6
+ <th class="manage-column">Registration</th>
7
<th class="manage-column">Last Logins (newest to oldest)</th>
8
<th class="manage-column">&nbsp;</th>
9
</tr>
inc/tpl/lastlogins-admins.snippet.tpl CHANGED
@@ -1,13 +1,13 @@
1
2
<tr>
3
- <td>%%SUCURI.AdminUsers.Username%%</td>
4
- <td><a href="mailto:%%SUCURI.AdminUsers.Email%%">%%SUCURI.AdminUsers.Email%%</a></td>
5
<td class="adminusers-lastlogin">
6
<div class="sucuriscan-%%SUCURI.AdminUsers.NoLastLogins%%">
7
<i>There isn't information available for this account.</i>
8
</div>
9
10
- <table class="widefat sucuriscan-%%SUCURI.AdminUsers.NoLastLoginsTable%%">
11
<thead>
12
<tr>
13
<th>IP Address</th>
1
2
<tr>
3
+ <td><a href="mailto:%%SUCURI.AdminUsers.Email%%">%%SUCURI.AdminUsers.Username%%</a></td>
4
+ <td>%%SUCURI.AdminUsers.RegisteredAt%%</td>
5
<td class="adminusers-lastlogin">
6
<div class="sucuriscan-%%SUCURI.AdminUsers.NoLastLogins%%">
7
<i>There isn't information available for this account.</i>
8
</div>
9
10
+ <table class="widefat sucuriscan-admins-lastlogins sucuriscan-%%SUCURI.AdminUsers.NoLastLoginsTable%%">
11
<thead>
12
<tr>
13
<th>IP Address</th>
inc/tpl/lastlogins-all.html.tpl CHANGED
@@ -3,8 +3,10 @@
3
<thead>
4
<tr>
5
<th colspan="6" class="thead-with-button">
6
- <span>User logins (latest %%SUCURI.UserListLimit%%, newest to oldest)</span>
7
- <a href="%%SUCURI.CurrentURL%%&limit=0" class="button button-primary lastlogins-showall thead-topright-action sucuriscan-%%SUCURI.UserList.ShowAll%%">Show all results</a>
8
</th>
9
</tr>
10
<tr>
@@ -19,5 +21,19 @@
19
20
<tbody>
21
%%SUCURI.UserList%%
22
</tbody>
23
</table>
3
<thead>
4
<tr>
5
<th colspan="6" class="thead-with-button">
6
+ <span>User last logins</span>
7
+ <span class="thead-topright-action sucuriscan-lastlogin-outof">
8
+ %%SUCURI.UserList.Limit%% per page out of %%SUCURI.UserList.Total%%
9
+ </span>
10
</th>
11
</tr>
12
<tr>
21
22
<tbody>
23
%%SUCURI.UserList%%
24
+
25
+ <tr class="sucuriscan-%%SUCURI.UserList.NoItemsVisibility%%">
26
+ <td colspan="6">
27
+ <em>No logs so far.</em>
28
+ </td>
29
+ </tr>
30
+
31
+ <tr class="sucuriscan-%%SUCURI.UserList.PaginationVisibility%%">
32
+ <td colspan="6">
33
+ <ul class="sucuriscan-pagination">
34
+ %%SUCURI.UserList.Pagination%%
35
+ </ul>
36
+ </td>
37
+ </tr>
38
</tbody>
39
</table>
inc/tpl/lastlogins-all.snippet.tpl CHANGED
@@ -1,7 +1,8 @@
1
<tr class="%%SUCURI.UserList.CssClass%%">
2
<td>%%SUCURI.UserList.Number%%</td>
3
<td>%%SUCURI.UserList.Displayname%% (%%SUCURI.UserList.Username%%)</td>
4
- <td><span class="sucuriscan-ellipsis" title="%%SUCURI.UserList.RemoteAddr%%">%%SUCURI.UserList.RemoteAddr%%</span></td>
5
<td><span class="sucuriscan-ellipsis" title="%%SUCURI.UserList.Hostname%%">%%SUCURI.UserList.Hostname%%</span></td>
6
<td><span title="%%SUCURI.UserList.Datetime%%">%%SUCURI.UserList.TimeAgo%%</span></td>
7
<td><a href="%%SUCURI.UserList.UserURL%%" target="_blank">Edit</a></td>
1
+
2
<tr class="%%SUCURI.UserList.CssClass%%">
3
<td>%%SUCURI.UserList.Number%%</td>
4
<td>%%SUCURI.UserList.Displayname%% (%%SUCURI.UserList.Username%%)</td>
5
+ <td><span class="sucuriscan-ellipsis sucuriscan-monospace" title="%%SUCURI.UserList.RemoteAddr%%">%%SUCURI.UserList.RemoteAddr%%</span></td>
6
<td><span class="sucuriscan-ellipsis" title="%%SUCURI.UserList.Hostname%%">%%SUCURI.UserList.Hostname%%</span></td>
7
<td><span title="%%SUCURI.UserList.Datetime%%">%%SUCURI.UserList.TimeAgo%%</span></td>
8
<td><a href="%%SUCURI.UserList.UserURL%%" target="_blank">Edit</a></td>
inc/tpl/lastlogins-failedlogins.html.tpl ADDED
@@ -0,0 +1,48 @@
1
+
2
+ <div id="poststuff">
3
+ <div class="postbox sucuriscan-border sucuriscan-table-description">
4
+ <h3>Failed logins</h3>
5
+
6
+ <div class="inside">
7
+ <p>
8
+ This information will be used to determine if your site is being victim of a brute-force attack using the
9
+ <a href="http://kb.sucuri.net/definitions/attacks/brute-force/password-guessing" target="_blank">password
10
+ guessing</a> technique. Multiple failed logins will be considered part of the attack if there are more than
11
+ <code>%%SUCURI.FailedLogins.MaxFailedLogins%%</code> during the same hour, that's why you will only see
12
+ <em>(in this table)</em> information of the last hour, previous reports will be sent to your email if you
13
+ checked the alert option in the settings page to receive notifications of brute-force attacks.
14
+ </p>
15
+
16
+ <div class="sucuriscan-inline-alert-error sucuriscan-%%SUCURI.FailedLogins.WarningVisibility%%">
17
+ <p>
18
+ The option to notify possible <strong>password guessing</strong> attacks is
19
+ disabled, failed logins reports will not be sent to your email when they occur.
20
+ Go to the <a href="%%SUCURI.URL.Settings%%#settings-notifications">notification
21
+ settings</a> to enable the brute-force attack alerts.
22
+ </p>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-lastlogins-failed sucuriscan-%%SUCURI.IgnoreRules.TableVisibility%%">
29
+ <thead>
30
+ <tr>
31
+ <th width="20">No.</th>
32
+ <th>User</th>
33
+ <th>IP Address</th>
34
+ <th>Date/Time</th>
35
+ <th width="400">User-Agent</th>
36
+ </tr>
37
+ </thead>
38
+
39
+ <tbody>
40
+ %%SUCURI.FailedLogins.List%%
41
+
42
+ <tr class="sucuriscan-%%SUCURI.FailedLogins.NoItemsVisibility%%">
43
+ <td colspan="5">
44
+ <em>No logs so far.</em>
45
+ </td>
46
+ </tr>
47
+ </tbody>
48
+ </table>
inc/tpl/lastlogins-failedlogins.snippet.tpl ADDED
@@ -0,0 +1,8 @@
1
+
2
+ <tr class="%%SUCURI.FailedLogins.CssClass%%">
3
+ <td>%%SUCURI.FailedLogins.Num%%</td>
4
+ <td>%%SUCURI.FailedLogins.Username%%</td>
5
+ <td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.RemoteAddr%%</span></td>
6
+ <td><em>%%SUCURI.FailedLogins.Datetime%%</em></td>
7
+ <td><div class="sucuriscan-wraptext">%%SUCURI.FailedLogins.UserAgent%%</div></td>
8
+ </tr>
inc/tpl/{infosys-loggedin.html.tpl → lastlogins-loggedin.html.tpl} RENAMED
@@ -2,7 +2,7 @@
2
<table class="wp-list-table widefat sucuriscan-loggedin-users">
3
<thead>
4
<tr>
5
- <th colspan="6">Logged in Users (%%SUCURI.LoggedInUsers.Total%% users)</th>
6
</tr>
7
<tr>
8
<th>ID</th>
2
<table class="wp-list-table widefat sucuriscan-loggedin-users">
3
<thead>
4
<tr>
5
+ <th colspan="6">Logged in users (%%SUCURI.LoggedInUsers.Total%% users)</th>
6
</tr>
7
<tr>
8
<th>ID</th>
inc/tpl/{infosys-loggedin.snippet.tpl → lastlogins-loggedin.snippet.tpl} RENAMED
@@ -1,3 +1,4 @@
1
<tr class="%%SUCURI.LoggedInUsers.CssClass%%">
2
<td>%%SUCURI.LoggedInUsers.Id%%</td>
3
<td><a href="mailto:%%SUCURI.LoggedInUsers.UserEmail%%">%%SUCURI.LoggedInUsers.UserLogin%%</a></td>
1
+
2
<tr class="%%SUCURI.LoggedInUsers.CssClass%%">
3
<td>%%SUCURI.LoggedInUsers.Id%%</td>
4
<td><a href="mailto:%%SUCURI.LoggedInUsers.UserEmail%%">%%SUCURI.LoggedInUsers.UserLogin%%</a></td>
inc/tpl/lastlogins.html.tpl CHANGED
@@ -7,6 +7,12 @@
7
<li>
8
<a href="#" data-tabname="lastlogins-admins">Admin Users</a>
9
</li>
10
</ul>
11
12
<div class="sucuriscan-tab-containers">
@@ -17,5 +23,13 @@
17
<div id="sucuriscan-lastlogins-admins">
18
%%SUCURI.LastLogins.Admins%%
19
</div>
20
</div>
21
</div>
7
<li>
8
<a href="#" data-tabname="lastlogins-admins">Admin Users</a>
9
</li>
10
+ <li>
11
+ <a href="#" data-tabname="loggedin-users">Logged In Users</a>
12
+ </li>
13
+ <li>
14
+ <a href="#" data-tabname="failed-logins">Failed Logins</a>
15
+ </li>
16
</ul>
17
18
<div class="sucuriscan-tab-containers">
23
<div id="sucuriscan-lastlogins-admins">
24
%%SUCURI.LastLogins.Admins%%
25
</div>
26
+
27
+ <div id="sucuriscan-loggedin-users">
28
+ %%SUCURI.LoggedInUsers%%
29
+ </div>
30
+
31
+ <div id="sucuriscan-failed-logins">
32
+ %%SUCURI.FailedLogins%%
33
+ </div>
34
</div>
35
</div>
inc/tpl/monitoring-settings.html.tpl CHANGED
@@ -4,7 +4,7 @@
4
<tr>
5
<td width="200"><label>CloudProxy API key</label></td>
6
<td class="td-with-button">
7
- <form method="post" class="sucuriscan-monitoring-apikey-form">
8
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
9
<input type="text" name="sucuriscan_cloudproxy_apikey" value="%%SUCURI.Monitoring.APIKey%%" class="input-text" />
10
<input type="submit" value="Save" class="button button-primary" />
@@ -17,7 +17,7 @@
17
<tr class="alternate sucuriscan-%%SUCURI.Monitoring.SettingsVisibility%%">
18
<td><label>Clear cache</label></td>
19
<td class="td-with-button">
20
- <form method="post" class="sucuriscan-monitoring-clear-cache-form">
21
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
22
<input type="hidden" name="sucuriscan_clear_cache" value="1" />
23
<input type="submit" value="Clear Cache" class="button button-primary" />
4
<tr>
5
<td width="200"><label>CloudProxy API key</label></td>
6
<td class="td-with-button">
7
+ <form action="%%SUCURI.URL.Monitoring%%#monitoring-settings" method="post" class="sucuriscan-monitoring-apikey-form">
8
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
9
<input type="text" name="sucuriscan_cloudproxy_apikey" value="%%SUCURI.Monitoring.APIKey%%" class="input-text" />
10
<input type="submit" value="Save" class="button button-primary" />
17
<tr class="alternate sucuriscan-%%SUCURI.Monitoring.SettingsVisibility%%">
18
<td><label>Clear cache</label></td>
19
<td class="td-with-button">
20
+ <form action="%%SUCURI.URL.Monitoring%%#monitoring-settings" method="post" class="sucuriscan-monitoring-clear-cache-form">
21
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
22
<input type="hidden" name="sucuriscan_clear_cache" value="1" />
23
<input type="submit" value="Clear Cache" class="button button-primary" />
inc/tpl/posthack-databasebackups.html.tpl DELETED
@@ -1,41 +0,0 @@
1
-
2
- <form action="%%SUCURI.URL.Posthack%%#database-backups" method="post">
3
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
4
- <input type="hidden" name="sucuriscan_database_backup" value="1" />
5
- <input type="hidden" name="sucuriscan_process_form" value="1" />
6
-
7
- <table class="wp-list-table widefat">
8
- <thead>
9
- <tr>
10
- <th colspan="5" class="thead-with-button">
11
- <span>Database Backups</span>
12
- <div class="generate-dbbackup-form thead-topright-action">
13
- <input type="submit" name="generate_dbbackup" value="Generate DB Backup" class="button button-primary" />
14
- </div>
15
- </th>
16
- </tr>
17
- <tr>
18
- <th class="manage-column column-cb check-column">
19
- <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
20
- <input id="cb-select-all-1" type="checkbox">
21
- </th>
22
- <th class="manage-column">Filename</th>
23
- <th class="manage-column">Type</th>
24
- <th class="manage-column">Size</th>
25
- <th class="manage-column">Date/Time</th>
26
- </tr>
27
- </thead>
28
-
29
- <tbody>
30
- %%SUCURI.BackupList%%
31
- </tbody>
32
-
33
- <tfoot>
34
- <tr>
35
- <td colspan="5">
36
- <input type="submit" name="remove_dbbackup" value="Remove selected files" class="button button-primary" />
37
- </td>
38
- </tr>
39
- </tfoot>
40
- </table>
41
- </form>
inc/tpl/posthack-databasebackups.snippet.tpl DELETED
@@ -1,10 +0,0 @@
1
-
2
- <tr class="%%SUCURI.BackupList.CssClass%%">
3
- <th class="check-column">
4
- <input type="checkbox" name="dbbackup_filenames[]" value="%%SUCURI.BackupList.Filename%%" />
5
- </th>
6
- <td><a href="%%SUCURI.BackupList.FileURL%%" target="_blank">%%SUCURI.BackupList.Filename%%</a></td>
7
- <td>%%SUCURI.BackupList.Filetype%%</td>
8
- <td>%%SUCURI.BackupList.Filesize%%</td>
9
- <td>%%SUCURI.BackupList.Filetime%%</td>
10
- </tr>
inc/tpl/posthack-resetpassword.html.tpl CHANGED
@@ -7,7 +7,7 @@
7
<input type="hidden" name="sucuriscan_reset_password" value="1" />
8
9
<p>
10
- Use this button to reset the current password for some specific users or for all
11
of them. We will send an email to each of those users adivising the password change
12
that includes the new password automatically generated by WordPress. After the
13
password reset your current session will be closed and you'll need to login again.
7
<input type="hidden" name="sucuriscan_reset_password" value="1" />
8
9
<p>
10
+ Use this tool to reset the current password for some specific users or for all
11
of them. We will send an email to each of those users adivising the password change
12
that includes the new password automatically generated by WordPress. After the
13
password reset your current session will be closed and you'll need to login again.
inc/tpl/{resetpassword.snippet.tpl → posthack-resetpassword.snippet.tpl} RENAMED
@@ -1,6 +1,7 @@
1
<tr class="%%SUCURI.ResetPassword.CssClass%%">
2
<td class="check-column">
3
- <input type="checkbox" name="user_ids[]" value="%%SUCURI.ResetPassword.UserId%%" />
4
</td>
5
<td>%%SUCURI.ResetPassword.Displayname%% (%%SUCURI.ResetPassword.Username%%)</td>
6
<td><a href="mailto:%%SUCURI.ResetPassword.Email%%">%%SUCURI.ResetPassword.Email%%</a></td>
1
+
2
<tr class="%%SUCURI.ResetPassword.CssClass%%">
3
<td class="check-column">
4
+ <input type="checkbox" name="user_ids[]" value="%%SUCURI.ResetPassword.UserId%%" />
5
</td>
6
<td>%%SUCURI.ResetPassword.Displayname%% (%%SUCURI.ResetPassword.Username%%)</td>
7
<td><a href="mailto:%%SUCURI.ResetPassword.Email%%">%%SUCURI.ResetPassword.Email%%</a></td>
inc/tpl/posthack-resetplugins.html.tpl ADDED
@@ -0,0 +1,49 @@
1
+
2
+ <div id="poststuff" class="sucuriscan-reset-plugins">
3
+ <div class="postbox">
4
+ <div class="inside">
5
+ <form action="%%SUCURI.URL.Posthack%%#reset-plugins" method="post">
6
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
7
+ <input type="hidden" name="sucuriscan_reset_plugins" value="1" />
8
+
9
+ <p>
10
+ In case that you suspect of an infection in your site, or even after you got rid
11
+ of a malicious code, it would be better if you <strong>re-install</strong> all
12
+ the plugins installed in your site, including the ones you are not using
13
+ <em>(aka. deactivated)</em>. Select from the list bellow the plugins you want to
14
+ reset <em>(it is recommended to select them all)</em>, be aware that
15
+ <strong>premium plugins will not be re-installed</strong>.
16
+ </p>
17
+
18
+ <table class="wp-list-table widefat sucuriscan-table">
19
+ <thead>
20
+ <tr>
21
+ <th class="manage-column column-cb check-column">
22
+ <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
23
+ <input id="cb-select-all-1" type="checkbox">
24
+ </th>
25
+ <th class="manage-column">Plugin</th>
26
+ <th class="manage-column">Version</th>
27
+ <th class="manage-column">Type</th>
28
+ <th class="manage-column">Status</th>
29
+ </tr>
30
+ </thead>
31
+
32
+ <tbody>
33
+ %%SUCURI.ResetPlugin.PluginList%%
34
+ </tbody>
35
+ </table>
36
+
37
+ <p>
38
+ <label>
39
+ <input type="hidden" name="sucuriscan_process_form" value="0" />
40
+ <input type="checkbox" name="sucuriscan_process_form" value="1" />
41
+ <span>I understand that this operation can not be reverted.</span>
42
+ </label>
43
+ </p>
44
+
45
+ <input type="submit" value="Process selected items" class="button button-primary" />
46
+ </form>
47
+ </div>
48
+ </div>
49
+ </div>
inc/tpl/posthack-resetplugins.snippet.tpl ADDED
@@ -0,0 +1,10 @@
1
+
2
+ <tr class="%%SUCURI.ResetPlugin.CssClass%%">
3
+ <td class="check-column">
4
+ <input type="checkbox" name="plugin_path[]" value="%%SUCURI.ResetPlugin.PluginPath%%" %%SUCURI.ResetPlugin.Disabled%% />
5
+ </td>
6
+ <td>%%SUCURI.ResetPlugin.Plugin%%</td>
7
+ <td><span class="sucuriscan-monospace">%%SUCURI.ResetPlugin.Version%%</span></td>
8
+ <td><span class="sucuriscan-label-%%SUCURI.ResetPlugin.TypeClass%%">%%SUCURI.ResetPlugin.Type%%</span></td>
9
+ <td><span class="sucuriscan-label-%%SUCURI.ResetPlugin.StatusClass%%">%%SUCURI.ResetPlugin.Status%%</span></td>
10
+ </tr>
inc/tpl/posthack.html.tpl CHANGED
@@ -1,5 +1,4 @@
1
2
-
3
<div class="sucuriscan-tabs">
4
<ul>
5
<li>
@@ -9,7 +8,7 @@
9
<a href="#" data-tabname="reset-users-password">Reset User's Password</a>
10
</li>
11
<li>
12
- <a href="#" data-tabname="database-backups">Database Backups</a>
13
</li>
14
</ul>
15
@@ -22,8 +21,8 @@
22
%%SUCURI.ResetPassword%%
23
</div>
24
25
- <div id="sucuriscan-database-backups">
26
- %%SUCURI.DatabaseBackups%%
27
</div>
28
</div>
29
</div>
1
2
<div class="sucuriscan-tabs">
3
<ul>
4
<li>
8
<a href="#" data-tabname="reset-users-password">Reset User's Password</a>
9
</li>
10
<li>
11
+ <a href="#" data-tabname="reset-plugins">Reset Plugins</a>
12
</li>
13
</ul>
14
21
%%SUCURI.ResetPassword%%
22
</div>
23
24
+ <div id="sucuriscan-reset-plugins">
25
+ %%SUCURI.ResetPlugins%%
26
</div>
27
</div>
28
</div>
inc/tpl/settings-general.html.tpl ADDED
@@ -0,0 +1,149 @@
1
+
2
+ %%SUCURI.ModalWhenAPIRegistered%%
3
+
4
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings">
5
+ <thead>
6
+ <tr>
7
+ <th colspan="3" class="thead-with-button">
8
+ <span>Plugin Settings</span>
9
+ <form method="post" class="thead-topright-action">
10
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
11
+ <button type="submit" name="sucuriscan_reset_options" class="button-primary">Reset plugin options</button>
12
+ </form>
13
+ </th>
14
+ </tr>
15
+ </thead>
16
+
17
+ <tbody>
18
+
19
+ <tr>
20
+ <td colspan="3">
21
+ <p>
22
+ Most of the tools in this plugin can be used without a specific configuration,
23
+ but the core features <strong>require an API key</strong> to communicate with
24
+ the Sucuri services. The key is generated using your administrator e-mail and
25
+ the domain of this site, this will allow you to have access to our free
26
+ monitoring tool forever even if you remove the API key and generate it again.
27
+ </p>
28
+ </td>
29
+ </tr>
30
+
31
+ <tr class="alternate">
32
+ <td>API Key</td>
33
+ <td>
34
+ <span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
35
+ </td>
36
+ <td class="td-with-button">
37
+ <form method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
38
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
39
+ <button type="submit" name="sucuriscan_recover_api_key" class="button-primary">Recover</button>
40
+ </form>
41
+
42
+ <form method="post" class="sucuriscan-%%SUCURI.APIKey.ManualKeyFormVisibility%%">
43
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
44
+ <input type="text" name="sucuriscan_manual_api_key" class="input-text" placeholder="API key sent to your email" />
45
+ <button type="submit" class="button-primary">Save</button>
46
+ </form>
47
+
48
+ <form method="post" class="sucuriscan-%%SUCURI.APIKey.RemoveVisibility%%">
49
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
50
+ <button type="submit" name="sucuriscan_remove_api_key" class="button-primary button-danger">Remove</button>
51
+ </form>
52
+ </td>
53
+ </tr>
54
+
55
+ <tr>
56
+ <td>Last Scanning</td>
57
+ <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
58
+ <td class="td-with-button">
59
+ <form action="%%SUCURI.URL.Home%%" method="post">
60
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
61
+ <button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
62
+ </form>
63
+ </td>
64
+ </tr>
65
+
66
+ <tr class="alternate">
67
+ <td>Notify events to</td>
68
+ <td><a href="mailto:%%SUCURI.NotifyTo%%">%%SUCURI.NotifyTo%%</a></td>
69
+ <td class="td-with-button">
70
+ <form method="post">
71
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
72
+ <input type="text" name="sucuriscan_notify_to" class="input-text" placeholder="Send notifications to..." />
73
+ <button type="submit" class="button-primary">Change</button>
74
+ </form>
75
+ </td>
76
+ </tr>
77
+
78
+ <tr>
79
+ <td>Alerts per hour</td>
80
+ <td>%%SUCURI.EmailsPerHour%%</td>
81
+ <td class="td-with-button">
82
+ <form method="post">
83
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
84
+ <select name="sucuriscan_emails_per_hour">
85
+ %%SUCURI.EmailsPerHourOptions%%
86
+ </select>
87
+ <button type="submit" class="button-primary">Change</button>
88
+ </form>
89
+ </td>
90
+ </tr>
91
+
92
+ <tr class="alternate">
93
+ <td>Consider brute-force after</td>
94
+ <td>%%SUCURI.MaximumFailedLogins%%</td>
95
+ <td class="td-with-button">
96
+ <form method="post">
97
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
98
+ <select name="sucuriscan_maximum_failed_logins">
99
+ %%SUCURI.MaximumFailedLoginsOptions%%
100
+ </select>
101
+ <button type="submit" class="button-primary">Change</button>
102
+ </form>
103
+ </td>
104
+ </tr>
105
+
106
+ <tr>
107
+ <td>Verify SSL Cert</td>
108
+ <td>%%SUCURI.VerifySSLCert%%</td>
109
+ <td class="td-with-button">
110
+ <form method="post">
111
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
112
+ <select name="sucuriscan_verify_ssl_cert">
113
+ %%SUCURI.VerifySSLCertOptions%%
114
+ </select>
115
+ <button type="submit" class="button-primary">Change</button>
116
+ </form>
117
+ </td>
118
+ </tr>
119
+
120
+ <tr class="alternate">
121
+ <td>Scanning frequency</td>
122
+ <td><span class="sucuriscan-monospace">%%SUCURI.ScanningFrequency%%</span></td>
123
+ <td class="td-with-button">
124
+ <form method="post">
125
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
126
+ <select name="sucuriscan_scan_frequency">
127
+ %%SUCURI.ScanningFrequencyOptions%%
128
+ </select>
129
+ <button type="submit" class="button-primary">Change</button>
130
+ </form>
131
+ </td>
132
+ </tr>
133
+
134
+ <tr class="sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
135
+ <td>Scanning interface</td>
136
+ <td><span class="sucuriscan-monospace">%%SUCURI.ScanningInterface%%</span></td>
137
+ <td class="td-with-button">
138
+ <form method="post">
139
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
140
+ <select name="sucuriscan_scan_interface">
141
+ %%SUCURI.ScanningInterfaceOptions%%
142
+ </select>
143
+ <button type="submit" class="button-primary">Change</button>
144
+ </form>
145
+ </td>
146
+ </tr>
147
+
148
+ </tbody>
149
+ </table>
inc/tpl/settings-ignorerules.html.tpl ADDED
@@ -0,0 +1,59 @@
1
+
2
+ <div id="poststuff">
3
+ <div class="postbox sucuriscan-border sucuriscan-border-bad sucuriscan-%%SUCURI.IgnoreRules.MessageVisibility%%">
4
+ <h3>Ignore Notifications</h3>
5
+
6
+ <div class="inside">
7
+ <p>
8
+ It seems that you disabled the email notifications for <strong>new site
9
+ content</strong>, this panel is intended to provide a way to ignore specific
10
+ events in your site and with that the alerts reported to your email. Since you
11
+ have deactivated the <strong>new site content</strong> alerts, this panel will
12
+ be disabled too.
13
+ </p>
14
+ </div>
15
+ </div>
16
+ </div>
17
+
18
+ <div id="poststuff">
19
+ <div class="postbox sucuriscan-border sucuriscan-table-description sucuriscan-%%SUCURI.IgnoreRules.TableVisibility%%">
20
+ <h3>Ignore Notifications</h3>
21
+
22
+ <div class="inside">
23
+ <p>
24
+ This is a list of registered <a href="http://codex.wordpress.org/Post_Types"
25
+ target="_blank">Post Types</a>, since you have enabled the email notifications
26
+ for <strong>new site content</strong>, we will send you an alert if any of these
27
+ <code>post-types</code> are changed. You may want to ignore some of them, in
28
+ which case you can use the buttons in the table bellow to do that.
29
+ </p>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-ignorerules sucuriscan-%%SUCURI.IgnoreRules.TableVisibility%%">
35
+ <thead>
36
+ <tr>
37
+ <th width="50">#Num</th>
38
+ <th>Post Type</th>
39
+ <th width="50">Ignored</th>
40
+ <th>Ignored At</th>
41
+ <th>&nbsp;</th>
42
+ </tr>
43
+ </thead>
44
+
45
+ <tbody>
46
+ %%SUCURI.IgnoreRules.PostTypes%%
47
+ </tbody>
48
+
49
+ <tfoot>
50
+ <tr>
51
+ <td colspan="5">
52
+ <em>
53
+ <strong>Notifications example:</strong>
54
+ <code>Post_Type</code> changed from private to published <code>#ID</code> (<code>Title</code>)
55
+ </em>
56
+ </td>
57
+ </tr>
58
+ </tfoot>
59
+ </table>
inc/tpl/settings-ignorerules.snippet.tpl ADDED
@@ -0,0 +1,15 @@
1
+
2
+ <tr class="%%SUCURI.IgnoreRules.CssClass%%">
3
+ <td>%%SUCURI.IgnoreRules.Num%%</td>
4
+ <td>%%SUCURI.IgnoreRules.PostTypeTitle%%</td>
5
+ <td><span class="sucuriscan-label-%%SUCURI.IgnoreRules.IsIgnoredClass%%">%%SUCURI.IgnoreRules.IsIgnored%%</span></td>
6
+ <td><em class="sucuriscan-monospace">%%SUCURI.IgnoreRules.WasIgnoredAt%%</em></td>
7
+ <td class="td-with-button">
8
+ <form action="%%SUCURI.URL.Settings%%#settings-ignorerules" method="post">
9
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
10
+ <input type="hidden" name="sucuriscan_ignorerule" value="%%SUCURI.IgnoreRules.PostType%%" />
11
+ <input type="hidden" name="sucuriscan_ignorerule_action" value="%%SUCURI.IgnoreRules.Action%%" />
12
+ <button type="submit" class="%%SUCURI.IgnoreRules.ButtonClass%%">%%SUCURI.IgnoreRules.ButtonText%%</button>
13
+ </form>
14
+ </td>
15
+ </tr>
inc/tpl/settings-notifications.html.tpl ADDED
@@ -0,0 +1,22 @@
1
+
2
+ <form action="%%SUCURI.URL.Settings%%#settings-notifications" method="post">
3
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-notifications">
4
+ <thead>
5
+ <tr>
6
+ <th colspan="3" class="thead-with-button">
7
+ <span>Email Alerts Settings</span>
8
+ <div class="thead-topright-action">
9
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
10
+ <button type="submit" name="sucuriscan_save_notification_settings" class="button-primary">Save</button>
11
+ </div>
12
+ </th>
13
+ </tr>
14
+ </thead>
15
+
16
+ <tbody>
17
+
18
+ %%SUCURI.NotificationOptions%%
19
+
20
+ </tbody>
21
+ </table>
22
+ </form>
inc/tpl/{settings-notification.snippet.tpl → settings-notifications.snippet.tpl} RENAMED
File without changes
inc/tpl/settings.html.tpl CHANGED
@@ -1,118 +1,28 @@
1
2
- %%SUCURI.ModalWhenAPIRegistered%%
3
-
4
- <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings">
5
- <thead>
6
- <tr>
7
- <th colspan="3" class="thead-with-button">
8
- <span>Plugin Settings</span>
9
- <form action="%%SUCURI.URL.Settings%%" method="post" class="thead-topright-action">
10
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
11
- <button type="submit" name="sucuriscan_reset_options" class="button-primary">Reset plugin options</button>
12
- </form>
13
- </th>
14
- </tr>
15
- </thead>
16
-
17
- <tbody>
18
-
19
- <tr>
20
- <td colspan="3">
21
- <p>
22
- Most of the tools in this plugin can be used without a specific configuration,
23
- but the core features <strong>require an API key</strong> to communicate with
24
- the Sucuri services. The key is generated using your administrator e-mail and
25
- the domain of this site, this will allow you to have access to our free
26
- monitoring tool forever even if you remove the API key and generate it again.
27
- </p>
28
- </td>
29
- </tr>
30
-
31
- <tr class="alternate">
32
- <td>API Key</td>
33
- <td>
34
- <span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
35
- </td>
36
- <td class="td-with-button">
37
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
38
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
39
- <button type="submit" name="sucuriscan_recover_api_key" class="button-primary">Recover</button>
40
- </form>
41
-
42
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.ManualKeyFormVisibility%%">
43
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
44
- <input type="text" name="sucuriscan_manual_api_key" class="input-text" placeholder="API key sent to your email" />
45
- <button type="submit" class="button-primary">Save</button>
46
- </form>
47
-
48
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.RemoveVisibility%%">
49
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
50
- <button type="submit" name="sucuriscan_remove_api_key" class="button-primary button-danger">Remove</button>
51
- </form>
52
- </td>
53
- </tr>
54
-
55
- <tr>
56
- <td>Last Scanning</td>
57
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
58
- <td class="td-with-button">
59
- <form action="%%SUCURI.URL.Home%%" method="post">
60
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
61
- <button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
62
- </form>
63
- </td>
64
- </tr>
65
-
66
- <tr class="alternate">
67
- <td>Scanning frequency</td>
68
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningFrequency%%</span></td>
69
- <td class="td-with-button">
70
- <form method="post">
71
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
72
- <select name="sucuriscan_scan_frequency">
73
- %%SUCURI.ScanningFrequencyOptions%%
74
- </select>
75
- <button type="submit" class="button-primary">Change</button>
76
- </form>
77
- </td>
78
- </tr>
79
-
80
- <tr class="sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
81
- <td>Scanning interface</td>
82
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningInterface%%</span></td>
83
- <td class="td-with-button">
84
- <form method="post">
85
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
86
- <select name="sucuriscan_scan_interface">
87
- %%SUCURI.ScanningInterfaceOptions%%
88
- </select>
89
- <button type="submit" class="button-primary">Change</button>
90
- </form>
91
- </td>
92
- </tr>
93
-
94
- </tbody>
95
- </table>
96
-
97
-
98
- <form method="post">
99
- <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-notifications">
100
- <thead>
101
- <tr>
102
- <th colspan="3" class="thead-with-button">
103
- <span>Email Alerts Settings</span>
104
- <div class="thead-topright-action">
105
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
106
- <button type="submit" name="sucuriscan_save_notification_settings" class="button-primary">Save</button>
107
- </div>
108
- </th>
109
- </tr>
110
- </thead>
111
-
112
- <tbody>
113
-
114
- %%SUCURI.NotificationOptions%%
115
-
116
- </tbody>
117
- </table>
118
- </form>
1
2
+ <div class="sucuriscan-tabs">
3
+ <ul>
4
+ <li>
5
+ <a href="#" data-tabname="settings-general">General Settings</a>
6
+ </li>
7
+ <li>
8
+ <a href="#" data-tabname="settings-notifications">Notification Settings</a>
9
+ </li>
10
+ <li>
11
+ <a href="#" data-tabname="settings-ignorerules">Ignore Notifications</a>
12
+ </li>
13
+ </ul>
14
+
15
+ <div class="sucuriscan-tab-containers">
16
+ <div id="sucuriscan-settings-general">
17
+ %%SUCURI.Settings.General%%
18
+ </div>
19
+
20
+ <div id="sucuriscan-settings-notifications">
21
+ %%SUCURI.Settings.Notifications%%
22
+ </div>
23
+
24
+ <div id="sucuriscan-settings-ignorerules">
25
+ %%SUCURI.Settings.IgnoreRules%%
26
+ </div>
27
+ </div>
28
+ </div>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: dd@sucuri.net
3
Donate Link: http://sitecheck.sucuri.net
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
Requires at least:3.2
6
- Stable tag:1.6.1
7
Tested up to: 3.9.1
8
9
The Sucuri Security - Auditing, SiteCheck Malware Scanner and Hardening is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It also includes post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
@@ -66,6 +66,20 @@ the compromise on your site).
66
67
== Changelog ==
68
69
= 1.6.1 =
70
* Initial release with new auditing options.
71
3
Donate Link: http://sitecheck.sucuri.net
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
Requires at least:3.2
6
+ Stable tag:1.6.4
7
Tested up to: 3.9.1
8
9
The Sucuri Security - Auditing, SiteCheck Malware Scanner and Hardening is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It also includes post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
66
67
== Changelog ==
68
69
+ = 1.6.4 =
70
+ * Fixed API generation bug.
71
+
72
+ = 1.6.3 =
73
+ * Added proper brute force alerts.
74
+ * Added option to restrict number of emails.
75
+ * Added more description to the emails.
76
+ * Added a list of failed login attempts inside the last login tab.
77
+
78
+ = 1.6.2 =
79
+ * Setting a maximum number of emails per hour.
80
+ * Fixing typos.
81
+
82
+
83
= 1.6.1 =
84
* Initial release with new auditing options.
85
sucuri.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Sucuri Security - Auditing, Malware Scanner and Hardening
4
Plugin URI: http://wordpress.sucuri.net/
5
Description: The <a href="http://sucuri.net/" target="_blank">Sucuri Security</a> <em>(Auditing, Malware Scanner and Hardening)</em> plugin enables you to scan your WordPress site using <a href="http://sitecheck.sucuri.net/" target="_blank">Sucuri SiteCheck</a> right in your dashboard. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
- Version: 1.6.1
8
Author URI: http://sucuri.net
9
*/
10
@@ -36,7 +36,7 @@ define('SUCURISCAN','sucuriscan');
36
/**
37
* Current version of the plugin's code.
38
*/
39
- define('SUCURISCAN_VERSION','1.6.1');
40
41
/**
42
* The local URL where the plugin's files and assets are served.
@@ -91,7 +91,7 @@ define('SUCURISCAN_CLOUDPROXY_API_VERSION', 'v2');
91
/**
92
* The maximum quantity of entries that will be displayed in the last login page.
93
*/
94
- define('SUCURISCAN_LASTLOGINS_USERSLIMIT', 50);
95
96
/**
97
* The maximum quantity of entries that will be displayed in the audit logs page.
@@ -108,6 +108,11 @@ define('SUCURISCAN_MINIMUM_RUNTIME', 10800);
108
*/
109
define('SUCURISCAN_SITECHECK_LIFETIME', 1200);
110
111
/**
112
* Miscellaneous library.
113
*
@@ -862,228 +867,6 @@ class SucuriScanDatabase extends SucuriScan {
862
863
}
864
865
- /**
866
- * Class responsible for the processing of the generation of backups for the database.
867
- *
868
- * Here are implemented the functions needed to get the list of databases, information
869
- * of single tables, generate the backup file (which can be a SQL or Zip file), a way
870
- * to download and remove old backup files.
871
- */
872
- class SucuriScanBackup extends SucuriScanDatabase {
873
-
874
- /**
875
- * Class constructor.
876
- */
877
- public function __construct(){
878
- ini_set('memory_limit', '-1');
879
- }
880
-
881
- /**
882
- * Generate a SQL or Zip file with the current state of the database in use.
883
- *
884
- * @return string Returns the SQL or Zip full file path created.
885
- */
886
- public function all_database(){
887
- $sql_output = '';
888
- $tables = $this->get_dbtables();
889
-
890
- foreach($tables as $table_name){
891
- $sql_output .= $this->single_table($table_name, TRUE);
892
- $sql_output .= PHP_EOL.PHP_EOL;
893
- }
894
-
895
- $sql_output .= PHP_EOL.PHP_EOL;
896
-
897
- return $this->generate_backup($sql_output);
898
- }
899
-
900
- /**
901
- * Generate a SQL or Zip file containing all the content inside a single table in the current database.
902
- *
903
- * @param string $table_name Specify the table name to dump.
904
- * @param boolean $batch_mode Specify whether if return the SQL generated or generate the SQL/Zip file.
905
- * @return string Returns the SQL generated or the SQL/Zip full file path created.
906
- */
907
- public function single_table( $table_name='', $batch_mode=FALSE ){
908
- global $wpdb;
909
-
910
- if( $wpdb->get_var("SHOW TABLES LIKE '{$table_name}'")==$table_name ){
911
- $sql_output = '';
912
-
913
- $results = $wpdb->get_results("SELECT * FROM `{$table_name}`", ARRAY_N);
914
- $fields = $wpdb->get_col("DESCRIBE `{$table_name}`", 0);
915
- $num_fields = count($fields);
916
-
917
- $sql_output .= "DROP TABLE IF EXISTS `{$table_name}`;";
918
- $table_definition = $wpdb->get_row("SHOW CREATE TABLE `{$table_name}`", ARRAY_N);
919
- $sql_output .= PHP_EOL.PHP_EOL . $table_definition[1].';' . PHP_EOL.PHP_EOL;
920
-
921
- foreach($results as $row){
922
- $sql_output .= "INSERT INTO `{$table_name}` VALUES(";
923
-
924
- for( $i=0; $i<$num_fields; $i++ ) {
925
- $row[$i] = esc_sql($row[$i]);
926
- $row[$i] = preg_replace('#'.PHP_EOL.'#', "\n", $row[$i]);
927
-
928
- if( isset($row[$i]) ){
929
- $sql_output .= "'{$row[$i]}'";
930
- } else {
931
- $sql_output .= "''";
932
- }
933
-
934
- if( $i < ($num_fields-1) ){
935
- $sql_output .= ','.chr(32);
936
- }
937
- }
938
-
939
- $sql_output .= ');'.PHP_EOL;
940
- }
941
-
942
- return $batch_mode===TRUE ? $sql_output : $this->generate_backup($sql_output);
943
- }
944
-
945
- return FALSE;
946
- }
947
-
948
- /**
949
- * Create a SQL or Zip file with the passed content.
950
- *
951
- * @param string $content SQL generated.
952
- * @return string|boolean Return FALSE or the SQL/Zip full file path created.
953
- */
954
- private function generate_backup( $content='' ){
955
- $plugin_upload_folder = $this->datastore_folder_path();
956
-
957
- if( is_writable($plugin_upload_folder) ){
958
- $filename = 'sucuri-dbbackup-'.current_time('timestamp').'.sql';
959
- $filepath = rtrim($plugin_upload_folder,'/').'/'.$filename;
960
- $handle = @fopen($filepath, 'w+');
961
- @fwrite($handle, $content);
962
- @fclose($handle);
963
-
964
- if( class_exists('ZipArchive') ){
965
- $package_path = $filepath.'.zip';
966
-
967
- $zip = new ZipArchive();
968
- $archive = $zip->open($package_path, ZipArchive::CREATE);
969
- $zip->addFile($filepath, $filename);
970
- $zip->close();
971
-
972
- if( file_exists($package_path) && filesize($package_path)>0 ){
973
- @unlink($filepath); /* Remove the old SQL file to keep the new Zip file */
974
- $filename = $filename.'.zip';
975
- $filepath = $package_path;
976
- }
977
- }
978
-
979
- return ( file_exists($filepath) && filesize($filepath)>0 ) ? $filepath : FALSE;
980
- } else {
981
- sucuriscan_error('Upload folder is not writable, can not continue with the backup: <code>'.$plugin_upload_folder.'</code>');
982
- }
983
-
984
- return FALSE;
985
- }
986
-
987
- /**
988
- * Get extra information of the filepath specified, including full filepath, filesize, timeatime, etc.
989
- *
990
- * @param string $filepath Relative path of the file.
991
- * @return object Extra information of the file specified.
992
- */
993
- private function get_backup_file_info( $filepath='' ){
994
- $backup_file = FALSE;
995
- $plugin_upload_folder = $this->datastore_folder_path();
996
-
997
- if( file_exists($filepath) && is_file($filepath) && is_readable($filepath) ){
998
- $filesize = filesize($filepath);
999
- $filename_exploded = explode('.', $filepath);
1000
- $backup_file = (object)array(
1001
- 'filepath' => $filepath,
1002
- 'filename' => basename($filepath),
1003
- 'filesize' => $filesize,
1004
- 'filehumansize' => $this->human_filesize($filesize),
1005
- 'filetime' => fileatime($filepath),
1006
- 'fileext' => array_pop($filename_exploded),
1007
- 'fileurl' => site_url( str_replace(ABSPATH, '', rtrim($plugin_upload_folder,'/').'/'.basename($filepath)) ),
1008
- );
1009
- }
1010
-
1011
- return $backup_file;
1012
- }
1013
-
1014
- /**
1015
- * List all database backup files generated with extra information.
1016
- *
1017
- * @return array Key-value list of backup files.
1018
- */
1019
- public function get_backup_files(){
1020
- $backup_files = array();
1021
- $plugin_upload_folder = $this->datastore_folder_path();
1022
-
1023
- $files = glob( rtrim($plugin_upload_folder,'/').'/sucuri-dbbackup*.{sql,zip}', GLOB_BRACE );
1024
- if( is_array($files) && !empty($files) ){
1025
- $files_ordered = array_reverse($files);
1026
-
1027
- foreach( $files_ordered as $filepath ){
1028
- $backup_file = $this->get_backup_file_info($filepath);
1029
-
1030
- if( $backup_file ){
1031
- $backup_files[] = $backup_file;
1032
- }
1033
- }
1034
- }
1035
-
1036
- return $backup_files;
1037
- }
1038
-
1039
- /**
1040
- * Get extra information of the filename specified, including full filepath, filesize, timeatime, etc.
1041
- *
1042
- * @param string $filename Simple filename with extension.
1043
- * @return object Extra information of the file specified.
1044
- */
1045
- public function get_backup_file_from_filename( $filename='' ){
1046
- $plugin_upload_folder = $this->datastore_folder_path();
1047
- $filepath = rtrim($plugin_upload_folder,'/').'/'.$filename;
1048
-
1049
- return $this->get_backup_file_info($filepath);
1050
- }
1051
-
1052
- /**
1053
- * Remove a list of backup files selected by the user through the plugin interface.
1054
- *
1055
- * @param array $files List of filenames that will be deleted.
1056
- * @return void
1057
- */
1058
- public function remove_backup_file( $files=array() ){
1059
- $files = is_array($files) ? $files : array($files);
1060
-
1061
- if( !empty($files) ){
1062
- $num_files_to_remove = count($files);
1063
- $num_removed_files = 0;
1064
-
1065
- foreach($files as $filename){
1066
- $backup_file = $this->get_backup_file_from_filename($filename);
1067
-
1068
- if($backup_file && @unlink($backup_file->filepath) ){
1069
- $num_removed_files += 1;
1070
- }
1071
- }
1072
-
1073
- $message = sprintf( 'Database backups removed: %d out of %d', $num_removed_files, $num_files_to_remove );
1074
-
1075
- if( $num_removed_files == $num_files_to_remove ){
1076
- sucuriscan_info( $message );
1077
- } else {
1078
- sucuriscan_error( $message );
1079
- }
1080
- } else {
1081
- sucuriscan_error('You did not select any backup file to remove.');
1082
- }
1083
- }
1084
-
1085
- }
1086
-
1087
/**
1088
* File-based cache library.
1089
*
@@ -1529,7 +1312,22 @@ if( !function_exists('sucuriscan_create_uploaddir') ){
1529
1530
if( !file_exists($plugin_upload_folder) ){
1531
if( @mkdir($plugin_upload_folder) ){
1532
sucuriscan_lastlogins_datastore_exists();
1533
} else {
1534
sucuriscan_error(
1535
'Data folder does not exists and could not be created. You will need to
@@ -1695,33 +1493,138 @@ function is_valid_email( $email='' ){
1695
}
1696
}
1697
1698
/**
1699
* Send a message to a specific email address.
1700
*
1701
- * @param string $to The email address of the recipient that will receive the message.
1702
* @param string $subject The reason of the message that will be sent.
1703
* @param string $message Body of the message that will be sent.
1704
* @param array $data_set Optional parameter to add more information to the notification.
1705
- * @param boolean $debug TRUE if you want to test the function printing the email before sending it.
1706
- * @return void
1707
*/
1708
- function sucuriscan_send_mail( $to='', $subject='', $message='', $data_set=array(), $debug=FALSE ){
1709
$headers = array();
1710
$subject = ucwords(strtolower($subject));
1711
$wp_domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : get_option('siteurl');
1712
1713
- if( sucuriscan_get_option('sucuriscan_prettify_mails') == 'enabled' ){
1714
$headers = array( 'Content-type: text/html' );
1715
$data_set['PrettifyType'] = 'pretty';
1716
}
1717
1718
- $message = sucuriscan_prettify_mail($subject, $message, $data_set);
1719
1720
- if( $debug ){
1721
- die($message);
1722
} else {
1723
- wp_mail($to, "Sucuri WP Notification: {$wp_domain} - {$subject}" , $message, $headers);
1724
}
1725
}
1726
1727
/**
@@ -2195,6 +2098,19 @@ function sucuriscan_get_remoteaddr(){
2195
return $remote_addr;
2196
}
2197
2198
/**
2199
* Check whether the site is behing the Sucuri CloudProxy network.
2200
*
@@ -2325,7 +2241,7 @@ function sucuriscan_time_ago($timestamp=0){
2325
$timestamp = strtotime($timestamp);
2326
}
2327
2328
- $diff = time() - (int)$timestamp;
2329
2330
if( $diff == 0 ){ return 'just now'; }
2331
@@ -2340,7 +2256,14 @@ function sucuriscan_time_ago($timestamp=0){
2340
);
2341
2342
$value = floor($diff/$intervals[1][1]);
2343
- return $value.chr(32).$intervals[1][0].($value > 1 ? 's' : '').' ago';
2344
}
2345
2346
/**
@@ -2461,18 +2384,26 @@ function sucuriscan_get_single_option( $option_name='' ){
2461
* @return string|array The default values for the specified options.
2462
*/
2463
function sucuriscan_get_default_options( $settings='' ){
2464
$default_options = array(
2465
'sucuriscan_api_key' => FALSE,
2466
- 'sucuriscan_account' => get_option('admin_email'),
2467
'sucuriscan_scan_frequency' => 'hourly',
2468
'sucuriscan_scan_interface' => 'spl',
2469
'sucuriscan_runtime' => 0,
2470
'sucuriscan_lastlogin_redirection' => 'enabled',
2471
'sucuriscan_prettify_mails' => 'enabled',
2472
'sucuriscan_notify_success_login' => 'enabled',
2473
'sucuriscan_notify_failed_login' => 'enabled',
2474
'sucuriscan_notify_post_publication' => 'enabled',
2475
'sucuriscan_notify_theme_editor' => 'enabled',
2476
);
2477
2478
if( is_array($settings) ){
@@ -2537,6 +2468,82 @@ function sucuriscan_what_options_were_changed( $request=array() ){
2537
return $options_changed;
2538
}
2539
2540
if( !function_exists('sucuriscan_plugin_setup_notice') ){
2541
/**
2542
* Display a notice message with instructions to continue the setup of the
@@ -2546,69 +2553,237 @@ if( !function_exists('sucuriscan_plugin_setup_notice') ){
2546
* @return void
2547
*/
2548
function sucuriscan_plugin_setup_notice(){
2549
- echo sucuriscan_get_section('setup_notice');
2550
}
2551
2552
- if( !sucuriscan_wordpress_apikey() ){
2553
- $sucuriscan_admin_notice_name = sucuriscan_is_multisite() ? 'network_admin_notices' : 'admin_notices';
2554
- add_action( $sucuriscan_admin_notice_name, 'sucuriscan_plugin_setup_notice' );
2555
- }
2556
}
2557
2558
/**
2559
- * Display the page with a temporary message explaining the action that will be
2560
- * performed once the hidden form is submitted to retrieve the scanning results
2561
- * from the public SiteCheck API.
2562
*
2563
- * @return void
2564
*/
2565
- function sucuriscan_scanner_page(){
2566
- if(
2567
- sucuriscan_check_page_nonce()
2568
- && isset($_POST['sucuriscan_malware_scan'])
2569
- ){
2570
- sucuriscan_sitecheck_info();
2571
- } else {
2572
- echo sucuriscan_get_template('malwarescan');
2573
- }
2574
- }
2575
2576
- /**
2577
- * Display the result of site scan made through SiteCheck.
2578
- *
2579
- * @return void
2580
- */
2581
- function sucuriscan_sitecheck_info(){
2582
- $sucuri_cache = new SucuriScanCache('sitecheck');
2583
- $scan_results = $sucuri_cache->get( 'scan_results', SUCURISCAN_SITECHECK_LIFETIME, 'array' );
2584
- $clean_domain = sucuriscan_get_domain();
2585
- $display_results = FALSE;
2586
2587
- ob_start();
2588
2589
- if( !$scan_results ){
2590
- $remote_url = 'http://sitecheck.sucuri.net/scanner/?serialized&clear&fromwp&scan='.$clean_domain;
2591
- $scan_results = wp_remote_get($remote_url, array('timeout' => 180));
2592
2593
- if( is_wp_error($scan_results) ){
2594
- sucuriscan_error( $scan_results->get_error_message() );
2595
}
2596
2597
- elseif( isset($scan_results['body']) ){
2598
- if( preg_match('/^ERROR:(.*)/', $scan_results['body'], $error_m) ){
2599
- sucuriscan_error( 'The site <code>' . $clean_domain . '</code> was not scanned: ' . $error_m[1] );
2600
}
2601
2602
- else {
2603
- $scan_results = @unserialize($scan_results['body']);
2604
- $display_results = TRUE;
2605
2606
- if( !$sucuri_cache->add( 'scan_results', $scan_results ) ){
2607
- sucuriscan_error( 'Could not cache the results of the SiteCheck scanning' );
2608
}
2609
}
2610
}
2611
- } else {
2612
$display_results = TRUE;
2613
// sucuriscan_info( 'SiteCheck results retrieved from cache.' );
2614
}
@@ -2718,11 +2893,11 @@ function sucuriscan_sitecheck_info(){
2718
2719
<?php if( !$malware_warns_exist ): ?>
2720
<p>
2721
- <span><strong>Malware:</strong> No.</span><br>
2722
- <span><strong>Malicious javascript:</strong> No.</span><br>
2723
- <span><strong>Malicious iframes:</strong> No.</span><br>
2724
- <span><strong>Suspicious redirections (htaccess):</strong> No.</span><br>
2725
- <span><strong>Blackhat SEO Spam:</strong> No.</span><br>
2726
<span><strong>Anomaly detection:</strong> Clean.</span>
2727
</p>
2728
<?php else: ?>
@@ -3018,7 +3193,7 @@ function sucuriscan_api_call( $url='', $method='GET', $params=array(), $args=arr
3018
'cookies' => array(),
3019
'compress' => FALSE,
3020
'decompress' => FALSE,
3021
- 'sslverify' => TRUE,
3022
);
3023
3024
// Update the request arguments with the values passed tot he function.
@@ -3092,7 +3267,7 @@ function sucuriscan_set_api_key( $api_key='', $validate=FALSE ){
3092
* @return string|boolean The API key or FALSE if it does not exists.
3093
*/
3094
function sucuriscan_wordpress_apikey(){
3095
- $api_key = get_option('sucuriscan_api_key');
3096
3097
if( $api_key && strlen($api_key) > 10 ){
3098
return $api_key;
@@ -3130,7 +3305,20 @@ function sucuriscan_valid_cloudproxy_apikey( $api_key='', $return_match=FALSE ){
3130
* @return array|boolean FALSE if the key is invalid or not present, an array otherwise.
3131
*/
3132
function sucuriscan_cloudproxy_apikey(){
3133
- $api_key = get_option('sucuriscan_cloudproxy_apikey');
3134
$match = sucuriscan_valid_cloudproxy_apikey( $api_key, TRUE );
3135
3136
if( $match ){
@@ -3308,12 +3496,13 @@ function sucuriscan_send_log( $event='' ){
3308
/**
3309
* Retrieve the event logs registered by the API service.
3310
*
3311
- * @return string The response of the API service.
3312
*/
3313
- function sucuriscan_get_logs(){
3314
$response = sucuriscan_api_call_wordpress( 'GET', array(
3315
'a' => 'get_logs',
3316
- 'l' => 50,
3317
) );
3318
3319
if( sucuriscan_handle_response($response) ){
@@ -3383,7 +3572,7 @@ function sucuriscan_send_hashes( $hashes='' ){
3383
*/
3384
function sucuriscan_verify_run( $runtime=0, $force_scan=FALSE ){
3385
$runtime_name = 'sucuriscan_runtime';
3386
- $last_run = get_option($runtime_name);
3387
$current_time = time();
3388
3389
if( $last_run && !$force_scan ){
@@ -3406,7 +3595,7 @@ function sucuriscan_verify_run( $runtime=0, $force_scan=FALSE ){
3406
*/
3407
function sucuriscan_report_wpversion(){
3408
$option_name = 'sucuriscan_wp_version';
3409
- $reported_version = get_option($option_name);
3410
$wp_version = sucuriscan_get_wpversion();
3411
3412
if( $reported_version != $wp_version ){
@@ -3454,7 +3643,7 @@ function sucuriscan_filesystem_scan( $force_scan=FALSE ){
3454
sucuriscan_report_wpversion();
3455
3456
$sucuri_fileinfo = new SucuriScanFileInfo();
3457
- $scan_interface = get_option('sucuriscan_scan_interface');
3458
$signatures = $sucuri_fileinfo->get_directory_tree_md5(ABSPATH, $scan_interface);
3459
3460
if( $signatures ){
@@ -3540,15 +3729,30 @@ function sucuriscan_report_event( $severity=0, $location='', $message='' ){
3540
function sucuriscan_notify_event( $event='', $content='' ){
3541
$event_name = 'sucuriscan_notify_' . $event;
3542
$notify = sucuriscan_get_option($event_name);
3543
- $email = sucuriscan_get_option('admin_email');
3544
3545
if( $notify == 'enabled' ){
3546
if( $event == 'post_publication' ){
3547
$event = 'post_update';
3548
}
3549
3550
$title = sprintf( 'Sucuri notification (%s)', str_replace('_', chr(32), $event) );
3551
- $mail_sent = sucuriscan_send_mail( $email, $title, $content );
3552
3553
return $mail_sent;
3554
}
@@ -3717,9 +3921,12 @@ function sucuriscan_hook_private_to_published( $id=0 ){
3717
$p_type = 'Publication';
3718
}
3719
3720
- $message = $p_type.' changed from private to published #'.$id.' ('.$title.')';
3721
- sucuriscan_report_event( 2, 'core', $message );
3722
- sucuriscan_notify_event( 'post_publication', $message );
3723
}
3724
3725
/**
@@ -3880,6 +4087,47 @@ function sucuriscan_hook_wp_login_failed( $title='' ){
3880
$message = 'User authentication failed: '.$title;
3881
sucuriscan_report_event( 2, 'core', $message );
3882
sucuriscan_notify_event( 'failed_login', $message );
3883
}
3884
3885
/**
@@ -3889,7 +4137,7 @@ function sucuriscan_hook_wp_login_failed( $title='' ){
3889
* @return void
3890
*/
3891
function sucuriscan_hook_login_form_resetpass(){
3892
- // Detecting wordpress 2.8.3 vulnerability - $key is array.
3893
if( isset($_GET['key']) && is_array($_GET['key']) ){
3894
sucuriscan_report_event( 3, 'core', 'Attempt to reset password by attacking WP/2.8.3 bug' );
3895
}
@@ -4316,6 +4564,11 @@ function sucuriscan_monitoring_settings( $api_key='' ){
4316
$settings = sucuriscan_explain_monitoring_settings($settings);
4317
4318
foreach( $settings as $option_name => $option_value ){
4319
$css_class = ( $counter % 2 == 0 ) ? 'alternate' : '';
4320
$option_title = ucwords(str_replace('_', chr(32), $option_name));
4321
@@ -4769,18 +5022,18 @@ function sucuriscan_harden_version(){
4769
global $wp_version;
4770
4771
$updates = get_core_updates();
4772
- if(
4773
- !is_array($updates)
4774
- || empty($updates)
4775
- || $updates[0]->response == 'latest'
4776
- ){
4777
- $cp = 1;
4778
- } else {
4779
- $cp = 0;
4780
}
4781
4782
- if(strcmp($wp_version, "3.7") < 0)
4783
- {
4784
$cp = 0;
4785
}
4786
@@ -5182,7 +5435,7 @@ function sucuriscan_harden_readme(){
5182
sucuriscan_harden_status(
5183
'Information leakage (readme.html)',
5184
$cp,
5185
- 'sucuriscan_harden_readme',
5186
'<code>readme.html</code> file properly deleted',
5187
'<code>readme.html</code> not deleted and leaking the WordPress version',
5188
'It checks whether you have the <code>readme.html</code> file available that leaks your WordPress version',
@@ -5244,7 +5497,7 @@ function sucuriscan_harden_fileeditor(){
5244
}
5245
5246
@file_put_contents($wp_config_path, $new_wpconfig, LOCK_EX);
5247
- sucuriscan_info( 'WP-Config file updated successfully, the plugin and theme editor was disabled.' );
5248
$file_editor_disabled = TRUE;
5249
} else {
5250
sucuriscan_error( 'The <code>wp-config.php</code> file is not in the default location
@@ -5258,7 +5511,7 @@ function sucuriscan_harden_fileeditor(){
5258
if( $wp_config_writable ){
5259
$new_wpconfig = str_replace("\n{$match[1]}", '', $new_wpconfig);
5260
file_put_contents($wp_config_path, $new_wpconfig, LOCK_EX);
5261
- sucuriscan_info( 'WP-Config file updated successfully, the plugin and theme editor was enabled.' );
5262
$file_editor_disabled = FALSE;
5263
} else {
5264
sucuriscan_error( 'The <code>wp-config.php</code> file is not in the default location
@@ -5299,37 +5552,10 @@ function sucuriscan_harden_dbtables(){
5299
5300
$hardened = ( $table_prefix == 'wp_' ? 0 : 1 );
5301
5302
- if(
5303
- isset($_POST['wpsucuri-doharden'])
5304
- && (
5305
- isset($_POST['sucuriscan_harden_dbtables']) ||
5306
- isset($_POST['sucuriscan_harden_dbtables_unharden'])
5307
- )
5308
- ){
5309
- $sucuri_backup = new SucuriScanBackup();
5310
- $dbbackup_filepath = $sucuri_backup->all_database();
5311
-
5312
- if( $dbbackup_filepath ){
5313
- sucuriscan_info( 'A new database table prefix change was initialized, if you have
5314
- problems after this operation finishes you can find a backup of the current
5315
- database here: <code>'.$dbbackup_filepath.'</code>' );
5316
-
5317
- if( isset($_POST['sucuriscan_harden_dbtables']) ){
5318
- $hardened = 1;
5319
- $sucuri_backup->new_table_prefix();
5320
- } elseif( isset($_POST['sucuriscan_harden_dbtables_unharden']) ){
5321
- $hardened = 0;
5322
- $sucuri_backup->reset_table_prefix();
5323
- }
5324
- } else {
5325
- sucuriscan_error( 'Error generating a backup for your database.' );
5326
- }
5327
- }
5328
-
5329
sucuriscan_harden_status(
5330
'Database table prefix',
5331
$hardened,
5332
- 'sucuriscan_harden_dbtables',
5333
'Database table prefix properly modified',
5334
'Database table set to the default value <code>wp_</code>.',
5335
'It checks whether your database table prefix has been changed from the default <code>wp_</code>',
@@ -5417,55 +5643,74 @@ function sucuriscan_get_integrity_tree( $dir='./', $recursive=FALSE ){
5417
*/
5418
function sucuriscan_auditlogs(){
5419
5420
- $audit_logs = sucuriscan_get_logs();
5421
$max_per_page = SUCURISCAN_AUDITLOGS_PER_PAGE;
5422
- $show_all = isset($_GET['show_all']) ? TRUE : FALSE;
5423
5424
$template_variables = array(
5425
'PageTitle' => 'Audit Logs',
5426
'AuditLogs.List' => '',
5427
'AuditLogs.Count' => 0,
5428
- 'AuditLogs.NoItemsVisibility' => 'visible',
5429
- 'AuditLogs.MaxItemsVisibility' => 'hidden',
5430
'AuditLogs.MaxPerPage' => $max_per_page,
5431
);
5432
5433
if( $audit_logs ){
5434
$counter_i = 0;
5435
$total_items = count($audit_logs->output_data);
5436
5437
- $template_variables['AuditLogs.Count'] = $total_items;
5438
- $template_variables['AuditLogs.NoItemsVisibility'] = 'hidden';
5439
-
5440
- if( $total_items > $max_per_page && !$show_all ){
5441
- $template_variables['AuditLogs.MaxItemsVisibility'] = 'visible';
5442
}
5443
5444
- foreach( $audit_logs->output_data as $audit_log ){
5445
- if( $counter_i > $max_per_page && !$show_all ){ break; }
5446
5447
- $css_class = ( $counter_i % 2 == 0 ) ? '' : 'alternate';
5448
- $snippet_data = array(
5449
- 'AuditLog.CssClass' => $css_class,
5450
- 'AuditLog.DateTime' => date( 'd/M/Y H:i:s', $audit_log['timestamp'] ),
5451
- 'AuditLog.Account' => $audit_log['account'],
5452
- 'AuditLog.Message' => $audit_log['message'],
5453
- 'AuditLog.Extra' => '',
5454
- );
5455
5456
- // Print every extra information item in a separate table.
5457
- if( $audit_log['extra'] ){
5458
- $css_scrollable = $audit_log['extra_total'] > 10 ? 'sucuriscan-list-as-table-scrollable' : '';
5459
- $snippet_data['AuditLog.Extra'] .= '<ul class="sucuriscan-list-as-table ' . $css_scrollable . '">';
5460
- foreach( $audit_log['extra'] as $log_extra ){
5461
- $snippet_data['AuditLog.Extra'] .= '<li>' . $log_extra . '</li>';
5462
}
5463
- $snippet_data['AuditLog.Extra'] .= '</ul>';
5464
- $snippet_data['AuditLog.Extra'] .= '<small>For Mac users, this is a scrollable container</small>';
5465
}
5466
5467
- $template_variables['AuditLogs.List'] .= sucuriscan_get_snippet('integrity-auditlogs', $snippet_data);
5468
- $counter_i += 1;
5469
}
5470
}
5471
@@ -5480,28 +5725,35 @@ function sucuriscan_auditlogs(){
5480
function sucuriscan_wordpress_outdated(){
5481
global $wp_version;
5482
5483
- $cp = 0;
5484
$updates = get_core_updates();
5485
-
5486
- if(
5487
- !is_array($updates)
5488
- || empty($updates)
5489
- || $updates[0]->response=='latest'
5490
- ){
5491
- $cp = 1;
5492
- }
5493
-
5494
- if( strcmp($wp_version, '3.7') < 0 ){
5495
- $cp = 0;
5496
- }
5497
5498
$template_variables = array(
5499
- 'WordPress.Version' => $wp_version,
5500
'WordPress.UpgradeURL' => admin_url('update-core.php'),
5501
'WordPress.UpdateVisibility' => 'hidden',
5502
);
5503
5504
- $wp_version = htmlspecialchars($wp_version);
5505
5506
if( $cp == 0 ){
5507
$template_variables['WordPress.UpdateVisibility'] = 'visible';
@@ -5791,7 +6043,7 @@ function sucuriscan_posthack_page(){
5791
'PageTitle' => 'Post-Hack',
5792
'UpdateSecretKeys' => sucuriscan_update_secret_keys($process_form),
5793
'ResetPassword' => sucuriscan_posthack_users($process_form),
5794
- 'DatabaseBackups' => sucuriscan_database_backups($process_form),
5795
);
5796
5797
echo sucuriscan_get_template('posthack', $template_variables);
@@ -5878,7 +6130,7 @@ function sucuriscan_posthack_users( $process_form=FALSE ){
5878
$user->user_registered_formatted = date('D, M/Y H:i', $user->user_registered_timestamp);
5879
$css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
5880
5881
- $user_snippet = sucuriscan_get_snippet('resetpassword', array(
5882
'ResetPassword.UserId' => $user->ID,
5883
'ResetPassword.Username' => $user->user_login,
5884
'ResetPassword.Displayname' => $user->display_name,
@@ -5932,119 +6184,99 @@ function sucuriscan_reset_user_password( $process_form=FALSE ){
5932
}
5933
5934
/**
5935
- * List and offer a way to download the database backups generates so far.
5936
*
5937
- * @param $process_form Whether a form was submitted or not.
5938
* @return void
5939
*/
5940
- function sucuriscan_database_backups( $process_form=FALSE ){
5941
$template_variables = array(
5942
- 'BackupList' => '',
5943
);
5944
5945
- // Process the form submission (if any).
5946
- sucuriscan_process_database_backups_form($process_form);
5947
-
5948
- // Instantiate the database/backup library and get all files.
5949
- $sucuri_backup = new SucuriScanBackup();
5950
- $backup_files = $sucuri_backup->get_backup_files();
5951
-
5952
- if( $backup_files ){
5953
- $counter = 0;
5954
5955
- foreach( $backup_files as $backup_file ){
5956
- $backupfile_snippet = sucuriscan_get_snippet('posthack-databasebackups', array(
5957
- 'BackupList.FileURL' => admin_url('?sucuriscan_download=' . $backup_file->filename),
5958
- 'BackupList.Filename' => $backup_file->filename,
5959
- 'BackupList.Filetype' => strtoupper($backup_file->fileext),
5960
- 'BackupList.Filesize' => ( $backup_file->filesize>0 ? "{$backup_file->filesize} (~ {$backup_file->filehumansize})" : 0 ),
5961
- 'BackupList.Filetime' => date('Y/M/d H:i', $backup_file->filetime),
5962
- 'BackupList.CssClass' => ( $counter % 2 == 0 ) ? '' : 'alternate',
5963
- ));
5964
5965
- $template_variables['BackupList'] .= $backupfile_snippet;
5966
- $counter += 1;
5967
- }
5968
}
5969
5970
- return sucuriscan_get_section('posthack-databasebackups', $template_variables);
5971
}
5972
5973
/**
5974
- * Process the form submissions of the database backups panel.
5975
*
5976
- * @param $process_form Whether a form was submitted or not.
5977
* @return void
5978
*/
5979
- function sucuriscan_process_database_backups_form( $process_form=FALSE ){
5980
- if( $process_form && isset($_POST['sucuriscan_database_backup']) ){
5981
-
5982
- if( isset($_POST['generate_dbbackup']) ){
5983
- $sucuri_backup = new SucuriScanBackup();
5984
- $dbbackup_filepath = $sucuri_backup->all_database();
5985
-
5986
- if( $dbbackup_filepath ){
5987
- $dbbackup_fileurl = admin_url( '?sucuriscan_download=' . basename($dbbackup_filepath) );
5988
- sucuriscan_info( 'Database backup generated and stored in the plugin upload folder, you can download the
5989
- file from here: <a href="'.$dbbackup_fileurl.'" target="_blank"><strong>Download DB Backup</strong></a>' );
5990
- } else {
5991
- sucuriscan_error( 'Could not generate a new database backup' );
5992
- }
5993
- }
5994
-
5995
- elseif( isset($_POST['remove_dbbackup']) ){
5996
- $sucuri_backup = new SucuriScanBackup();
5997
- $backups_to_remove = isset($_POST['dbbackup_filenames']) ? $_POST['dbbackup_filenames'] : array();
5998
- $sucuri_backup->remove_backup_file($backups_to_remove);
5999
- }
6000
6001
- }
6002
- }
6003
-
6004
- if( !function_exists('sucuriscan_download_file') ){
6005
- /**
6006
- * Download the SQL or Zip file generated to hold a backup of the database.
6007
- *
6008
- * @return void
6009
- */
6010
- function sucuriscan_download_file(){
6011
if(
6012
- current_user_can('manage_options')
6013
- AND isset($_GET['sucuriscan_download'])
6014
){
6015
- $sucuri_backup = new SucuriScanBackup();
6016
- $backup_file = $sucuri_backup->get_backup_file_from_filename($_GET['sucuriscan_download']);
6017
-
6018
- if( $backup_file ){
6019
- switch($backup_file->fileext){
6020
- case 'sql':
6021
- $download_filename = sprintf('%s.sql', DB_NAME);
6022
- header('Content-Type: application/x-sql');
6023
- break;
6024
- case 'zip':
6025
- $download_filename = sprintf('%s.sql.zip', DB_NAME);
6026
- header('Content-Type: application/zip');
6027
- break;
6028
- default:
6029
- $download_filename = $backup_file->filename;
6030
- header('Content-Type: application/octet-stream');
6031
- break;
6032
- }
6033
-
6034
- header('Content-Disposition: attachment; filename='.$download_filename);
6035
- header('Content-Length: '.$backup_file->filesize);
6036
- header('Cache-Control: private');
6037
-
6038
- if( $fd=fopen($backup_file->filepath,'r') ){
6039
- while( !feof($fd) ){ echo fread($fd, 2048); }
6040
}
6041
-
6042
- fclose($fd);
6043
}
6044
}
6045
}
6046
-
6047
- add_action('admin_init', 'sucuriscan_download_file');
6048
}
6049
6050
/**
@@ -6062,11 +6294,10 @@ function sucuriscan_lastlogins_page(){
6062
// Page pseudo-variables initialization.
6063
$template_variables = array(
6064
'PageTitle' => 'Last Logins',
6065
- 'LastLoginsNonce' => wp_create_nonce('sucuriscan_lastlogins_nonce'),
6066
'LastLogins.Admins' => sucuriscan_lastlogins_admins(),
6067
'LastLogins.AllUsers' => sucuriscan_lastlogins_all(),
6068
- 'UserList' => '',
6069
- 'UserListLimit' => SUCURISCAN_LASTLOGINS_USERSLIMIT,
6070
);
6071
6072
echo sucuriscan_get_template('lastlogins', $template_variables);
@@ -6088,13 +6319,15 @@ function sucuriscan_lastlogins_admins(){
6088
$user_query = new WP_User_Query(array( 'role' => 'Administrator' ));
6089
$admins = $user_query->get_results();
6090
6091
- foreach( (array)$admins as $admin ){
6092
- $admin->lastlogins = sucuriscan_get_logins(5, $admin->ID);
6093
6094
$user_snippet = array(
6095
'AdminUsers.Username' => $admin->user_login,
6096
'AdminUsers.Email' => $admin->user_email,
6097
'AdminUsers.LastLogins' => '',
6098
'AdminUsers.UserURL' => admin_url('user-edit.php?user_id='.$admin->ID),
6099
'AdminUsers.NoLastLogins' => 'visible',
6100
'AdminUsers.NoLastLoginsTable' => 'hidden',
@@ -6103,6 +6336,7 @@ function sucuriscan_lastlogins_admins(){
6103
if( !empty($admin->lastlogins) ){
6104
$user_snippet['AdminUsers.NoLastLogins'] = 'hidden';
6105
$user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible';
6106
$counter = 0;
6107
6108
foreach( $admin->lastlogins as $lastlogin ){
@@ -6130,27 +6364,38 @@ function sucuriscan_lastlogins_admins(){
6130
* @return string Last-logings for all user accounts.
6131
*/
6132
function sucuriscan_lastlogins_all(){
6133
$template_variables = array(
6134
'UserList' => '',
6135
- 'UserListLimit' => SUCURISCAN_LASTLOGINS_USERSLIMIT,
6136
);
6137
6138
if( !sucuriscan_lastlogins_datastore_is_writable() ){
6139
sucuriscan_error( 'Last-logins datastore file is not writable: <code>'.sucuriscan_lastlogins_datastore_filepath().'</code>' );
6140
}
6141
6142
- $limit = isset($_GET['limit']) ? intval($_GET['limit']) : SUCURISCAN_LASTLOGINS_USERSLIMIT;
6143
- $template_variables['UserList.ShowAll'] = $limit>0 ? 'visible' : 'hidden';
6144
-
6145
$counter = 0;
6146
- $user_list = sucuriscan_get_logins($limit);
6147
6148
- foreach( $user_list as $user ){
6149
$counter += 1;
6150
$css_class = ( $counter % 2 == 0 ) ? 'alternate' : '';
6151
6152
$user_dataset = array(
6153
- 'UserList.Number' => $counter,
6154
'UserList.UserId' => $user->user_id,
6155
'UserList.Username' => '<em>Unknown</em>',
6156
'UserList.Displayname' => '',
@@ -6174,6 +6419,13 @@ function sucuriscan_lastlogins_all(){
6174
$template_variables['UserList'] .= sucuriscan_get_snippet('lastlogins-all', $user_dataset);
6175
}
6176
6177
return sucuriscan_get_section('lastlogins-all', $template_variables);
6178
}
6179
@@ -6183,9 +6435,7 @@ function sucuriscan_lastlogins_all(){
6183
* @return string Absolute filepath where the user's last login information is stored.
6184
*/
6185
function sucuriscan_lastlogins_datastore_filepath(){
6186
- $plugin_upload_folder = sucuriscan_dir_filepath();
6187
- $datastore_filepath = rtrim($plugin_upload_folder,'/').'/sucuri-lastlogins.php';
6188
- return $datastore_filepath;
6189
}
6190
6191
/**
@@ -6272,57 +6522,86 @@ if( !function_exists('sucuri_set_lastlogin') ){
6272
* or limiting the quantity of entries.
6273
*
6274
* @param integer $limit How many entries will be returned from the operation.
6275
* @param integer $user_id Optional user identifier to filter the results.
6276
- * @return array The list of all the user logins through the time until now.
6277
*/
6278
- function sucuriscan_get_logins( $limit=10, $user_id=0 ){
6279
- $lastlogins = array();
6280
$datastore_filepath = sucuriscan_lastlogins_datastore_is_readable();
6281
6282
if( $datastore_filepath ){
6283
$parsed_lines = 0;
6284
- $lastlogins_lines = array_reverse(file($datastore_filepath));
6285
6286
- foreach( $lastlogins_lines as $line ){
6287
- $line = str_replace("\n", '', $line);
6288
6289
- if( preg_match('/^a:/', $line) ){
6290
- $user_lastlogin = unserialize($line);
6291
6292
- /* Only administrators can see all login stats */
6293
- if( !current_user_can('manage_options') ){
6294
- $current_user = wp_get_current_user();
6295
- if( $current_user->user_login!=$user_lastlogin['user_login'] ){ continue; }
6296
- }
6297
6298
- /* If an User_Id was specified when this function was called, filter by that number */
6299
- if( $user_id>0 ){
6300
- if( $user_lastlogin['user_id']!=$user_id ){ continue; }
6301
- }
6302
6303
- /* Get the WP_User object and add extra information from the last-login data */
6304
- $user_lastlogin['user_exists'] = FALSE;
6305
- $user_account = get_userdata($user_lastlogin['user_id']);
6306
6307
- if( $user_account ){
6308
- $user_lastlogin['user_exists'] = TRUE;
6309
6310
- foreach( $user_account->data as $var_name=>$var_value ){
6311
- $user_lastlogin[$var_name] = $var_value;
6312
}
6313
- }
6314
6315
- $lastlogins[] = (object)$user_lastlogin;
6316
- $parsed_lines += 1;
6317
- }
6318
6319
- if( preg_match('/^([0-9]+)#x2F;', $limit) && $limit>0 ){
6320
- if( $parsed_lines>=$limit ){ break; }
6321
}
6322
}
6323
}
6324
6325
- return $lastlogins;
6326
}
6327
6328
if( !function_exists('sucuri_login_redirect') ){
@@ -6362,228 +6641,29 @@ if( !function_exists('sucuri_get_user_lastlogin') ){
6362
$current_user = wp_get_current_user();
6363
6364
// Select the penultimate entry, not the last one.
6365
- $user_lastlogins = sucuriscan_get_logins(2, $current_user->ID);
6366
- $row = isset($user_lastlogins[1]) ? $user_lastlogins[1] : FALSE;
6367
6368
- if($row){
6369
- $message_tpl = 'The last time you logged in was: %s, from %s - %s';
6370
- $lastlogin_message = sprintf( $message_tpl, date('Y/M/d'), $row->user_remoteaddr, $row->user_hostname );
6371
- $lastlogin_message .= chr(32).'(<a href="'.site_url('wp-admin/admin.php?page='.SUCURISCAN.'_lastlogins').'">View Last-Logins</a>)';
6372
sucuriscan_info( $lastlogin_message );
6373
}
6374
}
6375
}
6376
add_action('admin_notices', 'sucuriscan_get_user_lastlogin');
6377
}
6378
6379
/**
6380
- * Generate and print the HTML code for the InfoSys page.
6381
- *
6382
- * This page will contains information of the system where the site is hosted,
6383
- * also information about users in session, htaccess rules and configuration
6384
- * options.
6385
*
6386
- * @return void
6387
*/
6388
- function sucuriscan_infosys_page(){
6389
- if( !current_user_can('manage_options') ){
6390
- wp_die(__('You do not have sufficient permissions to access this page: Sucuri Last-Logins') );
6391
- }
6392
-
6393
- // Page pseudo-variables initialization.
6394
- $template_variables = array(
6395
- 'PageTitle' => 'Site Info',