AntiVirus - Version 1.3.9

Version Description

Download this release

Release Info

Developer swissspidy
Plugin Icon 128x128 AntiVirus
Version 1.3.9
Comparing to
See all releases

Code changes from version 1.3.8 to 1.3.9

readme.txt → README.md RENAMED
@@ -1,160 +1,166 @@
1
- === AntiVirus ===
2
- Contributors: sergej.mueller
3
- Tags: antivirus, malware, scanner, phishing, safe browsing, vulnerability
4
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RDDW9FEHGLG6
5
- Requires at least: 3.8
6
- Tested up to: 3.9.1
7
- Stable tag: trunk
8
- License: GPLv2 or later
9
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
-
11
-
12
-
13
- Useful plugin that will scan your theme templates for malicious injections. Automatically. Every day. For more blog security.
14
-
15
-
16
-
17
- == Description ==
18
-
19
- = Scan & Notify =
20
- *AntiVirus for WordPress* is a easy and safe tool to protect your blog install against exploits, malware and spam injections. Scan your templates now!
21
-
22
-
23
- = Features =
24
- * Virus alert in the admin bar
25
- * Cleaning up after plugin removal
26
- * Translations into many languages​​
27
- * Daily scan with email notifications
28
- * Database tables and theme templates checks
29
- * WordPress 3.x ready: both visually and technically
30
- * Whitelist solution: Mark suspected cases as "no virus"
31
- * Manual check of template files with alerts on suspected cases
32
- * Optional: Google Safe Browsing for malware and phishing monitoring.
33
-
34
-
35
- = Requirements =
36
- * PHP 5.1
37
- * WordPress 3.8
38
-
39
-
40
- = Donation =
41
- * [Flattr](https://flattr.com/t/1322865)
42
- * [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RDDW9FEHGLG6)
43
-
44
-
45
- = Documentation =
46
- * [Sicherheit: AntiVirus für WordPress](http://playground.ebiene.de/antivirus-wordpress-plugin/ "AntiVirus für WordPress") (DE)
47
-
48
-
49
- = Website =
50
- * [wpantivirus.com](http://wpantivirus.com)
51
-
52
-
53
- = Author =
54
- * [Twitter](https://twitter.com/wpseo)
55
- * [Google+](https://plus.google.com/110569673423509816572)
56
- * [Plugins](http://wpcoder.de)
57
-
58
-
59
-
60
-
61
- == Changelog ==
62
-
63
- = 1.3.8 =
64
- * Deutsch: Erkennung der [MailPoet-Sicherheitslücke](http://blog.sucuri.net/2014/07/mailpoet-vulnerability-exploited-in-the-wild-breaking-thousands-of-wordpress-sites.html)
65
- * English: Detection and warning for the [MailPoet Vulnerability](http://blog.sucuri.net/2014/07/mailpoet-vulnerability-exploited-in-the-wild-breaking-thousands-of-wordpress-sites.html)
66
-
67
- = 1.3.7 =
68
- * Deutsch: Aktualisierung auf Safe Browsing Lookup API 3.1
69
- * English: Update the Google Safe Browsing Lookup API to v3.1
70
-
71
- = 1.3.6 =
72
- * Deutsch: Code-Revision und Datenvalidierung
73
- * English: Code revision and data validation
74
-
75
- = 1.3.5 =
76
- * Deutsch: Optimierungen für WordPress 3.8
77
- * English: Optimizations for WordPress 3.8
78
-
79
- = 1.3.4 =
80
- * Deutsch: Benachrichtigung per E-Mail, sobald [Google Safe Browsing](http://en.wikipedia.org/wiki/Google_Safe_Browsing) Malware im Blog erkennt. [Mehr auf Google+](https://plus.google.com/110569673423509816572/posts/H72FFwvna1i)
81
- * English: [Google Safe Browsing](http://en.wikipedia.org/wiki/Google_Safe_Browsing) for malware and phishing monitoring.
82
-
83
- = 1.3.3 =
84
- * Add inspection for iFrames
85
- * Retina support for teaser and screenshot
86
-
87
- = 1.3.2 =
88
- * Remove the check for include and require commands (#wpforce)
89
-
90
- = 1.3.1 =
91
- * Compatibility with WordPress 3.4
92
- * High-resolution plugin icon for retina displays
93
- * Remove icon from the admin sidebar
94
- * System requirements: From PHP 5.0 to PHP 5.1
95
-
96
- = 1.3 =
97
- * Xmas Edition
98
-
99
- = 1.2 =
100
- * "Virus suspected" alert in the admin bar
101
- * Fix for the manual scan link on dashboard
102
- * More detailed checks for existing malware
103
- * Code adjustments for WordPress 3.3
104
-
105
- = 1.1 =
106
- * Testing for templates with empty content
107
- * Minimum requirement upgraded to 2.8 and PHP5
108
- * Code improvements for more speed
109
- * GUI changes
110
-
111
- = 1.0 =
112
- * More security checks (Email & Regexp)
113
-
114
- = 0.9 =
115
- * Changes for the current WordPress virus
116
-
117
- = 0.8 =
118
- * Support for WordPress 3.0
119
- * System requirements: WordPress 2.7
120
- * Code optimization
121
-
122
- = 0.7 =
123
- * Advanced templates check
124
-
125
- = 0.6 =
126
- * WordPress 2.9 support
127
-
128
- = 0.5 =
129
- * Add security scan for the current [WordPress permalink back door](http://mashable.com/2009/09/05/wordpress-attack/ "WordPress permalink back door")
130
- * Software architecture changes
131
-
132
- = 0.4 =
133
- * Adds support for WordPress new changelog readme.txt standard
134
- * Various changes for more speed, usability and security
135
-
136
- = 0.3 =
137
- * Add alternate e-mail address (admin e-mail address as default)
138
- * Admin notice on dashboard where it has found the virus suspicion
139
- * Added blog URL in e-mail
140
- * WordPress 2.8 support
141
- * Check for hidden iframes
142
- * Bugfix for IE problem with box positions
143
- * Cleanup the source code
144
- * Language support for Persian
145
-
146
- = 0.2 =
147
- * Whitelist: Mark the suspicion as "No virus"
148
- * Improving the output formatting
149
- * Add WPlize library for option data
150
- * Language support for Italian
151
-
152
- = 0.1 =
153
- * AntiVirus for WordPress goes online
154
-
155
-
156
-
157
-
158
- == Screenshots ==
159
-
160
- 1. WordPress AntiVirus settings
 
 
 
 
 
 
1
+ # AntiVirus #
2
+ * Contributors: pluginkollektiv
3
+ * Tags: antivirus, malware, scanner, phishing, safe browsing, vulnerability
4
+ * Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=LG5VC9KXMAYXJ
5
+ * Requires at least: 3.8
6
+ * Tested up to: 4.6
7
+ * Stable tag: 1.3.9
8
+ * License: GPLv2 or later
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+
12
+ Security plugin to protect your blog or website against exploits and spam injections.
13
+
14
+
15
+ ## Description ##
16
+ *AntiVirus for WordPress* is a easy-to-use, safe tool to harden your WordPress site against exploits, malware and spam injections.
17
+ You can configure *AntiVirus* to perform an automated daily scan of your theme files and database tables. If the plugin happens to detect any suspicious code injections, it will send out a notification to a previously configured e-mail address.
18
+
19
+ In case your WordPress site has been hacked, *AntiVirus* will help you to become aware of the problem very quickly in order for you to take immediate action.
20
+
21
+
22
+ ### Features ###
23
+ * Virus alert in the admin bar
24
+ * Cleaning up after plugin removal
25
+ * Translations into many languages​​
26
+ * Daily scan with email notifications
27
+ * Database tables and theme templates checks
28
+ * WordPress 3.x ready: both visually and technically
29
+ * Whitelist solution: Mark suspected cases as "no virus"
30
+ * Manual check of template files with alerts on suspected cases
31
+ * Optional: Google Safe Browsing for malware and phishing monitoring.
32
+
33
+
34
+ > #### Auf Deutsch? ####
35
+ > Für eine ausführliche Dokumentation besuche bitte das [AntiVirus-Wiki](https://github.com/pluginkollektiv/antivirus/wiki).
36
+ >
37
+ > **Community-Support auf Deutsch** erhältst du in einem der [deutschsprachigen Foren](https://de.forums.wordpress.org/forum/plugins); im [Plugin-Forum für AntiVirus](https://wordpress.org/support/plugin/antivirus) wird, wie in allen Plugin-Foren auf wordpress.org, ausschließlich **Englisch** gesprochen.
38
+
39
+
40
+ ### Languages ###
41
+ * English
42
+ * German
43
+ * German formal
44
+
45
+
46
+ ### Credits ###
47
+ * Author: [Sergej Müller](https://sergejmueller.github.io/)
48
+ * Maintainers: [pluginkollektiv](http://pluginkollektiv.org/)
49
+
50
+
51
+ ## Installation ##
52
+ * If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).
53
+
54
+ ### Requirements ###
55
+ * PHP 5.2.4 or greater
56
+ * WordPress 3.8 or greater
57
+
58
+ ## Frequently Asked Questions ##
59
+
60
+ ### Will AntiVirus protect my site from being hacked? ###
61
+ Not literally “protect from”. The plugin’s purpose is to _detect_ any “hack” that has already happened and enable you to take immediate action upon it.
62
+
63
+
64
+ ## Changelog ##
65
+ ### 1.3.9 ###
66
+ * generated a POT file
67
+ * added German formal translation
68
+ * updated, translated + formatted README.md
69
+ * updated expired link URLs in plugin and languages files
70
+ * updated [plugin authors](https://gist.github.com/glueckpress/f058c0ab973d45a72720)
71
+
72
+ ### 1.3.8 ###
73
+ * Deutsch: Erkennung der [MailPoet-Sicherheitslücke](http://blog.sucuri.net/2014/07/mailpoet-vulnerability-exploited-in-the-wild-breaking-thousands-of-wordpress-sites.html)
74
+ * English: Detection and warning for the [MailPoet Vulnerability](http://blog.sucuri.net/2014/07/mailpoet-vulnerability-exploited-in-the-wild-breaking-thousands-of-wordpress-sites.html)
75
+
76
+ ### 1.3.7 ###
77
+ * Deutsch: Aktualisierung auf Safe Browsing Lookup API 3.1
78
+ * English: Update the Google Safe Browsing Lookup API to v3.1
79
+
80
+ ### 1.3.6 ###
81
+ * Deutsch: Code-Revision und Datenvalidierung
82
+ * English: Code revision and data validation
83
+
84
+ ### 1.3.5 ###
85
+ * Deutsch: Optimierungen für WordPress 3.8
86
+ * English: Optimizations for WordPress 3.8
87
+
88
+ ### 1.3.4 ###
89
+ * Deutsch: Benachrichtigung per E-Mail, sobald [Google Safe Browsing](http://en.wikipedia.org/wiki/Google_Safe_Browsing) Malware im Blog erkennt. [Mehr auf Google+](https://plus.google.com/110569673423509816572/posts/H72FFwvna1i)
90
+ * English: [Google Safe Browsing](http://en.wikipedia.org/wiki/Google_Safe_Browsing) for malware and phishing monitoring.
91
+
92
+ ### 1.3.3 ###
93
+ * Add inspection for iFrames
94
+ * Retina support for teaser and screenshot
95
+
96
+ ### 1.3.2 ###
97
+ * Remove the check for include and require commands (#wpforce)
98
+
99
+ ### 1.3.1 ###
100
+ * Compatibility with WordPress 3.4
101
+ * High-resolution plugin icon for retina displays
102
+ * Remove icon from the admin sidebar
103
+ * System requirements: From PHP 5.0 to PHP 5.1
104
+
105
+ ### 1.3 ###
106
+ * Xmas Edition
107
+
108
+ ### 1.2 ###
109
+ * "Virus suspected" alert in the admin bar
110
+ * Fix for the manual scan link on dashboard
111
+ * More detailed checks for existing malware
112
+ * Code adjustments for WordPress 3.3
113
+
114
+ ### 1.1 ###
115
+ * Testing for templates with empty content
116
+ * Minimum requirement upgraded to 2.8 and PHP5
117
+ * Code improvements for more speed
118
+ * GUI changes
119
+
120
+ ### 1.0 ###
121
+ * More security checks (Email & Regexp)
122
+
123
+ ### 0.9 ###
124
+ * Changes for the current WordPress virus
125
+
126
+ ### 0.8 ###
127
+ * Support for WordPress 3.0
128
+ * System requirements: WordPress 2.7
129
+ * Code optimization
130
+
131
+ ### 0.7 ###
132
+ * Advanced templates check
133
+
134
+ ### 0.6 ###
135
+ * WordPress 2.9 support
136
+
137
+ ### 0.5 ###
138
+ * Add security scan for the current [WordPress permalink back door](http://mashable.com/2009/09/05/wordpress-attack/ "WordPress permalink back door")
139
+ * Software architecture changes
140
+
141
+ ### 0.4 ###
142
+ * Adds support for WordPress new changelog readme.txt standard
143
+ * Various changes for more speed, usability and security
144
+
145
+ ### 0.3 ###
146
+ * Add alternate e-mail address (admin e-mail address as default)
147
+ * Admin notice on dashboard where it has found the virus suspicion
148
+ * Added blog URL in e-mail
149
+ * WordPress 2.8 support
150
+ * Check for hidden iframes
151
+ * Bugfix for IE problem with box positions
152
+ * Cleanup the source code
153
+ * Language support for Persian
154
+
155
+ ### 0.2 ###
156
+ * Whitelist: Mark the suspicion as "No virus"
157
+ * Improving the output formatting
158
+ * Add WPlize library for option data
159
+ * Language support for Italian
160
+
161
+ ### 0.1 ###
162
+ * AntiVirus for WordPress goes online
163
+
164
+
165
+ ## Screenshots ##
166
+ 1. WordPress AntiVirus settings
antivirus.php CHANGED
@@ -1,1343 +1,1332 @@
1
- <?php
2
- /*
3
- Plugin Name: AntiVirus
4
- Text Domain: antivirus
5
- Domain Path: /lang
6
- Description: Security solution as a smart, effectively plugin to protect your blog against exploits and spam injections.
7
- Author: Sergej M&uuml;ller
8
- Author URI: http://wpcoder.de
9
- Plugin URI: http://wpantivirus.com
10
- License: GPLv2 or later
11
- Version: 1.3.8
12
- */
13
-
14
- /*
15
- Copyright (C) 2009-2014 Sergej Müller
16
-
17
- This program is free software; you can redistribute it and/or modify
18
- it under the terms of the GNU General Public License as published by
19
- the Free Software Foundation; either version 2 of the License, or
20
- (at your option) any later version.
21
-
22
- This program is distributed in the hope that it will be useful,
23
- but WITHOUT ANY WARRANTY; without even the implied warranty of
24
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
- GNU General Public License for more details.
26
-
27
- You should have received a copy of the GNU General Public License along
28
- with this program; if not, write to the Free Software Foundation, Inc.,
29
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30
- */
31
-
32
-
33
- /* Sicherheitsabfrage */
34
- if ( ! class_exists('WP') ) {
35
- die();
36
- }
37
-
38
-
39
- /**
40
- * AntiVirus
41
- *
42
- * @since 0.1
43
- */
44
-
45
- class AntiVirus {
46
-
47
-
48
- /* Save me! */
49
- private static $base;
50
-
51
-
52
- /**
53
- * Pseudo-Konstruktor der Klasse
54
- *
55
- * @since 1.3.4
56
- * @change 1.3.4
57
- */
58
-
59
- public static function instance()
60
- {
61
- new self();
62
- }
63
-
64
-
65
- /**
66
- * Konstruktor der Klasse
67
- *
68
- * @since 0.1
69
- * @change 1.3.5
70
- */
71
-
72
- public function __construct()
73
- {
74
- /* AUTOSAVE */
75
- if ( ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) OR ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) ) {
76
- return;
77
- }
78
-
79
- /* Plugin-Base */
80
- self::$base = plugin_basename(__FILE__);
81
-
82
- /* Cronjob */
83
- if ( defined('DOING_CRON') ) {
84
- add_action(
85
- 'antivirus_daily_cronjob',
86
- array(
87
- __CLASS__,
88
- 'do_daily_cronjob'
89
- )
90
- );
91
-
92
- /* Admin */
93
- } elseif ( is_admin() ) {
94
- /* AJAX */
95
- if ( defined('DOING_AJAX') ) {
96
- add_action(
97
- 'wp_ajax_get_ajax_response',
98
- array(
99
- __CLASS__,
100
- 'get_ajax_response'
101
- )
102
- );
103
-
104
- /* Backend */
105
- } else {
106
- /* Actions */
107
- add_action(
108
- 'init',
109
- array(
110
- __CLASS__,
111
- 'load_plugin_lang'
112
- )
113
- );
114
- add_action(
115
- 'admin_menu',
116
- array(
117
- __CLASS__,
118
- 'add_sidebar_menu'
119
- )
120
- );
121
- add_action(
122
- 'admin_notices',
123
- array(
124
- __CLASS__,
125
- 'show_dashboard_notice'
126
- )
127
- );
128
- add_action(
129
- 'deactivate_' .self::$base,
130
- array(
131
- __CLASS__,
132
- 'clear_scheduled_hook'
133
- )
134
- );
135
- add_filter(
136
- 'plugin_row_meta',
137
- array(
138
- __CLASS__,
139
- 'init_row_meta'
140
- ),
141
- 10,
142
- 2
143
- );
144
- add_filter(
145
- 'plugin_action_links_' .self::$base,
146
- array(
147
- __CLASS__,
148
- 'init_action_links'
149
- )
150
- );
151
- }
152
- }
153
- }
154
-
155
-
156
- /**
157
- * Einbindung der Sprache
158
- *
159
- * @since 0.8
160
- * @change 0.8
161
- */
162
-
163
- public static function load_plugin_lang()
164
- {
165
- load_plugin_textdomain(
166
- 'antivirus',
167
- false,
168
- 'antivirus/lang'
169
- );
170
- }
171
-
172
-
173
- /**
174
- * Hinzufügen der Action-Links (Einstellungen links)
175
- *
176
- * @since 1.1
177
- * @change 1.3.4
178
- *
179
- * @param array $data Array mit Links
180
- * @return array $data Array mit erweitertem Link
181
- */
182
-
183
- public static function init_action_links($data)
184
- {
185
- /* Rechte? */
186
- if ( ! current_user_can('manage_options') ) {
187
- return $data;
188
- }
189
-
190
- return array_merge(
191
- $data,
192
- array(
193
- sprintf(
194
- '<a href="%s">%s</a>',
195
- add_query_arg(
196
- array(
197
- 'page' => 'antivirus'
198
- ),
199
- admin_url('options-general.php')
200
- ),
201
- __('Settings')
202
- )
203
- )
204
- );
205
- }
206
-
207
-
208
- /**
209
- * Links in der Plugin-Verwaltung
210
- *
211
- * @since 0.1
212
- * @change 1.3.4
213
- *
214
- * @param array $data Array mit Links
215
- * @param string $page Aktuelle Seite
216
- * @return array $data Array mit erweitertem Link
217
- */
218
-
219
- public static function init_row_meta($data, $page)
220
- {
221
- if ( $page != self::$base ) {
222
- return $data;
223
- }
224
-
225
- return array_merge(
226
- $data,
227
- array(
228
- '<a href="https://flattr.com/t/1322865" target="_blank">Flattr</a>',
229
- '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=5RDDW9FEHGLG6" target="_blank">PayPal</a>'
230
- )
231
- );
232
- }
233
-
234
-
235
- /**
236
- * Aktion bei Aktivierung des Plugins
237
- *
238
- * @since 0.1
239
- * @change 1.3.4
240
- */
241
-
242
- public static function install()
243
- {
244
- /* Option anlegen */
245
- add_option(
246
- 'antivirus',
247
- array(),
248
- '',
249
- 'no'
250
- );
251
-
252
- /* Cron aktivieren */
253
- if ( self::_get_option('cronjob_enable') ) {
254
- self::_add_scheduled_hook();
255
- }
256
- }
257
-
258
-
259
- /**
260
- * Aktionen bei der Deaktivierung des Plugins
261
- *
262
- * @since 1.3.4
263
- * @change 1.3.4
264
- */
265
-
266
- public static function deactivation()
267
- {
268
- self::clear_scheduled_hook();
269
- }
270
-
271
-
272
- /**
273
- * Uninstallation des Plugins pro MU-Blog
274
- *
275
- * @since 1.1
276
- * @change 1.3.5
277
- */
278
-
279
- public static function uninstall()
280
- {
281
- delete_option('antivirus');
282
- }
283
-
284
-
285
- /**
286
- * Rückgabe eines Optionsfeldes
287
- *
288
- * @since 0.1
289
- * @change 1.3.4
290
- *
291
- * @param string $field Name einer Option
292
- * @return mixed Wert einer Option
293
- */
294
-
295
- private static function _get_option($field)
296
- {
297
- $options = wp_parse_args(
298
- get_option('antivirus'),
299
- array(
300
- 'cronjob_enable' => 0,
301
- 'cronjob_alert' => 0,
302
- 'safe_browsing' => 0,
303
- 'notify_email' => '',
304
- 'white_list' => ''
305
- )
306
- );
307
-
308
- return ( empty($options[$field]) ? '' : $options[$field] );
309
- }
310
-
311
-
312
- /**
313
- * Aktualisiert ein Optionsfeld
314
- *
315
- * @since 0.1
316
- * @change 1.3.4
317
- *
318
- * @param string $field Name des Feldes
319
- * @param mixed Wert des Feldes
320
- */
321
-
322
- private static function _update_option($field, $value)
323
- {
324
- self::_update_options(
325
- array(
326
- $field => $value
327
- )
328
- );
329
- }
330
-
331
-
332
- /**
333
- * Aktualisiert mehrere Optionsfelder
334
- *
335
- * @since 0.1
336
- * @change 1.3.4
337
- *
338
- * @param array $data Array mit Feldern
339
- */
340
-
341
- private static function _update_options($data)
342
- {
343
- update_option(
344
- 'antivirus',
345
- array_merge(
346
- (array)get_option('antivirus'),
347
- $data
348
- )
349
- );
350
- }
351
-
352
-
353
- /**
354
- * Initialisierung des Cronjobs
355
- *
356
- * @since 1.3.4
357
- * @change 1.3.4
358
- */
359
-
360
- private static function _add_scheduled_hook()
361
- {
362
- if ( ! wp_next_scheduled('antivirus_daily_cronjob') ) {
363
- wp_schedule_event(
364
- time(),
365
- 'daily',
366
- 'antivirus_daily_cronjob'
367
- );
368
- }
369
- }
370
-
371
-
372
- /**
373
- * Beendigung des Cronjobs
374
- *
375
- * @since 0.1
376
- * @change 0.8
377
- */
378
-
379
- public static function clear_scheduled_hook()
380
- {
381
- if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
382
- wp_clear_scheduled_hook('antivirus_daily_cronjob');
383
- }
384
- }
385
-
386
-
387
- /**
388
- * Ausführung des Cronjobs
389
- *
390
- * @since 0.1
391
- * @change 1.3.4
392
- */
393
-
394
- public static function do_daily_cronjob()
395
- {
396
- /* Kein Cronjob? */
397
- if ( ! self::_get_option('cronjob_enable') ) {
398
- return;
399
- }
400
-
401
- /* Load translation */
402
- self::load_plugin_lang();
403
-
404
- /* Safe Browsing API */
405
- self::_check_safe_browsing();
406
-
407
- /* Theme & Permalinks */
408
- self::_check_blog_internals();
409
- }
410
-
411
-
412
- /**
413
- * Führt die Safe Browsing Prüfung aus
414
- *
415
- * @since 1.3.4
416
- * @change 1.3.7
417
- */
418
-
419
- private static function _check_safe_browsing()
420
- {
421
- /* Not enabled? */
422
- if ( ! self::_get_option('safe_browsing') ) {
423
- return;
424
- }
425
-
426
- /* Start request */
427
- $response = wp_remote_get(
428
- sprintf(
429
- 'https://sb-ssl.google.com/safebrowsing/api/lookup?client=wpantivirus&key=%s&appver=1.3.7&pver=3.1&url=%s',
430
- 'AIzaSyALNYwuy-Pidn7vx3-In-hU0zgMH5Wr42U',
431
- urlencode( get_bloginfo('url') )
432
- ),
433
- array(
434
- 'sslverify' => false
435
- )
436
- );
437
-
438
- /* API Error? */
439
- if ( is_wp_error($response) ) {
440
- return;
441
- }
442
-
443
- /* All clear */
444
- if ( wp_remote_retrieve_response_code($response) == 204 ) {
445
- return;
446
- }
447
-
448
- /* Send notification */
449
- self::_send_warning_notification(
450
- esc_html__('Safe Browsing Alert', 'antivirus'),
451
- sprintf(
452
- "%s\r\nhttps://www.google.com/safebrowsing/diagnostic?site=%s&hl=%s",
453
- esc_html__('Please check the Google Safe Browsing diagnostic page:', 'antivirus'),
454
- urlencode( get_bloginfo('url') ),
455
- substr(get_locale(), 0, 2)
456
- )
457
- );
458
- }
459
-
460
-
461
- /**
462
- * Führt die Blog-interne Prüfung aus
463
- *
464
- * @since 1.3.4
465
- * @change 1.3.4
466
- */
467
-
468
- private static function _check_blog_internals()
469
- {
470
- /* Execute checks */
471
- if ( ! self::_check_theme_files() && ! self::_check_permalink_structure() ) {
472
- return;
473
- }
474
-
475
- /* Send notification */
476
- self::_send_warning_notification(
477
- esc_html__('Virus suspected', 'antivirus'),
478
- sprintf(
479
- "%s\r\n%s",
480
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
481
- get_bloginfo('url')
482
- )
483
- );
484
-
485
- /* Store alert */
486
- self::_update_option(
487
- 'cronjob_alert',
488
- 1
489
- );
490
- }
491
-
492
-
493
- /**
494
- * Führt die Safe Browsing Prüfung aus
495
- *
496
- * @since 1.3.4
497
- * @change 1.3.6
498
- *
499
- * @param string $subject Betreff der E-Mail
500
- * @param string $body Inhalt der E-Mail
501
- */
502
-
503
- private static function _send_warning_notification($subject, $body)
504
- {
505
- /* Receiver email address */
506
- $email = self::_get_option('notify_email');
507
-
508
- /* Email address fallback */
509
- if ( ! is_email($email) ) {
510
- $email = get_bloginfo('admin_email');
511
- }
512
-
513
- /* Send it! */
514
- wp_mail(
515
- $email,
516
- sprintf(
517
- '[%s] %s',
518
- get_bloginfo('name'),
519
- $subject
520
- ),
521
- sprintf(
522
- "%s\r\n\r\n\r\n%s\r\n%s\r\n",
523
- $body,
524
- esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
525
- esc_html__('http://wpantivirus.com', 'antivirus')
526
- )
527
- );
528
- }
529
-
530
-
531
- /**
532
- * Initialisierung der GUI
533
- *
534
- * @since 0.1
535
- * @change 1.3.5
536
- */
537
-
538
- public static function add_sidebar_menu()
539
- {
540
- /* Menü anlegen */
541
- $page = add_options_page(
542
- 'AntiVirus',
543
- 'AntiVirus',
544
- 'manage_options',
545
- 'antivirus',
546
- array(
547
- __CLASS__,
548
- 'show_admin_menu'
549
- )
550
- );
551
-
552
- add_action(
553
- 'admin_print_styles-' . $page,
554
- array(
555
- __CLASS__,
556
- 'add_enqueue_style'
557
- )
558
- );
559
- add_action(
560
- 'admin_print_scripts-' . $page,
561
- array(
562
- __CLASS__,
563
- 'add_enqueue_script'
564
- )
565
- );
566
- }
567
-
568
-
569
- /**
570
- * Initialisierung von JavaScript
571
- *
572
- * @since 0.8
573
- * @change 1.3.5
574
- */
575
-
576
- public static function add_enqueue_script()
577
- {
578
- /* Infos auslesen */
579
- $data = get_plugin_data(__FILE__);
580
-
581
- /* JS einbinden */
582
- wp_register_script(
583
- 'av_script',
584
- plugins_url('js/script.min.js', __FILE__),
585
- array('jquery'),
586
- $data['Version']
587
- );
588
-
589
- /* Script einbinden */
590
- wp_enqueue_script('av_script');
591
-
592
- /* Script lokalisieren */
593
- wp_localize_script(
594
- 'av_script',
595
- 'av_settings',
596
- array(
597
- 'nonce' => wp_create_nonce('av_ajax_nonce'),
598
- 'theme' => urlencode(self::_get_theme_name()),
599
- 'msg_1' => esc_html__('There is no virus', 'antivirus'),
600
- 'msg_2' => esc_html__('View line', 'antivirus'),
601
- 'msg_3' => esc_html__('Scan finished', 'antivirus')
602
- )
603
- );
604
- }
605
-
606
-
607
- /**
608
- * Initialisierung von Stylesheets
609
- *
610
- * @since 0.8
611
- * @change 1.3.4
612
- */
613
-
614
- public static function add_enqueue_style()
615
- {
616
- /* Infos auslesen */
617
- $data = get_plugin_data(__FILE__);
618
-
619
- /* CSS registrieren */
620
- wp_register_style(
621
- 'av_css',
622
- plugins_url('css/style.min.css', __FILE__),
623
- array(),
624
- $data['Version']
625
- );
626
-
627
- /* CSS einbinden */
628
- wp_enqueue_style('av_css');
629
- }
630
-
631
-
632
- /**
633
- * Rückgabe des aktuellen Theme
634
- *
635
- * @since 0.1
636
- * @change 1.3.6
637
- *
638
- * @return array $themes Array mit Theme-Eigenschaften
639
- */
640
-
641
- private static function _get_current_theme()
642
- {
643
- /* Init */
644
- $theme = wp_get_theme();
645
- $name = $theme->get('Name');
646
- $slug = $theme->get_stylesheet();
647
- $files = $theme->get_files('php', 1);
648
-
649
- /* Leer? */
650
- if ( empty($name) OR empty($files) ) {
651
- return false;
652
- }
653
-
654
- /* Rückgabe */
655
- return array(
656
- 'Name' => $name,
657
- 'Slug' => $slug,
658
- 'Template Files' => $files
659
- );
660
- }
661
-
662
-
663
- /**
664
- * Rückgabe von Dateien des aktuellen Theme
665
- *
666
- * @since 0.1
667
- * @change 1.3.4
668
- *
669
- * @return array $files Array mit Dateien
670
- */
671
-
672
- private static function _get_theme_files()
673
- {
674
- /* Theme vorhanden? */
675
- if ( ! $theme = self::_get_current_theme() ) {
676
- return false;
677
- }
678
-
679
- /* Keine Files? */
680
- if ( empty($theme['Template Files']) ) {
681
- return false;
682
- }
683
-
684
- /* Zurückgeben */
685
- return array_unique(
686
- array_map(
687
- create_function(
688
- '$v',
689
- 'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
690
- ),
691
- $theme['Template Files']
692
- )
693
- );
694
- }
695
-
696
-
697
- /**
698
- * Rückgabe des Namen des aktuellen Theme
699
- *
700
- * @since 0.1
701
- * @change 1.3.4
702
- *
703
- * @return string $theme Name des aktuellen Theme
704
- */
705
-
706
- private static function _get_theme_name()
707
- {
708
- if ( $theme = self::_get_current_theme() ) {
709
- if ( ! empty($theme['Slug']) ) {
710
- return $theme['Slug'];
711
- }
712
- if ( ! empty($theme['Name']) ) {
713
- return $theme['Name'];
714
- }
715
- }
716
-
717
- return false;
718
- }
719
-
720
-
721
- /**
722
- * Rückgabe der WhiteList
723
- *
724
- * @since 0.1
725
- * @change 1.3.4
726
- *
727
- * @return array return Array mit MD5-Werten
728
- */
729
-
730
- private static function _get_white_list()
731
- {
732
- return explode(
733
- ':',
734
- self::_get_option('white_list')
735
- );
736
- }
737
-
738
-
739
- /**
740
- * Ausführung von AJAX
741
- *
742
- * @since 0.1
743
- * @change 1.3.4
744
- */
745
-
746
- public static function get_ajax_response()
747
- {
748
- /* Referer prüfen */
749
- check_ajax_referer('av_ajax_nonce');
750
-
751
- /* Zusätzliche Prüfung */
752
- if ( empty($_POST['_action_request']) ) {
753
- exit();
754
- }
755
-
756
- /* Capability check */
757
- if ( ! current_user_can('manage_options') ) {
758
- return;
759
- }
760
-
761
- /* Init */
762
- $values = array();
763
- $output = '';
764
-
765
- /* Ausgabe starten */
766
- switch ($_POST['_action_request']) {
767
- case 'get_theme_files':
768
- self::_update_option(
769
- 'cronjob_alert',
770
- 0
771
- );
772
-
773
- $values = self::_get_theme_files();
774
- break;
775
-
776
- case 'check_theme_file':
777
- if ( ! empty($_POST['_theme_file']) && $lines = self::_check_theme_file($_POST['_theme_file']) ) {
778
- foreach( $lines as $num => $line ) {
779
- foreach( $line as $string ) {
780
- $values[] = $num;
781
- $values[] = htmlentities($string, ENT_QUOTES);
782
- $values[] = md5($num . $string);
783
- }
784
- }
785
- }
786
- break;
787
-
788
- case 'update_white_list':
789
- if ( ! empty($_POST['_file_md5']) && preg_match('/^[a-f0-9]{32}$/', $_POST['_file_md5']) ) {
790
- self::_update_option(
791
- 'white_list',
792
- implode(
793
- ':',
794
- array_unique(
795
- array_merge(
796
- self::_get_white_list(),
797
- array($_POST['_file_md5'])
798
- )
799
- )
800
- )
801
- );
802
-
803
- $values = array($_POST['_file_md5']);
804
- }
805
- break;
806
-
807
- default:
808
- break;
809
- }
810
-
811
- /* Ausgabe starten */
812
- if ( $values ) {
813
- $output = sprintf(
814
- "['%s']",
815
- implode("', '", $values)
816
- );
817
-
818
- /* Header senden */
819
- header('Content-Type: plain/text');
820
-
821
- /* Ausgeben */
822
- echo sprintf(
823
- '{data:%s, nonce:"%s"}',
824
- $output,
825
- $_POST['_ajax_nonce']
826
- );
827
- }
828
-
829
- /* Raus! */
830
- exit();
831
- }
832
-
833
-
834
- /**
835
- * Rückgabe des Dateiinhaltes
836
- *
837
- * @since 0.1
838
- * @change 1.3.4
839
- *
840
- * @param string $file Dateipfad
841
- * @return array Array mit Dateizeilen
842
- */
843
-
844
- private static function _get_file_content($file)
845
- {
846
- return file(WP_CONTENT_DIR . $file);
847
- }
848
-
849
-
850
- /**
851
- * Kürzung eines Strings
852
- *
853
- * @since 0.1
854
- * @change 1.3.4
855
- *
856
- * @param string $line Eigenetliche Zeile als String
857
- * @param string $tag Gesuchtes Tag
858
- * @param integer $max Anzahl der Zeichen rechts und links
859
- * @return string $output Gekürzter String
860
- */
861
-
862
- private static function _get_dotted_line($line, $tag, $max = 100)
863
- {
864
- /* Keine Werte? */
865
- if ( ! $line OR ! $tag ) {
866
- return false;
867
- }
868
-
869
- /* Differenz ermitteln */
870
- if ( strlen($tag) > $max ) {
871
- return $tag;
872
- }
873
-
874
- /* Differenz ermitteln */
875
- $left = round( ($max - strlen($tag)) / 2 );
876
-
877
- /* Wert konvertieren */
878
- $tag = preg_quote($tag);
879
-
880
- /* String kürzen */
881
- $output = preg_replace(
882
- '/(' .$tag. ')(.{' .$left. '}).{0,}$/',
883
- '$1$2 ...',
884
- $line
885
- );
886
- $output = preg_replace(
887
- '/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
888
- '... $1$2',
889
- $output
890
- );
891
-
892
- return $output;
893
- }
894
-
895
-
896
- /**
897
- * Definition des Regexp
898
- *
899
- * @since 0.1
900
- * @change 1.3.4
901
- *
902
- * @return string return Regulärer Ausdruck
903
- */
904
-
905
- private static function _php_match_pattern()
906
- {
907
- return '/(assert|file_get_contents|curl_exec|popen|proc_open|unserialize|eval|base64_encode|base64_decode|create_function|exec|shell_exec|system|passthru|ob_get_contents|file|curl_init|readfile|fopen|fsockopen|pfsockopen|fclose|fread|file_put_contents)\s*?\(/';
908
- }
909
-
910
-
911
- /**
912
- * Prüfung einer Zeile
913
- *
914
- * @since 0.1
915
- * @change 1.3.8
916
- *
917
- * @param string $line Zeile zur Prüfung
918
- * @param integer $num Nummer zur Prüfung
919
- * @return string $line Zeile mit Resultaten
920
- */
921
-
922
- private static function _check_file_line($line = '', $num)
923
- {
924
- /* Wert trimmen */
925
- $line = trim((string)$line);
926
-
927
- /* Leere Werte? */
928
- if ( ! $line OR ! isset($num) ) {
929
- return false;
930
- }
931
-
932
- /* Werte initialisieren */
933
- $results = array();
934
- $output = array();
935
-
936
- /* Befehle suchen */
937
- preg_match_all(
938
- self::_php_match_pattern(),
939
- $line,
940
- $matches
941
- );
942
-
943
- /* Ergebnis speichern */
944
- if ( $matches[1] ) {
945
- $results = $matches[1];
946
- }
947
-
948
-
949
- /* Base64 suchen */
950
- preg_match_all(
951
- '/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/', /* get length of my life ;) */
952
- $line,
953
- $matches
954
- );
955
-
956
- /* Ergebnis speichern */
957
- if ( $matches[1] ) {
958
- $results = array_merge($results, $matches[1]);
959
- }
960
-
961
-
962
- /* Frames suchen */
963
- preg_match_all(
964
- '/<\s*?(i?frame)/',
965
- $line,
966
- $matches
967
- );
968
-
969
- /* Ergebnis speichern */
970
- if ( $matches[1] ) {
971
- $results = array_merge($results, $matches[1]);
972
- }
973
-
974
-
975
- /* MailPoet Vulnerability */
976
- preg_match_all(
977
- '/explode\s?\(chr\s?\(\s?\(\d{3}\s?-\s?\d{3}\s?\)\s?\)\s?,/',
978
- $line,
979
- $matches
980
- );
981
-
982
- /* Ergebnis speichern */
983
- if ( $matches[0] ) {
984
- $results = array_merge($results, $matches[0]);
985
- }
986
-
987
-
988
- /* Option suchen */
989
- preg_match(
990
- '/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
991
- $line,
992
- $matches
993
- );
994
-
995
- /* Option prüfen */
996
- if ( $matches && $matches[1] && self::_check_file_line(get_option($matches[1]), $num) ) {
997
- array_push($results, 'get_option');
998
- }
999
-
1000
- /* Ergebnisse? */
1001
- if ( $results ) {
1002
- /* Keine Duplikate */
1003
- $results = array_unique($results);
1004
-
1005
- /* White-Liste */
1006
- $md5 = self::_get_white_list();
1007
-
1008
- /* Resultate loopen */
1009
- foreach( $results as $tag ) {
1010
- $string = str_replace(
1011
- $tag,
1012
- '@span@' .$tag. '@/span@',
1013
- self::_get_dotted_line($line, $tag)
1014
- );
1015
-
1016
- /* In der Whitelist? */
1017
- if ( ! in_array(md5($num . $string), $md5) ) {
1018
- $output[] = $string;
1019
- }
1020
- }
1021
-
1022
- return $output;
1023
- }
1024
-
1025
- return false;
1026
- }
1027
-
1028
-
1029
- /**
1030
- * Prüfung der Dateien des aktuellen Theme
1031
- *
1032
- * @since 0.1
1033
- * @change 1.3.4
1034
- *
1035
- * @return mixed $results Array mit Ergebnissen | FALSE im Fehlerfall
1036
- */
1037
-
1038
- private static function _check_theme_files()
1039
- {
1040
- /* Files vorhanden? */
1041
- if ( ! $files = self::_get_theme_files() ) {
1042
- return false;
1043
- }
1044
-
1045
- /* Init */
1046
- $results = array();
1047
-
1048
- /* Files loopen */
1049
- foreach( $files as $file ) {
1050
- if ( $result = self::_check_theme_file($file) ) {
1051
- $results[$file] = $result;
1052
- }
1053
- }
1054
-
1055
- /* Werte vorhanden? */
1056
- if ( ! empty($results) ) {
1057
- return $results;
1058
- }
1059
-
1060
- return false;
1061
- }
1062
-
1063
-
1064
- /**
1065
- * Prüfung einer Datei
1066
- *
1067
- * @since 0.1
1068
- * @change 1.3.6
1069
- *
1070
- * @param string $file Datei zur Prüfung
1071
- * @return mixed $results Array mit Ergebnissen | FALSE im Fehlerfall
1072
- */
1073
-
1074
- private static function _check_theme_file($file)
1075
- {
1076
- /* Simple file path check */
1077
- if ( filter_var($file, FILTER_SANITIZE_URL) !== $file ) {
1078
- return false;
1079
- }
1080
-
1081
- /* Sanitize file string */
1082
- if ( validate_file($file) !== 0 ) {
1083
- return false;
1084
- }
1085
-
1086
- /* Kein File? */
1087
- if ( ! $file ) {
1088
- return false;
1089
- }
1090
-
1091
- /* Inhalt auslesen */
1092
- if ( ! $content = self::_get_file_content($file) ) {
1093
- return false;
1094
- }
1095
-
1096
- /* Init */
1097
- $results = array();
1098
-
1099
- /* Zeilen loopen */
1100
- foreach( $content as $num => $line ) {
1101
- if ( $result = self::_check_file_line($line, $num) ) {
1102
- $results[$num] = $result;
1103
- }
1104
- }
1105
-
1106
- /* Werte vorhanden? */
1107
- if ( ! empty($results) ) {
1108
- return $results;
1109
- }
1110
-
1111
- return false;
1112
- }
1113
-
1114
-
1115
- /**
1116
- * Prüfung des Permalinks
1117
- *
1118
- * @since 0.1
1119
- * @change 1.3.4
1120
- *
1121
- * @return mixed $matches FALSE im Fehlerfall
1122
- */
1123
-
1124
- private static function _check_permalink_structure()
1125
- {
1126
- if ( $structure = get_option('permalink_structure') ) {
1127
- /* Befehle suchen */
1128
- preg_match_all(
1129
- self::_php_match_pattern(),
1130
- $structure,
1131
- $matches
1132
- );
1133
-
1134
- /* Ergebnis speichern */
1135
- if ( $matches[1] ) {
1136
- return $matches[1];
1137
- }
1138
- }
1139
-
1140
- return false;
1141
- }
1142
-
1143
-
1144
- /**
1145
- * Anzeige des Dashboard-Hinweises
1146
- *
1147
- * @since 0.1
1148
- * @change 1.3.5
1149
- */
1150
-
1151
- public static function show_dashboard_notice() {
1152
- /* Kein Alert? */
1153
- if ( ! self::_get_option('cronjob_alert') ) {
1154
- return;
1155
- }
1156
-
1157
- /* Warnung */
1158
- echo sprintf(
1159
- '<div class="error"><p><strong>%1$s:</strong> %2$s <a href="%3$s">%4$s &rarr;</a></p></div>',
1160
- esc_html__('Virus suspected', 'antivirus'),
1161
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
1162
- add_query_arg(
1163
- array(
1164
- 'page' => 'antivirus'
1165
- ),
1166
- admin_url('options-general.php')
1167
- ),
1168
- esc_html__('Manual malware scan', 'antivirus')
1169
- );
1170
- }
1171
-
1172
-
1173
- /**
1174
- * Anzeige der GUI
1175
- *
1176
- * @since 0.1
1177
- * @change 1.3.6
1178
- */
1179
-
1180
- public static function show_admin_menu() {
1181
- /* Updates speichern */
1182
- if ( ! empty($_POST) ) {
1183
- /* Referer prüfen */
1184
- check_admin_referer('antivirus');
1185
-
1186
- /* Werte zuweisen */
1187
- $options = array(
1188
- 'cronjob_enable' => (int)(!empty($_POST['av_cronjob_enable'])),
1189
- 'notify_email' => sanitize_email(@$_POST['av_notify_email']),
1190
- 'safe_browsing' => (int)(!empty($_POST['av_safe_browsing']))
1191
- );
1192
-
1193
- /* Kein Cronjob? */
1194
- if ( empty($options['cronjob_enable']) ) {
1195
- $options['notify_email'] = '';
1196
- $options['safe_browsing'] = 0;
1197
- }
1198
-
1199
- /* Cron stoppen? */
1200
- if ( $options['cronjob_enable'] && ! self::_get_option('cronjob_enable') ) {
1201
- self::_add_scheduled_hook();
1202
- } else if ( ! $options['cronjob_enable'] && self::_get_option('cronjob_enable') ) {
1203
- self::clear_scheduled_hook();
1204
- }
1205
-
1206
- /* Optionen speichern */
1207
- self::_update_options($options); ?>
1208
-
1209
- <div id="message" class="updated fade">
1210
- <p>
1211
- <strong>
1212
- <?php _e('Settings saved.') ?>
1213
- </strong>
1214
- </p>
1215
- </div>
1216
- <?php } ?>
1217
-
1218
- <div class="wrap" id="av_main">
1219
- <h2>
1220
- AntiVirus
1221
- </h2>
1222
-
1223
- <table class="form-table">
1224
- <tr valign="top">
1225
- <th scope="row">
1226
- <?php esc_html_e('Manual malware scan', 'antivirus') ?>
1227
- </th>
1228
- <td>
1229
- <div class="inside" id="av_manual_scan">
1230
- <p>
1231
- <a href="#" class="button button-primary">
1232
- <?php esc_html_e('Scan the theme templates now', 'antivirus') ?>
1233
- </a>
1234
- <span class="alert"></span>
1235
- </p>
1236
- <div class="output"></div>
1237
- </div>
1238
- </td>
1239
- </tr>
1240
- </table>
1241
-
1242
-
1243
- <form method="post" action="">
1244
- <?php wp_nonce_field('antivirus') ?>
1245
-
1246
- <table class="form-table">
1247
- <tr valign="top">
1248
- <th scope="row">
1249
- <?php esc_html_e('Daily malware scan', 'antivirus') ?>
1250
- </th>
1251
- <td>
1252
- <fieldset>
1253
- <label for="av_cronjob_enable">
1254
- <input type="checkbox" name="av_cronjob_enable" id="av_cronjob_enable" value="1" <?php checked(self::_get_option('cronjob_enable'), 1) ?> />
1255
- <?php esc_html_e('Check the theme templates for malware', 'antivirus') ?>
1256
- </label>
1257
-
1258
- <p class="description">
1259
- <?php if ( $timestamp = wp_next_scheduled('antivirus_daily_cronjob') ) {
1260
- echo sprintf(
1261
- '%s: %s',
1262
- esc_html__('Next Run', 'antivirus'),
1263
- date_i18n('d.m.Y H:i:s', $timestamp + get_option('gmt_offset') * 3600)
1264
- );
1265
- } ?>
1266
- </p>
1267
-
1268
-
1269
- <br />
1270
-
1271
-
1272
- <label for="av_safe_browsing">
1273
- <input type="checkbox" name="av_safe_browsing" id="av_safe_browsing" value="1" <?php checked(self::_get_option('safe_browsing'), 1) ?> />
1274
- <?php esc_html_e('Malware detection by Google Safe Browsing', 'antivirus') ?>
1275
- </label>
1276
-
1277
- <p class="description">
1278
- <?php esc_html_e('Diagnosis and notification in suspicion case', 'antivirus') ?>
1279
- </p>
1280
-
1281
-
1282
- <br />
1283
-
1284
-
1285
- <label for="av_notify_email">
1286
- <input type="text" name="av_notify_email" id="av_notify_email" value="<?php esc_attr_e(self::_get_option('notify_email')) ?>" class="regular-text" placeholder="<?php esc_attr_e('Email address for notifications', 'antivirus') ?>" />
1287
- </label>
1288
-
1289
- <p class="description">
1290
- <?php esc_html_e('If the field is empty, the blog admin will be notified', 'antivirus') ?>
1291
- </p>
1292
- </fieldset>
1293
- </td>
1294
- </tr>
1295
-
1296
- <tr valign="top">
1297
- <th scope="row">
1298
- <input type="submit" class="button button-primary" value="<?php _e('Save Changes') ?>" />
1299
- </th>
1300
- <td>
1301
- <?php if ( get_locale() == 'de_DE' ) { ?><a href="http://playground.ebiene.de/antivirus-wordpress-plugin/" target="_blank">Handbuch</a> &bull; <?php } ?><a href="https://flattr.com/t/1322865" target="_blank">Flattr</a> &bull; <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=5RDDW9FEHGLG6" target="_blank">PayPal</a>
1302
- </td>
1303
- </tr>
1304
- </table>
1305
- </form>
1306
- </div>
1307
- <?php }
1308
- }
1309
-
1310
-
1311
- /* Fire */
1312
- add_action(
1313
- 'plugins_loaded',
1314
- array(
1315
- 'AntiVirus',
1316
- 'instance'
1317
- ),
1318
- 99
1319
- );
1320
-
1321
-
1322
- /* Hooks */
1323
- register_activation_hook(
1324
- __FILE__,
1325
- array(
1326
- 'AntiVirus',
1327
- 'install'
1328
- )
1329
- );
1330
- register_deactivation_hook(
1331
- __FILE__,
1332
- array(
1333
- 'AntiVirus',
1334
- 'deactivation'
1335
- )
1336
- );
1337
- register_uninstall_hook(
1338
- __FILE__,
1339
- array(
1340
- 'AntiVirus',
1341
- 'uninstall'
1342
- )
1343
- );
1
+ <?php
2
+ /*
3
+ Plugin Name: AntiVirus
4
+ Description: Security plugin to protect your blog or website against exploits and spam injections.
5
+ Author: pluginkollektiv
6
+ Author URI: http://pluginkollektiv.org
7
+ Plugin URI: https://wordpress.org/plugins/antivirus/
8
+ Text Domain: antivirus
9
+ Domain Path: /lang
10
+ License: GPLv2 or later
11
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
+ Version: 1.3.9
13
+ */
14
+
15
+ /*
16
+ Copyright (C) 2009-2015 Sergej Müller
17
+
18
+ This program is free software; you can redistribute it and/or modify
19
+ it under the terms of the GNU General Public License as published by
20
+ the Free Software Foundation; either version 2 of the License, or
21
+ (at your option) any later version.
22
+
23
+ This program is distributed in the hope that it will be useful,
24
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
+ GNU General Public License for more details.
27
+
28
+ You should have received a copy of the GNU General Public License along
29
+ with this program; if not, write to the Free Software Foundation, Inc.,
30
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31
+ */
32
+
33
+
34
+ /* Sicherheitsabfrage */
35
+ if ( ! class_exists('WP') ) {
36
+ die();
37
+ }
38
+
39
+
40
+ /**
41
+ * AntiVirus
42
+ *
43
+ * @since 0.1
44
+ */
45
+
46
+ class AntiVirus {
47
+
48
+
49
+ /* Save me! */
50
+ private static $base;
51
+
52
+
53
+ /**
54
+ * Pseudo-Konstruktor der Klasse
55
+ *
56
+ * @since 1.3.4
57
+ * @change 1.3.4
58
+ */
59
+
60
+ public static function instance()
61
+ {
62
+ new self();
63
+ }
64
+
65
+
66
+ /**
67
+ * Konstruktor der Klasse
68
+ *
69
+ * @since 0.1
70
+ * @change 1.3.5
71
+ */
72
+
73
+ public function __construct()
74
+ {
75
+ /* AUTOSAVE */
76
+ if ( ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) OR ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) ) {
77
+ return;
78
+ }
79
+
80
+ /* Plugin-Base */
81
+ self::$base = plugin_basename(__FILE__);
82
+
83
+ /* Cronjob */
84
+ if ( defined('DOING_CRON') ) {
85
+ add_action(
86
+ 'antivirus_daily_cronjob',
87
+ array(
88
+ __CLASS__,
89
+ 'do_daily_cronjob'
90
+ )
91
+ );
92
+
93
+ /* Admin */
94
+ } elseif ( is_admin() ) {
95
+ /* AJAX */
96
+ if ( defined('DOING_AJAX') ) {
97
+ add_action(
98
+ 'wp_ajax_get_ajax_response',
99
+ array(
100
+ __CLASS__,
101
+ 'get_ajax_response'
102
+ )
103
+ );
104
+
105
+ /* Backend */
106
+ } else {
107
+ /* Actions */
108
+ add_action(
109
+ 'init',
110
+ array(
111
+ __CLASS__,
112
+ 'load_plugin_lang'
113
+ )
114
+ );
115
+ add_action(
116
+ 'admin_menu',
117
+ array(
118
+ __CLASS__,
119
+ 'add_sidebar_menu'
120
+ )
121
+ );
122
+ add_action(
123
+ 'admin_notices',
124
+ array(
125
+ __CLASS__,
126
+ 'show_dashboard_notice'
127
+ )
128
+ );
129
+ add_action(
130
+ 'deactivate_' .self::$base,
131
+ array(
132
+ __CLASS__,
133
+ 'clear_scheduled_hook'
134
+ )
135
+ );
136
+ add_filter(
137
+ 'plugin_row_meta',
138
+ array(
139
+ __CLASS__,
140
+ 'init_row_meta'
141
+ ),
142
+ 10,
143
+ 2
144
+ );
145
+ add_filter(
146
+ 'plugin_action_links_' .self::$base,
147
+ array(
148
+ __CLASS__,
149
+ 'init_action_links'
150
+ )
151
+ );
152
+ }
153
+ }
154
+ }
155
+
156
+
157
+ /**
158
+ * Einbindung der Sprache
159
+ *
160
+ * @since 0.8
161
+ * @change 0.8
162
+ */
163
+
164
+ public static function load_plugin_lang()
165
+ {
166
+ load_plugin_textdomain(
167
+ 'antivirus',
168
+ false,
169
+ 'antivirus/lang'
170
+ );
171
+ }
172
+
173
+
174
+ /**
175
+ * Hinzufügen der Action-Links (Einstellungen links)
176
+ *
177
+ * @since 1.1
178
+ * @change 1.3.4
179
+ *
180
+ * @param array $data Array mit Links
181
+ * @return array $data Array mit erweitertem Link
182
+ */
183
+
184
+ public static function init_action_links($data)
185
+ {
186
+ /* Rechte? */
187
+ if ( ! current_user_can('manage_options') ) {
188
+ return $data;
189
+ }
190
+
191
+ return array_merge(
192
+ $data,
193
+ array(
194
+ sprintf(
195
+ '<a href="%s">%s</a>',
196
+ add_query_arg(
197
+ array(
198
+ 'page' => 'antivirus'
199
+ ),
200
+ admin_url('options-general.php')
201
+ ),
202
+ __('Settings')
203
+ )
204
+ )
205
+ );
206
+ }
207
+
208
+
209
+ /**
210
+ * Links in der Plugin-Verwaltung
211
+ *
212
+ * @since 0.1
213
+ * @change 1.3.4
214
+ *
215
+ * @param array $data Array mit Links
216
+ * @param string $page Aktuelle Seite
217
+ * @return array $data Array mit erweitertem Link
218
+ */
219
+
220
+ public static function init_row_meta($data, $page)
221
+ {
222
+ if ( $page != self::$base ) {
223
+ return $data;
224
+ }
225
+
226
+ return array_merge(
227
+ $data,
228
+ array(
229
+ '<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=LG5VC9KXMAYXJ" target="_blank">PayPal</a>'
230
+ )
231
+ );
232
+ }
233
+
234
+
235
+ /**
236
+ * Aktion bei Aktivierung des Plugins
237
+ *
238
+ * @since 0.1
239
+ * @change 1.3.4
240
+ */
241
+
242
+ public static function install()
243
+ {
244
+ /* Option anlegen */
245
+ add_option(
246
+ 'antivirus',
247
+ array(),
248
+ '',
249
+ 'no'
250
+ );
251
+
252
+ /* Cron aktivieren */
253
+ if ( self::_get_option('cronjob_enable') ) {
254
+ self::_add_scheduled_hook();
255
+ }
256
+ }
257
+
258
+
259
+ /**
260
+ * Aktionen bei der Deaktivierung des Plugins
261
+ *
262
+ * @since 1.3.4
263
+ * @change 1.3.4
264
+ */
265
+
266
+ public static function deactivation()
267
+ {
268
+ self::clear_scheduled_hook();
269
+ }
270
+
271
+
272
+ /**
273
+ * Uninstallation des Plugins pro MU-Blog
274
+ *
275
+ * @since 1.1
276
+ * @change 1.3.5
277
+ */
278
+
279
+ public static function uninstall()
280
+ {
281
+ delete_option('antivirus');
282
+ }
283
+
284
+
285
+ /**
286
+ * Rückgabe eines Optionsfeldes
287
+ *
288
+ * @since 0.1
289
+ * @change 1.3.4
290
+ *
291
+ * @param string $field Name einer Option
292
+ * @return mixed Wert einer Option
293
+ */
294
+
295
+ private static function _get_option($field)
296
+ {
297
+ $options = wp_parse_args(
298
+ get_option('antivirus'),
299
+ array(
300
+ 'cronjob_enable' => 0,
301
+ 'cronjob_alert' => 0,
302
+ 'safe_browsing' => 0,
303
+ 'notify_email' => '',
304
+ 'white_list' => ''
305
+ )
306
+ );
307
+
308
+ return ( empty($options[$field]) ? '' : $options[$field] );
309
+ }
310
+
311
+
312
+ /**
313
+ * Aktualisiert ein Optionsfeld
314
+ *
315
+ * @since 0.1
316
+ * @change 1.3.4
317
+ *
318
+ * @param string $field Name des Feldes
319
+ * @param mixed Wert des Feldes
320
+ */
321
+
322
+ private static function _update_option($field, $value)
323
+ {
324
+ self::_update_options(
325
+ array(
326
+ $field => $value
327
+ )
328
+ );
329
+ }
330
+
331
+
332
+ /**
333
+ * Aktualisiert mehrere Optionsfelder
334
+ *
335
+ * @since 0.1
336
+ * @change 1.3.4
337
+ *
338
+ * @param array $data Array mit Feldern
339
+ */
340
+
341
+ private static function _update_options($data)
342
+ {
343
+ update_option(
344
+ 'antivirus',
345
+ array_merge(
346
+ (array)get_option('antivirus'),
347
+ $data
348
+ )
349
+ );
350
+ }
351
+
352
+
353
+ /**
354
+ * Initialisierung des Cronjobs
355
+ *
356
+ * @since 1.3.4
357
+ * @change 1.3.4
358
+ */
359
+
360
+ private static function _add_scheduled_hook()
361
+ {
362
+ if ( ! wp_next_scheduled('antivirus_daily_cronjob') ) {
363
+ wp_schedule_event(
364
+ time(),
365
+ 'daily',
366
+ 'antivirus_daily_cronjob'
367
+ );
368
+ }
369
+ }
370
+
371
+
372
+ /**
373
+ * Beendigung des Cronjobs
374
+ *
375
+ * @since 0.1
376
+ * @change 0.8
377
+ */
378
+
379
+ public static function clear_scheduled_hook()
380
+ {
381
+ if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
382
+ wp_clear_scheduled_hook('antivirus_daily_cronjob');
383
+ }
384
+ }
385
+
386
+
387
+ /**
388
+ * Ausführung des Cronjobs
389
+ *
390
+ * @since 0.1
391
+ * @change 1.3.4
392
+ */
393
+
394
+ public static function do_daily_cronjob()
395
+ {
396
+ /* Kein Cronjob? */
397
+ if ( ! self::_get_option('cronjob_enable') ) {
398
+ return;
399
+ }
400
+
401
+ /* Load translation */
402
+ self::load_plugin_lang();
403
+
404
+ /* Safe Browsing API */
405
+ self::_check_safe_browsing();
406
+
407
+ /* Theme & Permalinks */
408
+ self::_check_blog_internals();
409
+ }
410
+
411
+
412
+ /**
413
+ * Führt die Safe Browsing Prüfung aus
414
+ *
415
+ * @since 1.3.4
416
+ * @change 1.3.7
417
+ */
418
+
419
+ private static function _check_safe_browsing()
420
+ {
421
+ /* Not enabled? */
422
+ if ( ! self::_get_option('safe_browsing') ) {
423
+ return;
424
+ }
425
+
426
+ /* Start request */
427
+ $response = wp_remote_get(
428
+ sprintf(
429
+ 'https://sb-ssl.google.com/safebrowsing/api/lookup?client=wpantivirus&key=%s&appver=1.3.7&pver=3.1&url=%s',
430
+ 'AIzaSyALNYwuy-Pidn7vx3-In-hU0zgMH5Wr42U',
431
+ urlencode( get_bloginfo('url') )
432
+ )
433
+ );
434
+
435
+ /* API Error? */
436
+ if ( is_wp_error($response) ) {
437
+ return;
438
+ }
439
+
440
+ /* All clear */
441
+ if ( wp_remote_retrieve_response_code($response) === 204 ) {
442
+ return;
443
+ }
444
+
445
+ /* Send notification */
446
+ self::_send_warning_notification(
447
+ esc_html__('Safe Browsing Alert', 'antivirus'),
448
+ sprintf(
449
+ "%s\r\nhttps://www.google.com/safebrowsing/diagnostic?site=%s&hl=%s",
450
+ esc_html__('Please check the Google Safe Browsing diagnostic page:', 'antivirus'),
451
+ urlencode( get_bloginfo('url') ),
452
+ substr(get_locale(), 0, 2)
453
+ )
454
+ );
455
+ }
456
+
457
+
458
+ /**
459
+ * Führt die Blog-interne Prüfung aus
460
+ *
461
+ * @since 1.3.4
462
+ * @change 1.3.4
463
+ */
464
+
465
+ private static function _check_blog_internals()
466
+ {
467
+ /* Execute checks */
468
+ if ( ! self::_check_theme_files() && ! self::_check_permalink_structure() ) {
469
+ return;
470
+ }
471
+
472
+ /* Send notification */
473
+ self::_send_warning_notification(
474
+ esc_html__('Virus suspected', 'antivirus'),
475
+ sprintf(
476
+ "%s\r\n%s",
477
+ esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
478
+ get_bloginfo('url')
479
+ )
480
+ );
481
+
482
+ /* Store alert */
483
+ self::_update_option(
484
+ 'cronjob_alert',
485
+ 1
486
+ );
487
+ }
488
+
489
+
490
+ /**
491
+ * Führt die Safe Browsing Prüfung aus
492
+ *
493
+ * @since 1.3.4
494
+ * @change 1.3.6
495
+ *
496
+ * @param string $subject Betreff der E-Mail
497
+ * @param string $body Inhalt der E-Mail
498
+ */
499
+
500
+ private static function _send_warning_notification($subject, $body)
501
+ {
502
+ /* Receiver email address */
503
+ $email = self::_get_option('notify_email');
504
+
505
+ /* Email address fallback */
506
+ if ( ! is_email($email) ) {
507
+ $email = get_bloginfo('admin_email');
508
+ }
509
+
510
+ /* Send it! */
511
+ wp_mail(
512
+ $email,
513
+ sprintf(
514
+ '[%s] %s',
515
+ get_bloginfo('name'),
516
+ $subject
517
+ ),
518
+ sprintf(
519
+ "%s\r\n\r\n\r\n%s\r\n%s\r\n",
520
+ $body,
521
+ esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
522
+ esc_html__('http://wpantivirus.com', 'antivirus')
523
+ )
524
+ );
525
+ }
526
+
527
+
528
+ /**
529
+ * Initialisierung der GUI
530
+ *
531
+ * @since 0.1
532
+ * @change 1.3.5
533
+ */
534
+
535
+ public static function add_sidebar_menu()
536
+ {
537
+ /* Menü anlegen */
538
+ $page = add_options_page(
539
+ 'AntiVirus',
540
+ 'AntiVirus',
541
+ 'manage_options',
542
+ 'antivirus',
543
+ array(
544
+ __CLASS__,
545
+ 'show_admin_menu'
546
+ )
547
+ );
548
+
549
+ add_action(
550
+ 'admin_print_styles-' . $page,
551
+ array(
552
+ __CLASS__,
553
+ 'add_enqueue_style'
554
+ )
555
+ );
556
+ add_action(
557
+ 'admin_print_scripts-' . $page,
558
+ array(
559
+ __CLASS__,
560
+ 'add_enqueue_script'
561
+ )
562
+ );
563
+ }
564
+
565
+
566
+ /**
567
+ * Initialisierung von JavaScript
568
+ *
569
+ * @since 0.8
570
+ * @change 1.3.5
571
+ */
572
+
573
+ public static function add_enqueue_script()
574
+ {
575
+ /* Infos auslesen */
576
+ $data = get_plugin_data(__FILE__);
577
+
578
+ /* JS einbinden */
579
+ wp_register_script(
580
+ 'av_script',
581
+ plugins_url('js/script.min.js', __FILE__),
582
+ array('jquery'),
583
+ $data['Version']
584
+ );
585
+
586
+ /* Script einbinden */
587
+ wp_enqueue_script('av_script');
588
+
589
+ /* Script lokalisieren */
590
+ wp_localize_script(
591
+ 'av_script',
592
+ 'av_settings',
593
+ array(
594
+ 'nonce' => wp_create_nonce('av_ajax_nonce'),
595
+ 'theme' => esc_js(urlencode(self::_get_theme_name())),
596
+ 'msg_1' => esc_js(__('There is no virus', 'antivirus')),
597
+ 'msg_2' => esc_js(__('View line', 'antivirus')),
598
+ 'msg_3' => esc_js(__('Scan finished', 'antivirus'))
599
+ )
600
+ );
601
+ }
602
+
603
+
604
+ /**
605
+ * Initialisierung von Stylesheets
606
+ *
607
+ * @since 0.8
608
+ * @change 1.3.4
609
+ */
610
+
611
+ public static function add_enqueue_style()
612
+ {
613
+ /* Infos auslesen */
614
+ $data = get_plugin_data(__FILE__);
615
+
616
+ /* CSS registrieren */
617
+ wp_register_style(
618
+ 'av_css',
619
+ plugins_url('css/style.min.css', __FILE__),
620
+ array(),
621
+ $data['Version']
622
+ );
623
+
624
+ /* CSS einbinden */
625
+ wp_enqueue_style('av_css');
626
+ }
627
+
628
+
629
+ /**
630
+ * Rückgabe des aktuellen Theme
631
+ *
632
+ * @since 0.1
633
+ * @change 1.3.6
634
+ *
635
+ * @return array $themes Array mit Theme-Eigenschaften
636
+ */
637
+
638
+ private static function _get_current_theme()
639
+ {
640
+ /* Init */
641
+ $theme = wp_get_theme();
642
+ $name = $theme->get('Name');
643
+ $slug = $theme->get_stylesheet();
644
+ $files = $theme->get_files('php', 1);
645
+
646
+ /* Leer? */
647
+ if ( empty($name) OR empty($files) ) {
648
+ return false;
649
+ }
650
+
651
+ /* Rückgabe */
652
+ return array(
653
+ 'Name' => $name,
654
+ 'Slug' => $slug,
655
+ 'Template Files' => $files
656
+ );
657
+ }
658
+
659
+
660
+ /**
661
+ * Rückgabe von Dateien des aktuellen Theme
662
+ *
663
+ * @since 0.1
664
+ * @change 1.3.4
665
+ *
666
+ * @return array $files Array mit Dateien
667
+ */
668
+
669
+ private static function _get_theme_files()
670
+ {
671
+ /* Theme vorhanden? */
672
+ if ( ! $theme = self::_get_current_theme() ) {
673
+ return false;
674
+ }
675
+
676
+ /* Keine Files? */
677
+ if ( empty($theme['Template Files']) ) {
678
+ return false;
679
+ }
680
+
681
+ /* Zurückgeben */
682
+ return array_unique(
683
+ array_map(
684
+ create_function(
685
+ '$v',
686
+ 'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
687
+ ),
688
+ $theme['Template Files']
689
+ )
690
+ );
691
+ }
692
+
693
+
694
+ /**
695
+ * Rückgabe des Namen des aktuellen Theme
696
+ *
697
+ * @since 0.1
698
+ * @change 1.3.4
699
+ *
700
+ * @return string $theme Name des aktuellen Theme
701
+ */
702
+
703
+ private static function _get_theme_name()
704
+ {
705
+ if ( $theme = self::_get_current_theme() ) {
706
+ if ( ! empty($theme['Slug']) ) {
707
+ return $theme['Slug'];
708
+ }
709
+ if ( ! empty($theme['Name']) ) {
710
+ return $theme['Name'];
711
+ }
712
+ }
713
+
714
+ return false;
715
+ }
716
+
717
+
718
+ /**
719
+ * Rückgabe der WhiteList
720
+ *
721
+ * @since 0.1
722
+ * @change 1.3.4
723
+ *
724
+ * @return array return Array mit MD5-Werten
725
+ */
726
+
727
+ private static function _get_white_list()
728
+ {
729
+ return explode(
730
+ ':',
731
+ self::_get_option('white_list')
732
+ );
733
+ }
734
+
735
+
736
+ /**
737
+ * Ausführung von AJAX
738
+ *
739
+ * @since 0.1
740
+ * @change 1.3.4
741
+ */
742
+
743
+ public static function get_ajax_response()
744
+ {
745
+ /* Referer prüfen */
746
+ check_ajax_referer('av_ajax_nonce');
747
+
748
+ /* Zusätzliche Prüfung */
749
+ if ( empty($_POST['_action_request']) ) {
750
+ exit();
751
+ }
752
+
753
+ /* Capability check */
754
+ if ( ! current_user_can('manage_options') ) {
755
+ return;
756
+ }
757
+
758
+ /* Init */
759
+ $values = array();
760
+ $output = '';
761
+
762
+ /* Ausgabe starten */
763
+ switch ($_POST['_action_request']) {
764
+ case 'get_theme_files':
765
+ self::_update_option(
766
+ 'cronjob_alert',
767
+ 0
768
+ );
769
+
770
+ $values = self::_get_theme_files();
771
+ break;
772
+
773
+ case 'check_theme_file':
774
+ if ( ! empty($_POST['_theme_file']) && $lines = self::_check_theme_file($_POST['_theme_file']) ) {
775
+ foreach( $lines as $num => $line ) {
776
+ foreach( $line as $string ) {
777
+ $values[] = $num;
778
+ $values[] = htmlentities($string, ENT_QUOTES);
779
+ $values[] = md5($num . $string);
780
+ }
781
+ }
782
+ }
783
+ break;
784
+
785
+ case 'update_white_list':
786
+ if ( ! empty($_POST['_file_md5']) && preg_match('/^[a-f0-9]{32}$/', $_POST['_file_md5']) ) {
787
+ self::_update_option(
788
+ 'white_list',
789
+ implode(
790
+ ':',
791
+ array_unique(
792
+ array_merge(
793
+ self::_get_white_list(),
794
+ array($_POST['_file_md5'])
795
+ )
796
+ )
797
+ )
798
+ );
799
+
800
+ $values = array($_POST['_file_md5']);
801
+ }
802
+ break;
803
+
804
+ default:
805
+ break;
806
+ }
807
+
808
+ /* Ausgabe starten */
809
+ if ( $values ) {
810
+ wp_send_json(
811
+ array(
812
+ 'data' => array_values($values),
813
+ 'nonce' => $_POST['_ajax_nonce']
814
+ )
815
+ );
816
+ }
817
+
818
+ /* Raus! */
819
+ exit();
820
+ }
821
+
822
+
823
+ /**
824
+ * Rückgabe des Dateiinhaltes
825
+ *
826
+ * @since 0.1
827
+ * @change 1.3.4
828
+ *
829
+ * @param string $file Dateipfad
830
+ * @return array Array mit Dateizeilen
831
+ */
832
+
833
+ private static function _get_file_content($file)
834
+ {
835
+ return file(WP_CONTENT_DIR . $file);
836
+ }
837
+
838
+
839
+ /**
840
+ * Kürzung eines Strings
841
+ *
842
+ * @since 0.1
843
+ * @change 1.3.4
844
+ *
845
+ * @param string $line Eigenetliche Zeile als String
846
+ * @param string $tag Gesuchtes Tag
847
+ * @param integer $max Anzahl der Zeichen rechts und links
848
+ * @return string $output Gekürzter String
849
+ */
850
+
851
+ private static function _get_dotted_line($line, $tag, $max = 100)
852
+ {
853
+ /* Keine Werte? */
854
+ if ( ! $line OR ! $tag ) {
855
+ return false;
856
+ }
857
+
858
+ /* Differenz ermitteln */
859
+ if ( strlen($tag) > $max ) {
860
+ return $tag;
861
+ }
862
+
863
+ /* Differenz ermitteln */
864
+ $left = round( ($max - strlen($tag)) / 2 );
865
+
866
+ /* Wert konvertieren */
867
+ $tag = preg_quote($tag);
868
+
869
+ /* String kürzen */
870
+ $output = preg_replace(
871
+ '/(' .$tag. ')(.{' .$left. '}).{0,}$/',
872
+ '$1$2 ...',
873
+ $line
874
+ );
875
+ $output = preg_replace(
876
+ '/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
877
+ '... $1$2',
878
+ $output
879
+ );
880
+
881
+ return $output;
882
+ }
883
+
884
+
885
+ /**
886
+ * Definition des Regexp
887
+ *
888
+ * @since 0.1
889
+ * @change 1.3.4
890
+ *
891
+ * @return string return Regulärer Ausdruck
892
+ */
893
+
894
+ private static function _php_match_pattern()
895
+ {
896
+ return '/(assert|file_get_contents|curl_exec|popen|proc_open|unserialize|eval|base64_encode|base64_decode|create_function|exec|shell_exec|system|passthru|ob_get_contents|file|curl_init|readfile|fopen|fsockopen|pfsockopen|fclose|fread|file_put_contents)\s*?\(/';
897
+ }
898
+
899
+
900
+ /**
901
+ * Prüfung einer Zeile
902
+ *
903
+ * @since 0.1
904
+ * @change 1.3.8
905
+ *
906
+ * @param string $line Zeile zur Prüfung
907
+ * @param integer $num Nummer zur Prüfung
908
+ * @return string $line Zeile mit Resultaten
909
+ */
910
+
911
+ private static function _check_file_line($line = '', $num)
912
+ {
913
+ /* Wert trimmen */
914
+ $line = trim((string)$line);
915
+
916
+ /* Leere Werte? */
917
+ if ( ! $line OR ! isset($num) ) {
918
+ return false;
919
+ }
920
+
921
+ /* Werte initialisieren */
922
+ $results = array();
923
+ $output = array();
924
+
925
+ /* Befehle suchen */
926
+ preg_match_all(
927
+ self::_php_match_pattern(),
928
+ $line,
929
+ $matches
930
+ );
931
+
932
+ /* Ergebnis speichern */
933
+ if ( $matches[1] ) {
934
+ $results = $matches[1];
935
+ }
936
+
937
+
938
+ /* Base64 suchen */
939
+ preg_match_all(
940
+ '/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/', /* get length of my life ;) */
941
+ $line,
942
+ $matches
943
+ );
944
+
945
+ /* Ergebnis speichern */
946
+ if ( $matches[1] ) {
947
+ $results = array_merge($results, $matches[1]);
948
+ }
949
+
950
+
951
+ /* Frames suchen */
952
+ preg_match_all(
953
+ '/<\s*?(i?frame)/',
954
+ $line,
955
+ $matches
956
+ );
957
+
958
+ /* Ergebnis speichern */
959
+ if ( $matches[1] ) {
960
+ $results = array_merge($results, $matches[1]);
961
+ }
962
+
963
+
964
+ /* MailPoet Vulnerability */
965
+ preg_match_all(
966
+ '/explode\s?\(chr\s?\(\s?\(\d{3}\s?-\s?\d{3}\s?\)\s?\)\s?,/',
967
+ $line,
968
+ $matches
969
+ );
970
+
971
+ /* Ergebnis speichern */
972
+ if ( $matches[0] ) {
973
+ $results = array_merge($results, $matches[0]);
974
+ }
975
+
976
+
977
+ /* Option suchen */
978
+ preg_match(
979
+ '/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
980
+ $line,
981
+ $matches
982
+ );
983
+
984
+ /* Option prüfen */
985
+ if ( $matches && $matches[1] && self::_check_file_line(get_option($matches[1]), $num) ) {
986
+ array_push($results, 'get_option');
987
+ }
988
+
989
+ /* Ergebnisse? */
990
+ if ( $results ) {
991
+ /* Keine Duplikate */
992
+ $results = array_unique($results);
993
+
994
+ /* White-Liste */
995
+ $md5 = self::_get_white_list();
996
+
997
+ /* Resultate loopen */
998
+ foreach( $results as $tag ) {
999
+ $string = str_replace(
1000
+ $tag,
1001
+ '@span@' .$tag. '@/span@',
1002
+ self::_get_dotted_line($line, $tag)
1003
+ );
1004
+
1005
+ /* In der Whitelist? */
1006
+ if ( ! in_array(md5($num . $string), $md5) ) {
1007
+ $output[] = $string;
1008
+ }
1009
+ }
1010
+
1011
+ return $output;
1012
+ }
1013
+
1014
+ return false;
1015
+ }
1016
+
1017
+
1018
+ /**
1019
+ * Prüfung der Dateien des aktuellen Theme
1020
+ *
1021
+ * @since 0.1
1022
+ * @change 1.3.4
1023
+ *
1024
+ * @return mixed $results Array mit Ergebnissen | FALSE im Fehlerfall
1025
+ */
1026
+
1027
+ private static function _check_theme_files()
1028
+ {
1029
+ /* Files vorhanden? */
1030
+ if ( ! $files = self::_get_theme_files() ) {
1031
+ return false;
1032
+ }
1033
+
1034
+ /* Init */
1035
+ $results = array();
1036
+
1037
+ /* Files loopen */
1038
+ foreach( $files as $file ) {
1039
+ if ( $result = self::_check_theme_file($file) ) {
1040
+ $results[$file] = $result;
1041
+ }
1042
+ }
1043
+
1044
+ /* Werte vorhanden? */
1045
+ if ( ! empty($results) ) {
1046
+ return $results;
1047
+ }
1048
+
1049
+ return false;
1050
+ }
1051
+
1052
+
1053
+ /**
1054
+ * Prüfung einer Datei
1055
+ *
1056
+ * @since 0.1
1057
+ * @change 1.3.6
1058
+ *
1059
+ * @param string $file Datei zur Prüfung
1060
+ * @return mixed $results Array mit Ergebnissen | FALSE im Fehlerfall
1061
+ */
1062
+
1063
+ private static function _check_theme_file($file)
1064
+ {
1065
+ /* Simple file path check */
1066
+ if ( filter_var($file, FILTER_SANITIZE_URL) !== $file ) {
1067
+ return false;
1068
+ }
1069
+
1070
+ /* Sanitize file string */
1071
+ if ( validate_file($file) !== 0 ) {
1072
+ return false;
1073
+ }
1074
+
1075
+ /* Kein File? */
1076
+ if ( ! $file ) {
1077
+ return false;
1078
+ }
1079
+
1080
+ /* Inhalt auslesen */
1081
+ if ( ! $content = self::_get_file_content($file) ) {
1082
+ return false;
1083
+ }
1084
+
1085
+ /* Init */
1086
+ $results = array();
1087
+
1088
+ /* Zeilen loopen */
1089
+ foreach( $content as $num => $line ) {
1090
+ if ( $result = self::_check_file_line($line, $num) ) {
1091
+ $results[$num] = $result;
1092
+ }
1093
+ }
1094
+
1095
+ /* Werte vorhanden? */
1096
+ if ( ! empty($results) ) {
1097
+ return $results;
1098
+ }
1099
+
1100
+ return false;
1101
+ }
1102
+
1103
+
1104
+ /**
1105
+ * Prüfung des Permalinks
1106
+ *
1107
+ * @since 0.1
1108
+ * @change 1.3.4
1109
+ *
1110
+ * @return mixed $matches FALSE im Fehlerfall
1111
+ */
1112
+
1113
+ private static function _check_permalink_structure()
1114
+ {
1115
+ if ( $structure = get_option('permalink_structure') ) {
1116
+ /* Befehle suchen */
1117
+ preg_match_all(
1118
+ self::_php_match_pattern(),
1119
+ $structure,
1120
+ $matches
1121
+ );
1122
+
1123
+ /* Ergebnis speichern */
1124
+ if ( $matches[1] ) {
1125
+ return $matches[1];
1126
+ }
1127
+ }
1128
+
1129
+ return false;
1130
+ }
1131
+
1132
+
1133
+ /**
1134
+ * Anzeige des Dashboard-Hinweises
1135
+ *
1136
+ * @since 0.1
1137
+ * @change 1.3.5
1138
+ */
1139
+
1140
+ public static function show_dashboard_notice() {
1141
+ /* Kein Alert? */
1142
+ if ( ! self::_get_option('cronjob_alert') ) {
1143
+ return;
1144
+ }
1145
+
1146
+ /* Warnung */
1147
+ echo sprintf(
1148
+ '<div class="error"><p><strong>%1$s:</strong> %2$s <a href="%3$s">%4$s &rarr;</a></p></div>',
1149
+ esc_html__('Virus suspected', 'antivirus'),
1150
+ esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
1151
+ add_query_arg(
1152
+ array(
1153
+ 'page' => 'antivirus'
1154
+ ),
1155
+ admin_url('options-general.php')
1156
+ ),
1157
+ esc_html__('Manual malware scan', 'antivirus')
1158
+ );
1159
+ }
1160
+
1161
+
1162
+ /**
1163
+ * Anzeige der GUI
1164
+ *
1165
+ * @since 0.1
1166
+ * @change 1.3.6
1167
+ */
1168
+
1169
+ public static function show_admin_menu() {
1170
+ /* Updates speichern */
1171
+ if ( ! empty($_POST) ) {
1172
+ /* Referer prüfen */
1173
+ check_admin_referer('antivirus');
1174
+
1175
+ /* Werte zuweisen */
1176
+ $options = array(
1177
+ 'cronjob_enable' => (int)(!empty($_POST['av_cronjob_enable'])),
1178
+ 'notify_email' => sanitize_email(@$_POST['av_notify_email']),
1179
+ 'safe_browsing' => (int)(!empty($_POST['av_safe_browsing']))
1180
+ );
1181
+
1182
+ /* Kein Cronjob? */
1183
+ if ( empty($options['cronjob_enable']) ) {
1184
+ $options['notify_email'] = '';
1185
+ $options['safe_browsing'] = 0;
1186
+ }
1187
+
1188
+ /* Cron stoppen? */
1189
+ if ( $options['cronjob_enable'] && ! self::_get_option('cronjob_enable') ) {
1190
+ self::_add_scheduled_hook();
1191
+ } else if ( ! $options['cronjob_enable'] && self::_get_option('cronjob_enable') ) {
1192
+ self::clear_scheduled_hook();
1193
+ }
1194
+
1195
+ /* Optionen speichern */
1196
+ self::_update_options($options); ?>
1197
+
1198
+ <div id="message" class="updated fade">
1199
+ <p>
1200
+ <strong>
1201
+ <?php _e('Settings saved.') ?>
1202
+ </strong>
1203
+ </p>
1204
+ </div>
1205
+ <?php } ?>
1206
+
1207
+ <div class="wrap" id="av_main">
1208
+ <h2>
1209
+ AntiVirus
1210
+ </h2>
1211
+
1212
+ <table class="form-table">
1213
+ <tr valign="top">
1214
+ <th scope="row">
1215
+ <?php esc_html_e('Manual malware scan', 'antivirus') ?>
1216
+ </th>
1217
+ <td>
1218
+ <div class="inside" id="av_manual_scan">
1219
+ <p>
1220
+ <a href="#" class="button button-primary">
1221
+ <?php esc_html_e('Scan the theme templates now', 'antivirus') ?>
1222
+ </a>
1223
+ <span class="alert"></span>
1224
+ </p>
1225
+ <div class="output"></div>
1226
+ </div>
1227
+ </td>
1228
+ </tr>
1229
+ </table>
1230
+
1231
+
1232
+ <form method="post" action="">
1233
+ <?php wp_nonce_field('antivirus') ?>
1234
+
1235
+ <table class="form-table">
1236
+ <tr valign="top">
1237
+ <th scope="row">
1238
+ <?php esc_html_e('Daily malware scan', 'antivirus') ?>
1239
+ </th>
1240
+ <td>
1241
+ <fieldset>
1242
+ <label for="av_cronjob_enable">
1243
+ <input type="checkbox" name="av_cronjob_enable" id="av_cronjob_enable" value="1" <?php checked(self::_get_option('cronjob_enable'), 1) ?> />
1244
+ <?php esc_html_e('Check the theme templates for malware', 'antivirus') ?>
1245
+ </label>
1246
+
1247
+ <p class="description">
1248
+ <?php if ( $timestamp = wp_next_scheduled('antivirus_daily_cronjob') ) {
1249
+ echo sprintf(
1250
+ '%s: %s',
1251
+ esc_html__('Next Run', 'antivirus'),
1252
+ date_i18n('d.m.Y H:i:s', $timestamp + get_option('gmt_offset') * 3600)
1253
+ );
1254
+ } ?>
1255
+ </p>
1256
+
1257
+
1258
+ <br />
1259
+
1260
+
1261
+ <label for="av_safe_browsing">
1262
+ <input type="checkbox" name="av_safe_browsing" id="av_safe_browsing" value="1" <?php checked(self::_get_option('safe_browsing'), 1) ?> />
1263
+ <?php esc_html_e('Malware detection by Google Safe Browsing', 'antivirus') ?>
1264
+ </label>
1265
+
1266
+ <p class="description">
1267
+ <?php esc_html_e('Diagnosis and notification in suspicion case', 'antivirus') ?>
1268
+ </p>
1269
+
1270
+
1271
+ <br />
1272
+
1273
+
1274
+ <label for="av_notify_email">
1275
+ <input type="text" name="av_notify_email" id="av_notify_email" value="<?php esc_attr_e(self::_get_option('notify_email')) ?>" class="regular-text" placeholder="<?php esc_attr_e('Email address for notifications', 'antivirus') ?>" />
1276
+ </label>
1277
+
1278
+ <p class="description">
1279
+ <?php esc_html_e('If the field is empty, the blog admin will be notified', 'antivirus') ?>
1280
+ </p>
1281
+ </fieldset>
1282
+ </td>
1283
+ </tr>
1284
+
1285
+ <tr valign="top">
1286
+ <th scope="row">
1287
+ <input type="submit" class="button button-primary" value="<?php _e('Save Changes') ?>" />
1288
+ </th>
1289
+ <td>
1290
+ <?php if ( substr( get_locale(), 0, 3 ) === 'de_' ) { ?><a href="https://github.com/pluginkollektiv/antivirus/wiki" target="_blank">Handbuch</a> &bull; <?php } ?><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=LG5VC9KXMAYXJ" target="_blank">PayPal</a>
1291
+ </td>
1292
+ </tr>
1293
+ </table>
1294
+ </form>
1295
+ </div>
1296
+ <?php }
1297
+ }
1298
+
1299
+
1300
+ /* Fire */
1301
+ add_action(
1302
+ 'plugins_loaded',
1303
+ array(
1304
+ 'AntiVirus',
1305
+ 'instance'
1306
+ ),
1307
+ 99
1308
+ );
1309
+
1310
+
1311
+ /* Hooks */
1312
+ register_activation_hook(
1313
+ __FILE__,
1314
+ array(
1315
+ 'AntiVirus',
1316
+ 'install'
1317
+ )
1318
+ );
1319
+ register_deactivation_hook(
1320
+ __FILE__,
1321
+ array(
1322
+ 'AntiVirus',
1323
+ 'deactivation'
1324
+ )
1325
+ );
1326
+ register_uninstall_hook(
1327
+ __FILE__,
1328
+ array(
1329
+ 'AntiVirus',
1330
+ 'uninstall'
1331
+ )
1332
+ );
 
 
 
 
 
 
 
 
 
 
 
css/style.css CHANGED
@@ -1,94 +1,94 @@
1
- /* @group Manual Scan */
2
-
3
- #av_manual_scan {
4
- height: 1%;
5
- overflow: hidden;
6
- }
7
- #av_manual_scan a.button {
8
- float: left;
9
- }
10
- #av_manual_scan .alert {
11
- float: left;
12
- color: green;
13
- margin: 0 10px;
14
- border: 1px solid green;
15
- display: none;
16
- height: 26px;
17
- line-height: 26px;
18
- padding: 0 10px;
19
- background: #fff;
20
- border-radius: 3px;
21
- }
22
-
23
- #av_main .inside .output {
24
- clear: both;
25
- height: 1%;
26
- margin: 0 0 0 -6px;
27
- padding: 0 0 6px;
28
- overflow: hidden;
29
- }
30
- #av_main .inside .output div {
31
- float: left;
32
- color: #FFF;
33
- margin: 12px 6px 0;
34
- padding: 8px 12px 10px;
35
- background: orange;
36
- border-radius: 3px;
37
-
38
- transition: background-color 0.5s linear;
39
- -o-transition: background-color 0.5s linear;
40
- -ms-transition: background-color 0.5s linear;
41
- -moz-transition: background-color 0.5s linear;
42
- -webkit-transition: background-color 0.5s linear;
43
- }
44
- #av_main .inside .output div.done {
45
- background: green;
46
- }
47
- #av_main .inside .output div.danger {
48
- width: 97%;
49
- background: red;
50
- }
51
- #av_main .inside .output div p {
52
- padding: 10px;
53
- overflow: hidden;
54
- background: #F9F9F9;
55
- white-space: nowrap;
56
- border-radius: 3px;
57
- }
58
- #av_main .inside .output div p a {
59
- float: left;
60
- color: #646464;
61
- margin: 0 6px 12px 0;
62
- display: block;
63
- border: 1px solid #bbbbbb;
64
- padding: 2px 5px;
65
- background: #f2f2f2;
66
- text-decoration: none;
67
- border-radius: 3px;
68
- }
69
- #av_main .inside .output div p a:hover {
70
- color: #000;
71
- border: 1px solid #646464;
72
- }
73
- #av_main .inside .output div p code {
74
- clear: both;
75
- float: left;
76
- color: #000;
77
- padding: 2px 5px;
78
- border-radius: 3px;
79
- }
80
- #av_main .inside .output div p code span {
81
- padding: 2px;
82
- background: yellow;
83
- }
84
-
85
- /* @end group */
86
-
87
-
88
- /* @group WordPress 3.8 Fix */
89
-
90
- #av_notify_email {
91
- line-height: 1.5;
92
- }
93
-
94
  /* @end group */
1
+ /* @group Manual Scan */
2
+
3
+ #av_manual_scan {
4
+ height: 1%;
5
+ overflow: hidden;
6
+ }
7
+ #av_manual_scan a.button {
8
+ float: left;
9
+ }
10
+ #av_manual_scan .alert {
11
+ float: left;
12
+ color: green;
13
+ margin: 0 10px;
14
+ border: 1px solid green;
15
+ display: none;
16
+ height: 26px;
17
+ line-height: 26px;
18
+ padding: 0 10px;
19
+ background: #fff;
20
+ border-radius: 3px;
21
+ }
22
+
23
+ #av_main .inside .output {
24
+ clear: both;
25
+ height: 1%;
26
+ margin: 0 0 0 -6px;
27
+ padding: 0 0 6px;
28
+ overflow: hidden;
29
+ }
30
+ #av_main .inside .output div {
31
+ float: left;
32
+ color: #FFF;
33
+ margin: 12px 6px 0;
34
+ padding: 8px 12px 10px;
35
+ background: orange;
36
+ border-radius: 3px;
37
+
38
+ transition: background-color 0.5s linear;
39
+ -o-transition: background-color 0.5s linear;
40
+ -ms-transition: background-color 0.5s linear;
41
+ -moz-transition: background-color 0.5s linear;
42
+ -webkit-transition: background-color 0.5s linear;
43
+ }
44
+ #av_main .inside .output div.done {
45
+ background: green;
46
+ }
47
+ #av_main .inside .output div.danger {
48
+ width: 97%;
49
+ background: red;
50
+ }
51
+ #av_main .inside .output div p {
52
+ padding: 10px;
53
+ overflow: hidden;
54
+ background: #F9F9F9;
55
+ white-space: nowrap;
56
+ border-radius: 3px;
57
+ }
58
+ #av_main .inside .output div p a {
59
+ float: left;
60
+ color: #646464;
61
+ margin: 0 6px 12px 0;
62
+ display: block;
63
+ border: 1px solid #b4b9be;
64
+ padding: 2px 5px;
65
+ background: #f2f2f2;
66
+ text-decoration: none;
67
+ border-radius: 3px;
68
+ }
69
+ #av_main .inside .output div p a:hover {
70
+ color: #000;
71
+ border: 1px solid #646464;
72
+ }
73
+ #av_main .inside .output div p code {
74
+ clear: both;
75
+ float: left;
76
+ color: #000;
77
+ padding: 2px 5px;
78
+ border-radius: 3px;
79
+ }
80
+ #av_main .inside .output div p code span {
81
+ padding: 2px;
82
+ background: yellow;
83
+ }
84
+
85
+ /* @end group */
86
+
87
+
88
+ /* @group WordPress 3.8 Fix */
89
+
90
+ #av_notify_email {
91
+ line-height: 1.5;
92
+ }
93
+
94
  /* @end group */
css/style.min.css CHANGED
@@ -1 +1 @@
1
- #av_manual_scan{height:1%;overflow:hidden;}#av_manual_scan a.button{float:left;}#av_manual_scan .alert{float:left;color:green;margin:0 10px;border:1px solid green;display:none;height:26px;line-height:26px;padding:0 10px;background:#fff;border-radius:3px;}#av_main .inside .output{clear:both;height:1%;margin:0 0 0 -6px;padding:0 0 6px;overflow:hidden;}#av_main .inside .output div{float:left;color:#FFF;margin:12px 6px 0;padding:8px 12px 10px;background:orange;border-radius:3px;transition:background-color 0.5s linear;-o-transition:background-color 0.5s linear;-ms-transition:background-color 0.5s linear;-moz-transition:background-color 0.5s linear;-webkit-transition:background-color 0.5s linear;}#av_main .inside .output div.done{background:green;}#av_main .inside .output div.danger{width:97%;background:red;}#av_main .inside .output div p{padding:10px;overflow:hidden;background:#f9f9f9;white-space:nowrap;border-radius:3px;}#av_main .inside .output div p a{float:left;color:#646464;margin:0 6px 12px 0;display:block;border:1px solid #bbb;padding:2px 5px;background:#f2f2f2;text-decoration:none;border-radius:3px;}#av_main .inside .output div p a:hover{color:#000;border:1px solid #646464;}#av_main .inside .output div p code{clear:both;float:left;color:#000;padding:2px 5px;border-radius:3px;}#av_main .inside .output div p code span{padding:2px;background:yellow;}#av_notify_email{line-height:1.5;}
1
+ #av_manual_scan{height:1%;overflow:hidden;}#av_manual_scan a.button{float:left;}#av_manual_scan .alert{float:left;color:green;margin:0 10px;border:1px solid green;display:none;height:26px;line-height:26px;padding:0 10px;background:#fff;border-radius:3px;}#av_main .inside .output{clear:both;height:1%;margin:0 0 0 -6px;padding:0 0 6px;overflow:hidden;}#av_main .inside .output div{float:left;color:#FFF;margin:12px 6px 0;padding:8px 12px 10px;background:orange;border-radius:3px;transition:background-color 0.5s linear;-o-transition:background-color 0.5s linear;-ms-transition:background-color 0.5s linear;-moz-transition:background-color 0.5s linear;-webkit-transition:background-color 0.5s linear;}#av_main .inside .output div.done{background:green;}#av_main .inside .output div.danger{width:97%;background:red;}#av_main .inside .output div p{padding:10px;overflow:hidden;background:#f9f9f9;white-space:nowrap;border-radius:3px;}#av_main .inside .output div p a{float:left;color:#646464;margin:0 6px 12px 0;display:block;border:1px solid #b4b9be;padding:2px 5px;background:#f2f2f2;text-decoration:none;border-radius:3px;}#av_main .inside .output div p a:hover{color:#000;border:1px solid #646464;}#av_main .inside .output div p code{clear:both;float:left;color:#000;padding:2px 5px;border-radius:3px;}#av_main .inside .output div p code span{padding:2px;background:yellow;}#av_notify_email{line-height:1.5;}
js/script.js CHANGED
@@ -1,189 +1,180 @@
1
- jQuery(document).ready(
2
- function($) {
3
- /* Init */
4
- av_nonce = av_settings.nonce;
5
- av_theme = av_settings.theme;
6
- av_msg_1 = av_settings.msg_1;
7
- av_msg_2 = av_settings.msg_2;
8
- av_msg_3 = av_settings.msg_3;
9
-
10
- /* Einzelne Datei prüfen */
11
- function check_theme_file(current) {
12
- /* ID umwandeln */
13
- var id = parseInt(current || 0);
14
-
15
- /* File ermitteln */
16
- var file = av_files[id];
17
-
18
- /* Request starten */
19
- $.post(
20
- ajaxurl,
21
- {
22
- 'action': 'get_ajax_response',
23
- '_ajax_nonce': av_nonce,
24
- '_theme_file': file,
25
- '_action_request': 'check_theme_file'
26
- },
27
- function(input) {
28
- /* Wert initialisieren */
29
- var item = $('#av_template_' + id);
30
-
31
- /* Daten vorhanden? */
32
- if ( input ) {
33
- /* Input konvertieren */
34
- input = eval('(' + input + ')');
35
-
36
- /* Sicherheitscheck */
37
- if ( !input.nonce || input.nonce != av_nonce ) {
38
- return;
39
- }
40
-
41
- /* Farblich anpassen */
42
- item.addClass('danger');
43
-
44
- /* Init */
45
- var i,
46
- lines = input.data,
47
- len = lines.length;
48
-
49
- /* Zeilen loopen */
50
- for (i = 0; i < len; i = i + 3) {
51
- var num = parseInt(lines[i]) + 1,
52
- md5 = lines[i + 2],
53
- line = lines[i + 1].replace(/@span@/g, '<span>').replace(/@\/span@/g, '</span>'),
54
- file = item.text();
55
-
56
- item.append('<p><a href="#" id="' + md5 + '">' + av_msg_1 + '</a> <code>' + line + '</code></p>');
57
-
58
- $('#' + md5).click(
59
- function() {
60
- $.post(
61
- ajaxurl,
62
- {
63
- 'action': 'get_ajax_response',
64
- '_ajax_nonce': av_nonce,
65
- '_file_md5': $(this).attr('id'),
66
- '_action_request': 'update_white_list'
67
- },
68
- function(input) {
69
- /* Keine Daten? */
70
- if (!input) {
71
- return;
72
- }
73
-
74
- /* Input konvertieren */
75
- input = eval('(' + input + ')');
76
-
77
- /* Sicherheitscheck */
78
- if (!input.nonce || input.nonce != av_nonce) {
79
- return;
80
- }
81
-
82
- var parent = $('#' + input.data[0]).parent();
83
-
84
- if (parent.parent().children().length <= 1) {
85
- parent.parent().hide('slow').remove();
86
- }
87
- parent.hide('slow').remove();
88
- }
89
- );
90
-
91
- return false;
92
- }
93
- );
94
- }
95
- } else {
96
- item.addClass('done');
97
- }
98
-
99
- /* Counter erhöhen */
100
- av_files_loaded ++;
101
-
102
- /* Hinweis ausgeben */
103
- if ( av_files_loaded >= av_files_total ) {
104
- $('#av_manual_scan .alert').text(av_msg_3).fadeIn().fadeOut().fadeIn().fadeOut().fadeIn().animate({opacity: 1.0}, 500).fadeOut(
105
- 'slow',
106
- function() {
107
- $(this).empty();
108
- }
109
- );
110
- } else {
111
- check_theme_file(id + 1);
112
- }
113
- }
114
- );
115
- }
116
-
117
- /* Tempates Check */
118
- $('#av_manual_scan a.button').click(
119
- function() {
120
- /* Request */
121
- $.post(
122
- ajaxurl,
123
- {
124
- action: 'get_ajax_response',
125
- _ajax_nonce: av_nonce,
126
- _action_request: 'get_theme_files'
127
- },
128
- function(input) {
129
- /* Keine Daten? */
130
- if ( !input ) {
131
- return;
132
- }
133
-
134
- /* Input konvertieren */
135
- input = eval('(' + input + ')');
136
-
137
- /* Sicherheitscheck */
138
- if ( !input.nonce || input.nonce != av_nonce ) {
139
- return;
140
- }
141
-
142
- /* Wert initialisieren */
143
- var output = '';
144
-
145
- /* Globale Werte */
146
- av_files = input.data;
147
- av_files_total = av_files.length;
148
- av_files_loaded = 0;
149
-
150
- /* Files visualisieren */
151
- jQuery.each(
152
- av_files,
153
- function(i, val) {
154
- output += '<div id="av_template_' + i + '">' + val + '</div>';
155
- }
156
- );
157
-
158
- /* Werte zuweisen */
159
- $('#av_manual_scan .alert').empty();
160
- $('#av_manual_scan .output').empty().append(output);
161
-
162
- /* Files loopen */
163
- check_theme_file();
164
- }
165
- );
166
-
167
- return false;
168
- }
169
- );
170
-
171
- /* Checkboxen markieren */
172
- function manage_options() {
173
- var $$ = $('#av_cronjob_enable'),
174
- input = $$.parents('fieldset').find(':text, :checkbox').not($$);
175
-
176
- if ( typeof $.fn.prop === 'function' ) {
177
- input.prop('disabled', !$$.prop('checked'));
178
- } else {
179
- input.attr('disabled', !$$.attr('checked'));
180
- }
181
- }
182
-
183
- /* Checkbox überwachen */
184
- $('#av_cronjob_enable').click(manage_options);
185
-
186
- /* Fire! */
187
- manage_options();
188
- }
189
  );
1
+ jQuery(document).ready(
2
+ function($) {
3
+ /* Init */
4
+ av_nonce = av_settings.nonce;
5
+ av_theme = av_settings.theme;
6
+ av_msg_1 = av_settings.msg_1;
7
+ av_msg_2 = av_settings.msg_2;
8
+ av_msg_3 = av_settings.msg_3;
9
+
10
+ /* Einzelne Datei prüfen */
11
+ function check_theme_file(current) {
12
+ /* ID umwandeln */
13
+ var id = parseInt(current || 0);
14
+
15
+ /* File ermitteln */
16
+ var file = av_files[id];
17
+
18
+ /* Request starten */
19
+ $.post(
20
+ ajaxurl,
21
+ {
22
+ 'action': 'get_ajax_response',
23
+ '_ajax_nonce': av_nonce,
24
+ '_theme_file': file,
25
+ '_action_request': 'check_theme_file'
26
+ },
27
+ function(input) {
28
+ /* Wert initialisieren */
29
+ var item = $('#av_template_' + id);
30
+
31
+ /* Daten vorhanden? */
32
+ if ( input ) {
33
+ /* Sicherheitscheck */
34
+ if ( !input.nonce || input.nonce != av_nonce ) {
35
+ return;
36
+ }
37
+
38
+ /* Farblich anpassen */
39
+ item.addClass('danger');
40
+
41
+ /* Init */
42
+ var i,
43
+ lines = input.data,
44
+ len = lines.length;
45
+
46
+ /* Zeilen loopen */
47
+ for (i = 0; i < len; i = i + 3) {
48
+ var num = parseInt(lines[i]) + 1,
49
+ md5 = lines[i + 2],
50
+ line = lines[i + 1].replace(/@span@/g, '<span>').replace(/@\/span@/g, '</span>'),
51
+ file = item.text();
52
+
53
+ item.append('<p><a href="#" id="' + md5 + '">' + av_msg_1 + '</a> <code>' + line + '</code></p>');
54
+
55
+ $('#' + md5).click(
56
+ function() {
57
+ $.post(
58
+ ajaxurl,
59
+ {
60
+ 'action': 'get_ajax_response',
61
+ '_ajax_nonce': av_nonce,
62
+ '_file_md5': $(this).attr('id'),
63
+ '_action_request': 'update_white_list'
64
+ },
65
+ function(input) {
66
+ /* Keine Daten? */
67
+ if (!input) {
68
+ return;
69
+ }
70
+
71
+ /* Sicherheitscheck */
72
+ if (!input.nonce || input.nonce != av_nonce) {
73
+ return;
74
+ }
75
+
76
+ var parent = $('#' + input.data[0]).parent();
77
+
78
+ if (parent.parent().children().length <= 1) {
79
+ parent.parent().hide('slow').remove();
80
+ }
81
+ parent.hide('slow').remove();
82
+ }
83
+ );
84
+
85
+ return false;
86
+ }
87
+ );
88
+ }
89
+ } else {
90
+ item.addClass('done');
91
+ }
92
+
93
+ /* Counter erhöhen */
94
+ av_files_loaded ++;
95
+
96
+ /* Hinweis ausgeben */
97
+ if ( av_files_loaded >= av_files_total ) {
98
+ $('#av_manual_scan .alert').text(av_msg_3).fadeIn().fadeOut().fadeIn().fadeOut().fadeIn().animate({opacity: 1.0}, 500).fadeOut(
99
+ 'slow',
100
+ function() {
101
+ $(this).empty();
102
+ }
103
+ );
104
+ } else {
105
+ check_theme_file(id + 1);
106
+ }
107
+ }
108
+ );
109
+ }
110
+
111
+ /* Tempates Check */
112
+ $('#av_manual_scan a.button').click(
113
+ function() {
114
+ /* Request */
115
+ $.post(
116
+ ajaxurl,
117
+ {
118
+ action: 'get_ajax_response',
119
+ _ajax_nonce: av_nonce,
120
+ _action_request: 'get_theme_files'
121
+ },
122
+ function(input) {
123
+ /* Keine Daten? */
124
+ if ( !input ) {
125
+ return;
126
+ }
127
+
128
+ /* Sicherheitscheck */
129
+ if ( !input.nonce || input.nonce != av_nonce ) {
130
+ return;
131
+ }
132
+
133
+ /* Wert initialisieren */
134
+ var output = '';
135
+
136
+ /* Globale Werte */
137
+ av_files = input.data;
138
+ av_files_total = av_files.length;
139
+ av_files_loaded = 0;
140
+
141
+ /* Files visualisieren */
142
+ jQuery.each(
143
+ av_files,
144
+ function(i, val) {
145
+ output += '<div id="av_template_' + i + '">' + val + '</div>';
146
+ }
147
+ );
148
+
149
+ /* Werte zuweisen */
150
+ $('#av_manual_scan .alert').empty();
151
+ $('#av_manual_scan .output').empty().append(output);
152
+
153
+ /* Files loopen */
154
+ check_theme_file();
155
+ }
156
+ );
157
+
158
+ return false;
159
+ }
160
+ );
161
+
162
+ /* Checkboxen markieren */
163
+ function manage_options() {
164
+ var $$ = $('#av_cronjob_enable'),
165
+ input = $$.parents('fieldset').find(':text, :checkbox').not($$);
166
+
167
+ if ( typeof $.fn.prop === 'function' ) {
168
+ input.prop('disabled', !$$.prop('checked'));
169
+ } else {
170
+ input.attr('disabled', !$$.attr('checked'));
171
+ }
172
+ }
173
+
174
+ /* Checkbox überwachen */
175
+ $('#av_cronjob_enable').click(manage_options);
176
+
177
+ /* Fire! */
178
+ manage_options();
179
+ }
 
 
 
 
 
 
 
 
 
180
  );
js/script.min.js CHANGED
@@ -1,4 +1,4 @@
1
- jQuery(document).ready(function(b){function g(a){var d=parseInt(a||0);b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,_theme_file:av_files[d],_action_request:"check_theme_file"},function(c){var a=b("#av_template_"+d);if(c){c=eval("("+c+")");if(!c.nonce||c.nonce!=av_nonce)return;a.addClass("danger");var e=c.data,f=e.length;for(c=0;c<f;c+=3){parseInt(e[c]);var h=e[c+2],k=e[c+1].replace(/@span@/g,"<span>").replace(/@\/span@/g,"</span>");a.text();a.append('<p><a href="#" id="'+h+'">'+
2
- av_msg_1+"</a> <code>"+k+"</code></p>");b("#"+h).click(function(){b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,_file_md5:b(this).attr("id"),_action_request:"update_white_list"},function(a){a&&(a=eval("("+a+")"),a.nonce&&a.nonce==av_nonce&&(a=b("#"+a.data[0]).parent(),1>=a.parent().children().length&&a.parent().hide("slow").remove(),a.hide("slow").remove()))});return!1})}}else a.addClass("done");av_files_loaded++;av_files_loaded>=av_files_total?b("#av_manual_scan .alert").text(av_msg_3).fadeIn().fadeOut().fadeIn().fadeOut().fadeIn().animate({opacity:1},
3
- 500).fadeOut("slow",function(){b(this).empty()}):g(d+1)})}function f(){var a=b("#av_cronjob_enable"),d=a.parents("fieldset").find(":text, :checkbox").not(a);"function"===typeof b.fn.prop?d.prop("disabled",!a.prop("checked")):d.attr("disabled",!a.attr("checked"))}av_nonce=av_settings.nonce;av_theme=av_settings.theme;av_msg_1=av_settings.msg_1;av_msg_2=av_settings.msg_2;av_msg_3=av_settings.msg_3;b("#av_manual_scan a.button").click(function(){b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,
4
- _action_request:"get_theme_files"},function(a){if(a&&(a=eval("("+a+")"),a.nonce&&a.nonce==av_nonce)){var d="";av_files=a.data;av_files_total=av_files.length;av_files_loaded=0;jQuery.each(av_files,function(a,b){d+='<div id="av_template_'+a+'">'+b+"</div>"});b("#av_manual_scan .alert").empty();b("#av_manual_scan .output").empty().append(d);g()}});return!1});b("#av_cronjob_enable").click(f);f()});
1
+ jQuery(document).ready(function(b){function g(a){var d=parseInt(a||0);b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,_theme_file:av_files[d],_action_request:"check_theme_file"},function(c){var a=b("#av_template_"+d);if(c){if(!c.nonce||c.nonce!=av_nonce)return;a.addClass("danger");var e=c.data,f=e.length;for(c=0;c<f;c+=3){parseInt(e[c]);var h=e[c+2],k=e[c+1].replace(/@span@/g,"<span>").replace(/@\/span@/g,"</span>");a.text();a.append('<p><a href="#" id="'+h+'">'+av_msg_1+"</a> <code>"+
2
+ k+"</code></p>");b("#"+h).click(function(){b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,_file_md5:b(this).attr("id"),_action_request:"update_white_list"},function(a){a&&a.nonce&&a.nonce==av_nonce&&(a=b("#"+a.data[0]).parent(),1>=a.parent().children().length&&a.parent().hide("slow").remove(),a.hide("slow").remove())});return!1})}}else a.addClass("done");av_files_loaded++;av_files_loaded>=av_files_total?b("#av_manual_scan .alert").text(av_msg_3).fadeIn().fadeOut().fadeIn().fadeOut().fadeIn().animate({opacity:1},
3
+ 500).fadeOut("slow",function(){b(this).empty()}):g(d+1)})}function f(){var a=b("#av_cronjob_enable"),d=a.parents("fieldset").find(":text, :checkbox").not(a);"function"===typeof b.fn.prop?d.prop("disabled",!a.prop("checked")):d.attr("disabled",!a.attr("checked"))}av_nonce=av_settings.nonce;av_theme=av_settings.theme;av_msg_1=av_settings.msg_1;av_msg_2=av_settings.msg_2;av_msg_3=av_settings.msg_3;b("#av_manual_scan a.button").click(function(){b.post(ajaxurl,{action:"get_ajax_response",_ajax_nonce:av_nonce,
4
+ _action_request:"get_theme_files"},function(a){if(a&&a.nonce&&a.nonce==av_nonce){var d="";av_files=a.data;av_files_total=av_files.length;av_files_loaded=0;jQuery.each(av_files,function(a,b){d+='<div id="av_template_'+a+'">'+b+"</div>"});b("#av_manual_scan .alert").empty();b("#av_manual_scan .output").empty().append(d);g()}});return!1});b("#av_cronjob_enable").click(f);f()});
lang/antivirus-de_DE.mo CHANGED
Binary file
lang/antivirus-de_DE.po CHANGED
@@ -1,77 +1,112 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: AntiVirus\n"
4
- "POT-Creation-Date: \n"
5
- "PO-Revision-Date: \n"
6
- "Last-Translator: Sergej Müller\n"
7
- "Language-Team: Sergej Müller\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=utf-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "X-Poedit-Language: German\n"
12
- "X-Poedit-Country: GERMANY\n"
13
- "X-Poedit-SourceCharset: utf-8\n"
14
- "X-Poedit-KeywordsList: __;_e\n"
15
- "X-Poedit-Basepath: .\n"
16
- "X-Poedit-SearchPath-0: .\n"
17
-
18
- msgid "Virus suspected"
19
- msgstr "Virusverdacht"
20
-
21
- msgid "AntiVirus for WordPress"
22
- msgstr "AntiVirus für WordPress"
23
-
24
- msgid "View line"
25
- msgstr "Zeige Zeile"
26
-
27
- msgid "There is no virus"
28
- msgstr "Als 'Kein Virus' markieren"
29
-
30
- msgid "Scan finished"
31
- msgstr "Prüfung abgeschlossen"
32
-
33
- msgid "Daily malware scan"
34
- msgstr "Tägliche Prüfung"
35
-
36
- msgid "Check the theme templates for malware"
37
- msgstr "Überprüfung der Theme-Templates auf Malware"
38
-
39
- msgid "Next Run"
40
- msgstr "Nächste Ausführung"
41
-
42
- msgid "Malware detection by Google Safe Browsing"
43
- msgstr "Malware-Erkennung durch Google Safe Browsing"
44
-
45
- msgid "Diagnosis and notification in suspicion case"
46
- msgstr "Diagnose und Benachrichtigung im Verdachtsfall"
47
-
48
- msgid "Email address for notifications"
49
- msgstr "E-Mail-Adresse für Benachrichtigungen"
50
-
51
- msgid "If the field is empty, the blog admin will be notified"
52
- msgstr "Bleibt das Eingabefeld leer, wird der Admin benachrichtigt"
53
-
54
- msgid "Manual malware scan"
55
- msgstr "Manuelle Prüfung"
56
-
57
- msgid "Scan the theme templates now"
58
- msgstr "Theme-Templates jetzt prüfen"
59
-
60
- msgid "The daily antivirus scan of your blog suggests alarm."
61
- msgstr "Die tägliche AntiVirus-Prüfung des Blogs schlägt Alarm."
62
-
63
- msgid "Security solution as a smart, effectively plugin to protect your blog against exploits and spam injections."
64
- msgstr "Kostenfreie Sicherheitslösung als Plugin zur Früherkennung und Warnung vor bösartigen Injektionen in Theme-Templates."
65
-
66
- msgid "Notify message by AntiVirus for WordPress"
67
- msgstr "Benachrichtigung von AntiVirus für WordPress"
68
-
69
- msgid "http://wpantivirus.com"
70
- msgstr "http://wpantivirus.de"
71
-
72
- msgid "Safe Browsing Alert"
73
- msgstr "Safe Browsing Alarm"
74
-
75
- msgid "Please check the Google Safe Browsing diagnostic page:"
76
- msgstr "Für weitere Details die Google Safe Browsing Diagnoseseite aufsuchen:"
77
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AntiVirus\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: 2015-08-18 14:35+0100\n"
7
+ "Last-Translator: Caspar Huebinger <caspar@glueckpress.com>\n"
8
+ "Language-Team: Sergej Müller\n"
9
+ "Language: de\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=utf-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
16
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;"
17
+ "__ngettext_noop:1,2;_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;"
18
+ "_nx_js:1,2,3c;esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;"
19
+ "esc_attr_x:1,2c;esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;"
20
+ "transChoice:1,2\n"
21
+ "X-Poedit-Basepath: .\n"
22
+ "X-Loco-Target-Locale: de_DE\n"
23
+ "X-Generator: Poedit 1.8\n"
24
+ "X-Poedit-SearchPath-0: .\n"
25
+
26
+ #: ../antivirus.php:447
27
+ msgid "Safe Browsing Alert"
28
+ msgstr "Safe Browsing Alarm"
29
+
30
+ #: ../antivirus.php:450
31
+ msgid "Please check the Google Safe Browsing diagnostic page:"
32
+ msgstr "Für weitere Details die Google Safe Browsing Diagnoseseite aufsuchen:"
33
+
34
+ #: ../antivirus.php:474 ../antivirus.php:1149
35
+ msgid "Virus suspected"
36
+ msgstr "Virusverdacht"
37
+
38
+ #: ../antivirus.php:477 ../antivirus.php:1150
39
+ msgid "The daily antivirus scan of your blog suggests alarm."
40
+ msgstr "Die tägliche AntiVirus-Prüfung des Blogs schlägt Alarm."
41
+
42
+ #: ../antivirus.php:521
43
+ msgid "Notify message by AntiVirus for WordPress"
44
+ msgstr "Benachrichtigung von AntiVirus für WordPress"
45
+
46
+ #: ../antivirus.php:522
47
+ msgid "http://wpantivirus.com"
48
+ msgstr "http://wpantivirus.de"
49
+
50
+ #: ../antivirus.php:596
51
+ msgid "There is no virus"
52
+ msgstr "Nicht erneut hinweisen"
53
+
54
+ #: ../antivirus.php:597
55
+ msgid "View line"
56
+ msgstr "Zeige Zeile"
57
+
58
+ #: ../antivirus.php:598
59
+ msgid "Scan finished"
60
+ msgstr "Prüfung abgeschlossen"
61
+
62
+ #: ../antivirus.php:1157 ../antivirus.php:1215
63
+ msgid "Manual malware scan"
64
+ msgstr "Manuelle Prüfung"
65
+
66
+ #: ../antivirus.php:1221
67
+ msgid "Scan the theme templates now"
68
+ msgstr "Theme-Templates jetzt prüfen"
69
+
70
+ #: ../antivirus.php:1238
71
+ msgid "Daily malware scan"
72
+ msgstr "Tägliche Prüfung"
73
+
74
+ #: ../antivirus.php:1244
75
+ msgid "Check the theme templates for malware"
76
+ msgstr "Überprüfung der Theme-Templates auf Malware"
77
+
78
+ #: ../antivirus.php:1251
79
+ msgid "Next Run"
80
+ msgstr "Nächste Ausführung"
81
+
82
+ #: ../antivirus.php:1263
83
+ msgid "Malware detection by Google Safe Browsing"
84
+ msgstr "Malware-Erkennung durch Google Safe Browsing"
85
+
86
+ #: ../antivirus.php:1267
87
+ msgid "Diagnosis and notification in suspicion case"
88
+ msgstr "Diagnose und Benachrichtigung im Verdachtsfall"
89
+
90
+ #: ../antivirus.php:1275
91
+ msgid "Email address for notifications"
92
+ msgstr "E-Mail-Adresse für Benachrichtigungen"
93
+
94
+ #: ../antivirus.php:1279
95
+ msgid "If the field is empty, the blog admin will be notified"
96
+ msgstr "Bleibt das Eingabefeld leer, wird der Admin benachrichtigt"
97
+
98
+ msgid ""
99
+ "Security plugin to protect your blog or website against exploits and spam "
100
+ "injections."
101
+ msgstr ""
102
+ "Kostenfreie Sicherheitslösung als Plugin zur Früherkennung und Warnung vor "
103
+ "bösartigen Injektionen."
104
+
105
+ msgid "pluginkollektiv"
106
+ msgstr "pluginkollektiv"
107
+
108
+ msgid "http://pluginkollektiv.org"
109
+ msgstr "http://pluginkollektiv.org"
110
+
111
+ msgid "https://wordpress.org/plugins/antivirus/"
112
+ msgstr "https://wordpress.org/plugins/antivirus/"
lang/antivirus-de_DE_formal.mo ADDED
Binary file
lang/antivirus-de_DE_formal.po ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AntiVirus\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: \n"
7
+ "Last-Translator: Caspar Huebinger <caspar@glueckpress.com>\n"
8
+ "Language-Team: pluginkollektiv\n"
9
+ "Language: de_DE\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=utf-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Poedit-SourceCharset: utf-8\n"
14
+ "X-Poedit-KeywordsList: __;_e\n"
15
+ "X-Poedit-Basepath: .\n"
16
+ "X-Generator: Poedit 1.8\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: ../antivirus.php:447
20
+ msgid "Safe Browsing Alert"
21
+ msgstr "Safe Browsing Alarm"
22
+
23
+ #: ../antivirus.php:450
24
+ msgid "Please check the Google Safe Browsing diagnostic page:"
25
+ msgstr "Für weitere Details die Google Safe Browsing Diagnoseseite aufsuchen:"
26
+
27
+ #: ../antivirus.php:474 ../antivirus.php:1149
28
+ msgid "Virus suspected"
29
+ msgstr "Virusverdacht"
30
+
31
+ #: ../antivirus.php:477 ../antivirus.php:1150
32
+ msgid "The daily antivirus scan of your blog suggests alarm."
33
+ msgstr "Die tägliche AntiVirus-Prüfung des Blogs schlägt Alarm."
34
+
35
+ #: ../antivirus.php:521
36
+ msgid "Notify message by AntiVirus for WordPress"
37
+ msgstr "Benachrichtigung von AntiVirus für WordPress"
38
+
39
+ #: ../antivirus.php:522
40
+ msgid "http://wpantivirus.com"
41
+ msgstr "http://wpantivirus.de"
42
+
43
+ #: ../antivirus.php:596
44
+ msgid "There is no virus"
45
+ msgstr "Nicht erneut hinweisen"
46
+
47
+ #: ../antivirus.php:597
48
+ msgid "View line"
49
+ msgstr "Zeige Zeile"
50
+
51
+ #: ../antivirus.php:598
52
+ msgid "Scan finished"
53
+ msgstr "Prüfung abgeschlossen"
54
+
55
+ #: ../antivirus.php:1157 ../antivirus.php:1215
56
+ msgid "Manual malware scan"
57
+ msgstr "Manuelle Prüfung"
58
+
59
+ #: ../antivirus.php:1221
60
+ msgid "Scan the theme templates now"
61
+ msgstr "Theme-Templates jetzt prüfen"
62
+
63
+ #: ../antivirus.php:1238
64
+ msgid "Daily malware scan"
65
+ msgstr "Tägliche Prüfung"
66
+
67
+ #: ../antivirus.php:1244
68
+ msgid "Check the theme templates for malware"
69
+ msgstr "Überprüfung der Theme-Templates auf Malware"
70
+
71
+ #: ../antivirus.php:1251
72
+ msgid "Next Run"
73
+ msgstr "Nächste Ausführung"
74
+
75
+ #: ../antivirus.php:1263
76
+ msgid "Malware detection by Google Safe Browsing"
77
+ msgstr "Malware-Erkennung durch Google Safe Browsing"
78
+
79
+ #: ../antivirus.php:1267
80
+ msgid "Diagnosis and notification in suspicion case"
81
+ msgstr "Diagnose und Benachrichtigung im Verdachtsfall"
82
+
83
+ #: ../antivirus.php:1275
84
+ msgid "Email address for notifications"
85
+ msgstr "E-Mail-Adresse für Benachrichtigungen"
86
+
87
+ #: ../antivirus.php:1279
88
+ msgid "If the field is empty, the blog admin will be notified"
89
+ msgstr "Bleibt das Eingabefeld leer, wird der Admin benachrichtigt"
90
+
91
+ msgid ""
92
+ "Security plugin to protect your blog or website against exploits and spam "
93
+ "injections."
94
+ msgstr ""
95
+ "Kostenfreie Sicherheitslösung als Plugin zur Früherkennung und Warnung vor "
96
+ "bösartigen Injektionen."
97
+
98
+ msgid "pluginkollektiv"
99
+ msgstr "pluginkollektiv"
100
+
101
+ msgid "http://pluginkollektiv.org"
102
+ msgstr "http://pluginkollektiv.org"
103
+
104
+ msgid "https://wordpress.org/plugins/antivirus/"
105
+ msgstr "https://wordpress.org/plugins/antivirus/"
lang/antivirus-es_ES.po CHANGED
@@ -1,162 +1,162 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: AntiVirus v1.3.5\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: \n"
6
- "PO-Revision-Date: 2014-03-08 22:21:17+0000\n"
7
- "Last-Translator: Pablo Laguna <laguna.sanchez@gmail.com>\n"
8
- "Language-Team: \n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
13
- "X-Generator: CSL v1.x\n"
14
- "X-Poedit-Language: Spanish\n"
15
- "X-Poedit-Country: SPAIN\n"
16
- "X-Poedit-SourceCharset: utf-8\n"
17
- "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
18
- "X-Poedit-Basepath: ../\n"
19
- "X-Poedit-Bookmarks: \n"
20
- "X-Poedit-SearchPath-0: .\n"
21
- "X-Textdomain-Support: yes"
22
-
23
- #. translators: plugin header field 'Name'
24
- #: antivirus.php:0
25
- #@ antivirus
26
- msgid "AntiVirus"
27
- msgstr "AntiVirus"
28
-
29
- #. translators: plugin header field 'PluginURI'
30
- #: antivirus.php:0
31
- #: antivirus.php:505
32
- #@ antivirus
33
- msgid "http://wpantivirus.com"
34
- msgstr "http://wpantivirus.com"
35
-
36
- #. translators: plugin header field 'Description'
37
- #: antivirus.php:0
38
- #@ antivirus
39
- msgid "Security solution as a smart, effectively plugin to protect your blog against exploits and spam injections."
40
- msgstr "Solución de seguridad en un sencillo y efectivo plugin para proteger tu blog de agujeros e infecciones."
41
-
42
- #. translators: plugin header field 'Author'
43
- #: antivirus.php:0
44
- #@ antivirus
45
- msgid "Sergej M&uuml;ller"
46
- msgstr "Sergej M&uuml;ller"
47
-
48
- #. translators: plugin header field 'AuthorURI'
49
- #: antivirus.php:0
50
- #@ antivirus
51
- msgid "http://wpcoder.de"
52
- msgstr "http://wpcoder.de"
53
-
54
- #. translators: plugin header field 'Version'
55
- #: antivirus.php:0
56
- #@ antivirus
57
- msgid "1.3.5"
58
- msgstr "1.3.5"
59
-
60
- #: antivirus.php:182
61
- #@ default
62
- msgid "Settings"
63
- msgstr "Opciones"
64
-
65
- #: antivirus.php:431
66
- #@ antivirus
67
- msgid "Safe Browsing Alert"
68
- msgstr "Alerta de Safe Browsing"
69
-
70
- #: antivirus.php:434
71
- #@ antivirus
72
- msgid "Please check the Google Safe Browsing diagnostic page:"
73
- msgstr "Por favor, revisa la página de diagnóstico de Google Safe Browsing:"
74
-
75
- #: antivirus.php:458
76
- #: antivirus.php:1125
77
- #@ antivirus
78
- msgid "Virus suspected"
79
- msgstr "Sospecha de virus"
80
-
81
- #: antivirus.php:461
82
- #: antivirus.php:1126
83
- #@ antivirus
84
- msgid "The daily antivirus scan of your blog suggests alarm."
85
- msgstr "El análisis antivirus diario de tu blog ha dado una alarma."
86
-
87
- #: antivirus.php:504
88
- #@ antivirus
89
- msgid "Notify message by AntiVirus for WordPress"
90
- msgstr "Mensaje de notificación de AntiVirus para WordPress"
91
-
92
- #: antivirus.php:579
93
- #@ antivirus
94
- msgid "There is no virus"
95
- msgstr "No hay virus"
96
-
97
- #: antivirus.php:580
98
- #@ antivirus
99
- msgid "View line"
100
- msgstr "Ver línea"
101
-
102
- #: antivirus.php:581
103
- #@ antivirus
104
- msgid "Scan finished"
105
- msgstr "Escaneo finalizado"
106
-
107
- #: antivirus.php:1133
108
- #: antivirus.php:1191
109
- #@ antivirus
110
- msgid "Manual malware scan"
111
- msgstr "Escaneo manual de software malicioso"
112
-
113
- #: antivirus.php:1177
114
- #@ default
115
- msgid "Settings saved."
116
- msgstr "Opciones guardadas."
117
-
118
- #: antivirus.php:1197
119
- #@ antivirus
120
- msgid "Scan the theme templates now"
121
- msgstr "Escanear los ficheros del tema ahora"
122
-
123
- #: antivirus.php:1214
124
- #@ antivirus
125
- msgid "Daily malware scan"
126
- msgstr "Escaneo diario de software malicioso"
127
-
128
- #: antivirus.php:1220
129
- #@ antivirus
130
- msgid "Check the theme templates for malware"
131
- msgstr "Revisar los ficheros del tema en busca de software malicioso"
132
-
133
- #: antivirus.php:1227
134
- #@ antivirus
135
- msgid "Next Run"
136
- msgstr "Próxima ejecución"
137
-
138
- #: antivirus.php:1239
139
- #@ antivirus
140
- msgid "Malware detection by Google Safe Browsing"
141
- msgstr "Detección de software malicioso por Google Safe Browsing"
142
-
143
- #: antivirus.php:1243
144
- #@ antivirus
145
- msgid "Diagnosis and notification in suspicion case"
146
- msgstr "Diagnóstico y notificación en caso de sospecha"
147
-
148
- #: antivirus.php:1251
149
- #@ antivirus
150
- msgid "Email address for notifications"
151
- msgstr "Dirección electrónica para notificaciones"
152
-
153
- #: antivirus.php:1255
154
- #@ antivirus
155
- msgid "If the field is empty, the blog admin will be notified"
156
- msgstr "Si el campo está vacío, se enviarán las notificaciones al administrador del sitio"
157
-
158
- #: antivirus.php:1263
159
- #@ default
160
- msgid "Save Changes"
161
- msgstr "Guardar cambios"
162
-
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: AntiVirus v1.3.5\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: 2014-03-08 22:21:17+0000\n"
7
+ "Last-Translator: Pablo Laguna <laguna.sanchez@gmail.com>\n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
13
+ "X-Generator: CSL v1.x\n"
14
+ "X-Poedit-Language: Spanish\n"
15
+ "X-Poedit-Country: SPAIN\n"
16
+ "X-Poedit-SourceCharset: utf-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
18
+ "X-Poedit-Basepath: ../\n"
19
+ "X-Poedit-Bookmarks: \n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+ "X-Textdomain-Support: yes"
22
+
23
+ #. translators: plugin header field 'Name'
24
+ #: antivirus.php:0
25
+ #@ antivirus
26
+ msgid "AntiVirus"
27
+ msgstr "AntiVirus"
28
+
29
+ #. translators: plugin header field 'PluginURI'
30
+ #: antivirus.php:0
31
+ #: antivirus.php:505
32
+ #@ antivirus
33
+ msgid "http://wpantivirus.com"
34
+ msgstr "http://wpantivirus.com"
35
+
36
+ #. translators: plugin header field 'Description'
37
+ #: antivirus.php:0
38
+ #@ antivirus
39
+ msgid "Security solution as a smart, effectively plugin to protect your blog against exploits and spam injections."
40
+ msgstr "Solución de seguridad en un sencillo y efectivo plugin para proteger tu blog de agujeros e infecciones."
41
+
42
+ #. translators: plugin header field 'Author'
43
+ #: antivirus.php:0
44
+ #@ antivirus
45
+ msgid "Sergej M&uuml;ller"
46
+ msgstr "Sergej M&uuml;ller"
47
+
48
+ #. translators: plugin header field 'AuthorURI'
49
+ #: antivirus.php:0
50
+ #@ antivirus
51
+ msgid "http://wpcoder.de"
52
+ msgstr "http://wpcoder.de"
53
+
54
+ #. translators: plugin header field 'Version'
55
+ #: antivirus.php:0
56
+ #@ antivirus
57
+ msgid "1.3.5"
58
+ msgstr "1.3.5"
59
+
60
+ #: antivirus.php:182
61
+ #@ default
62
+ msgid "Settings"
63
+ msgstr "Opciones"
64
+
65
+ #: antivirus.php:431
66
+ #@ antivirus
67
+ msgid "Safe Browsing Alert"
68
+ msgstr "Alerta de Safe Browsing"
69
+
70
+ #: antivirus.php:434
71
+ #@ antivirus
72
+ msgid "Please check the Google Safe Browsing diagnostic page:"
73
+ msgstr "Por favor, revisa la página de diagnóstico de Google Safe Browsing:"
74
+
75
+ #: antivirus.php:458
76
+ #: antivirus.php:1125
77
+ #@ antivirus
78
+ msgid "Virus suspected"
79
+ msgstr "Sospecha de virus"
80
+
81
+ #: antivirus.php:461
82
+ #: antivirus.php:1126
83
+ #@ antivirus
84
+ msgid "The daily antivirus scan of your blog suggests alarm."
85
+ msgstr "El análisis antivirus diario de tu blog ha dado una alarma."
86
+
87
+ #: antivirus.php:504
88
+ #@ antivirus
89
+ msgid "Notify message by AntiVirus for WordPress"
90
+ msgstr "Mensaje de notificación de AntiVirus para WordPress"
91
+
92
+ #: antivirus.php:579
93
+ #@ antivirus
94
+ msgid "There is no virus"
95
+ msgstr "No hay virus"
96
+
97
+ #: antivirus.php:580
98
+ #@ antivirus
99
+ msgid "View line"
100
+ msgstr "Ver línea"
101
+
102
+ #: antivirus.php:581
103
+ #@ antivirus
104
+ msgid "Scan finished"
105
+ msgstr "Escaneo finalizado"
106
+
107
+ #: antivirus.php:1133
108
+ #: antivirus.php:1191
109
+ #@ antivirus
110
+ msgid "Manual malware scan"
111
+ msgstr "Escaneo manual de software malicioso"
112
+
113
+ #: antivirus.php:1177
114
+ #@ default
115
+ msgid "Settings saved."
116
+ msgstr "Opciones guardadas."
117
+
118
+ #: antivirus.php:1197
119
+ #@ antivirus
120
+ msgid "Scan the theme templates now"
121
+ msgstr "Escanear los ficheros del tema ahora"
122
+
123
+ #: antivirus.php:1214
124
+ #@ antivirus
125
+ msgid "Daily malware scan"
126
+ msgstr "Escaneo diario de software malicioso"
127
+
128
+ #: antivirus.php:1220
129
+ #@ antivirus
130
+ msgid "Check the theme templates for malware"
131
+ msgstr "Revisar los ficheros del tema en busca de software malicioso"
132
+
133
+ #: antivirus.php:1227
134
+ #@ antivirus
135
+ msgid "Next Run"
136
+ msgstr "Próxima ejecución"
137
+
138
+ #: antivirus.php:1239
139
+ #@ antivirus
140
+ msgid "Malware detection by Google Safe Browsing"
141
+ msgstr "Detección de software malicioso por Google Safe Browsing"
142
+
143
+ #: antivirus.php:1243
144
+ #@ antivirus
145
+ msgid "Diagnosis and notification in suspicion case"
146
+ msgstr "Diagnóstico y notificación en caso de sospecha"
147
+
148
+ #: antivirus.php:1251
149
+ #@ antivirus
150
+ msgid "Email address for notifications"
151
+ msgstr "Dirección electrónica para notificaciones"
152
+
153
+ #: antivirus.php:1255
154
+ #@ antivirus
155
+ msgid "If the field is empty, the blog admin will be notified"
156
+ msgstr "Si el campo está vacío, se enviarán las notificaciones al administrador del sitio"
157
+
158
+ #: antivirus.php:1263
159
+ #@ default
160
+ msgid "Save Changes"
161
+ msgstr "Guardar cambios"
162
+
lang/antivirus.pot ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Loco Gettext template
2
+ #, fuzzy
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: AntiVirus\n"
6
+ "Report-Msgid-Bugs-To: \n"
7
+ "POT-Creation-Date: \n"
8
+ "POT-Revision-Date: Tue Aug 18 2015 14:02:12 GMT+0200 (CEST)\n"
9
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
10
+ "Last-Translator: Torsten Landsiedel <torsten.landsiedel@gmx.de>\n"
11
+ "Language-Team: pluginkollektiv\n"
12
+ "Language: \n"
13
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=utf-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Poedit-SourceCharset: utf-8\n"
18
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
19
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
20
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
21
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
22
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
23
+ "X-Poedit-Basepath: .\n"
24
+ "X-Generator: Loco - https://localise.biz/\n"
25
+ "X-Poedit-SearchPath-0: ."
26
+
27
+ #: ../antivirus.php:447
28
+ msgid "Safe Browsing Alert"
29
+ msgstr ""
30
+
31
+ #: ../antivirus.php:450
32
+ msgid "Please check the Google Safe Browsing diagnostic page:"
33
+ msgstr ""
34
+
35
+ #: ../antivirus.php:474 ../antivirus.php:1149
36
+ msgid "Virus suspected"
37
+ msgstr ""
38
+
39
+ #: ../antivirus.php:477 ../antivirus.php:1150
40
+ msgid "The daily antivirus scan of your blog suggests alarm."
41
+ msgstr ""
42
+
43
+ #: ../antivirus.php:521
44
+ msgid "Notify message by AntiVirus for WordPress"
45
+ msgstr ""
46
+
47
+ #: ../antivirus.php:522
48
+ msgid "http://wpantivirus.com"
49
+ msgstr ""
50
+
51
+ #: ../antivirus.php:596
52
+ msgid "There is no virus"
53
+ msgstr ""
54
+
55
+ #: ../antivirus.php:597
56
+ msgid "View line"
57
+ msgstr ""
58
+
59
+ #: ../antivirus.php:598
60
+ msgid "Scan finished"
61
+ msgstr ""
62
+
63
+ #: ../antivirus.php:1157 ../antivirus.php:1215
64
+ msgid "Manual malware scan"
65
+ msgstr ""
66
+
67
+ #: ../antivirus.php:1221
68
+ msgid "Scan the theme templates now"
69
+ msgstr ""
70
+
71
+ #: ../antivirus.php:1238
72
+ msgid "Daily malware scan"
73
+ msgstr ""
74
+
75
+ #: ../antivirus.php:1244
76
+ msgid "Check the theme templates for malware"
77
+ msgstr ""
78
+
79
+ #: ../antivirus.php:1251
80
+ msgid "Next Run"
81
+ msgstr ""
82
+
83
+ #: ../antivirus.php:1263
84
+ msgid "Malware detection by Google Safe Browsing"
85
+ msgstr ""
86
+
87
+ #: ../antivirus.php:1267
88
+ msgid "Diagnosis and notification in suspicion case"
89
+ msgstr ""
90
+
91
+ #: ../antivirus.php:1275
92
+ msgid "Email address for notifications"
93
+ msgstr ""
94
+
95
+ #: ../antivirus.php:1279
96
+ msgid "If the field is empty, the blog admin will be notified"
97
+ msgstr ""
98
+
99
+ msgid ""
100
+ "Security plugin to protect your blog or website against exploits and spam "
101
+ "injections."
102
+ msgstr ""
103
+
104
+ msgid "pluginkollektiv"
105
+ msgstr ""
106
+
107
+ msgid "http://pluginkollektiv.org"
108
+ msgstr ""
109
+
110
+ msgid "https://wordpress.org/plugins/antivirus/"
111
+ msgstr ""