AntiVirus - Version 1.3.1

Version Description

  • Compatibility with WordPress 3.4
  • High-resolution plugin icon for retina displays
  • Remove icon from the admin sidebar
  • System requirements: From PHP 5.0 to PHP 5.1
Download this release

Release Info

Developer sergej.mueller
Plugin Icon 128x128 AntiVirus
Version 1.3.1
Comparing to
See all releases

Code changes from version 1.2 to 1.3.1

antivirus.original.php DELETED
@@ -1,1259 +0,0 @@
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://wpseo.de
9
- Plugin URI: http://wpantivirus.com
10
- Version: 1.2
11
- */
12
-
13
-
14
- /* Sicherheitsabfrage */
15
- if ( !class_exists('WP') ) {
16
- header('Status: 403 Forbidden');
17
- header('HTTP/1.1 403 Forbidden');
18
- exit();
19
- }
20
-
21
-
22
- /**
23
- * AntiVirus
24
- *
25
- * @since 0.1
26
- */
27
-
28
- class AntiVirus {
29
-
30
-
31
- /* Save me! */
32
- private static $base;
33
-
34
-
35
- /**
36
- * Konstruktor der Klasse
37
- *
38
- * @since 0.1
39
- * @change 1.2
40
- */
41
-
42
- public static function init()
43
- {
44
- /* AUTOSAVE */
45
- if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) or (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
46
- return;
47
- }
48
-
49
- /* Plugin-Base */
50
- self::$base = plugin_basename(__FILE__);
51
-
52
- /* Cronjob */
53
- if ( defined('DOING_CRON') ) {
54
- add_action(
55
- 'antivirus_daily_cronjob',
56
- array(
57
- __CLASS__,
58
- 'exe_daily_cronjob'
59
- )
60
- );
61
-
62
- /* Admin */
63
- } elseif ( is_admin() ) {
64
- /* AJAX */
65
- if ( defined('DOING_AJAX') ) {
66
- add_action(
67
- 'wp_ajax_get_ajax_response',
68
- array(
69
- __CLASS__,
70
- 'get_ajax_response'
71
- )
72
- );
73
-
74
- /* Backend */
75
- } else {
76
- /* Actions */
77
- add_action(
78
- 'init',
79
- array(
80
- __CLASS__,
81
- 'load_plugin_lang'
82
- )
83
- );
84
- add_action(
85
- 'admin_menu',
86
- array(
87
- __CLASS__,
88
- 'add_sidebar_menu'
89
- )
90
- );
91
- add_action(
92
- 'admin_bar_menu',
93
- array(
94
- __CLASS__,
95
- 'add_adminbar_menu'
96
- ),
97
- 91
98
- );
99
- add_action(
100
- 'admin_notices',
101
- array(
102
- __CLASS__,
103
- 'show_dashboard_notice'
104
- )
105
- );
106
- add_action(
107
- 'admin_print_styles',
108
- array(
109
- __CLASS__,
110
- 'add_enqueue_style'
111
- )
112
- );
113
-
114
- /* GUI */
115
- if ( self::is_current_page('home') ) {
116
- add_action(
117
- 'admin_print_scripts',
118
- array(
119
- __CLASS__,
120
- 'add_enqueue_script'
121
- )
122
- );
123
-
124
- /* Plugins */
125
- } else if ( self::is_current_page('plugins') ) {
126
- add_action(
127
- 'deactivate_' .self::$base,
128
- array(
129
- __CLASS__,
130
- 'clear_scheduled_hook'
131
- )
132
- );
133
- add_filter(
134
- 'plugin_row_meta',
135
- array(
136
- __CLASS__,
137
- 'init_row_meta'
138
- ),
139
- 10,
140
- 2
141
- );
142
- add_filter(
143
- 'plugin_action_links_' .self::$base,
144
- array(
145
- __CLASS__,
146
- 'init_action_links'
147
- )
148
- );
149
- }
150
- }
151
- }
152
- }
153
-
154
-
155
- /**
156
- * Einbindung der Sprache
157
- *
158
- * @since 0.8
159
- * @change 0.8
160
- */
161
-
162
- public static function load_plugin_lang()
163
- {
164
- load_plugin_textdomain(
165
- 'antivirus',
166
- false,
167
- 'antivirus/lang'
168
- );
169
- }
170
-
171
-
172
- /**
173
- * Hinzufügen der Action-Links (Einstellungen links)
174
- *
175
- * @since 1.1
176
- * @change 1.1
177
- */
178
-
179
- public static function init_action_links($data)
180
- {
181
- /* Rechte? */
182
- if ( !current_user_can('manage_options') ) {
183
- return $data;
184
- }
185
-
186
- return array_merge(
187
- $data,
188
- array(
189
- sprintf(
190
- '<a href="%s">%s</a>',
191
- add_query_arg(
192
- array(
193
- 'page' => 'antivirus'
194
- ),
195
- admin_url('options-general.php')
196
- ),
197
- __('Settings')
198
- )
199
- )
200
- );
201
- }
202
-
203
-
204
- /**
205
- * Links in der Plugins-Verwaltung
206
- *
207
- * @since 0.1
208
- * @change 1.1
209
- *
210
- * @param array $links Array mit Links
211
- * @param string $file Name des Plugins
212
- * @return array $links Array mit erweitertem Link
213
- */
214
-
215
- public static function init_row_meta($data, $page)
216
- {
217
- if ( $page == self::$base ) {
218
- $data = array_merge(
219
- $data,
220
- array(
221
- sprintf(
222
- '<a href="https://flattr.com/thing/58179/Sicherheit-in-WordPress-Das-erste-AntiVirus-Plugin-fur-WordPress" target="_blank">%s</a>',
223
- esc_html__('Flattr plugin', 'antivirus')
224
- ),
225
- sprintf(
226
- '<a href="https://plus.google.com/110569673423509816572" target="_blank">%s</a>',
227
- esc_html__('Follow on Google+', 'antivirus')
228
- )
229
- )
230
- );
231
- }
232
-
233
- return $data;
234
- }
235
-
236
-
237
- /**
238
- * Aktion bei Aktivierung des Plugins
239
- *
240
- * @since 0.1
241
- * @change 0.8
242
- */
243
-
244
- public static function install()
245
- {
246
- /* Option anlegen */
247
- add_option(
248
- 'antivirus',
249
- array(),
250
- '',
251
- 'no'
252
- );
253
-
254
- /* Cron aktivieren */
255
- if ( self::get_option('cronjob_enable') ) {
256
- self::init_scheduled_hook();
257
- }
258
- }
259
-
260
-
261
- /**
262
- * Uninstallation des Plugins pro MU-Blog
263
- *
264
- * @since 1.1
265
- * @change 1.1
266
- */
267
-
268
- public static function uninstall()
269
- {
270
- /* Global */
271
- global $wpdb;
272
-
273
- /* Remove settings */
274
- delete_option('antivirus');
275
-
276
- /* Clean DB */
277
- $wpdb->query("OPTIMIZE TABLE `" .$wpdb->options. "`");
278
- }
279
-
280
-
281
- /**
282
- * Rückgabe eines Optionsfeldes
283
- *
284
- * @since 0.1
285
- * @change 0.8
286
- *
287
- * @param string $field Name des Feldes
288
- * @return mixed Wert des Feldes
289
- */
290
-
291
- private static function get_option($field)
292
- {
293
- if ( !$options = wp_cache_get('antivirus') ) {
294
- $options = get_option('antivirus');
295
- wp_cache_set(
296
- 'antivirus',
297
- $options
298
- );
299
- }
300
-
301
- return @$options[$field];
302
- }
303
-
304
-
305
- /**
306
- * Aktualisiert ein Optionsfeld
307
- *
308
- * @since 0.1
309
- * @change 0.8
310
- *
311
- * @param string $field Name des Feldes
312
- * @param mixed Wert des Feldes
313
- */
314
-
315
- private static function update_option($field, $value)
316
- {
317
- self::update_options(
318
- array(
319
- $field => $value
320
- )
321
- );
322
- }
323
-
324
-
325
- /**
326
- * Aktualisiert mehrere Optionsfelder
327
- *
328
- * @since 0.1
329
- * @change 0.8
330
- *
331
- * @param array $data Array mit Feldern
332
- */
333
-
334
- private static function update_options($data)
335
- {
336
- /* Option zuweisen */
337
- $options = array_merge(
338
- (array)get_option('antivirus'),
339
- $data
340
- );
341
-
342
- /* DB updaten */
343
- update_option(
344
- 'antivirus',
345
- $options
346
- );
347
-
348
- /* Cache updaten */
349
- wp_cache_set(
350
- 'antivirus',
351
- $options
352
- );
353
- }
354
-
355
-
356
- /**
357
- * Initialisierung des Cronjobs
358
- *
359
- * @since 0.1
360
- * @change 0.8
361
- */
362
-
363
- private static function init_scheduled_hook()
364
- {
365
- if ( !wp_next_scheduled('antivirus_daily_cronjob') ) {
366
- wp_schedule_event(
367
- time(),
368
- 'daily',
369
- 'antivirus_daily_cronjob'
370
- );
371
- }
372
- }
373
-
374
-
375
- /**
376
- * Beendigung des Cronjobs
377
- *
378
- * @since 0.1
379
- * @change 0.8
380
- */
381
-
382
- public static function clear_scheduled_hook()
383
- {
384
- if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
385
- wp_clear_scheduled_hook('antivirus_daily_cronjob');
386
- }
387
- }
388
-
389
-
390
- /**
391
- * Ausführung des Cronjobs
392
- *
393
- * @since 0.1
394
- * @change 1.0
395
- */
396
-
397
- public static function exe_daily_cronjob()
398
- {
399
- /* Kein Cronjob? */
400
- if ( !self::get_option('cronjob_enable') ) {
401
- return;
402
- }
403
-
404
- /* Timestamp updaten */
405
- self::update_option(
406
- 'cronjob_timestamp',
407
- time()
408
- );
409
-
410
- /* Files prüfen */
411
- if ( self::check_theme_files() or self::check_permalink_structure() ) {
412
- /* Sprache laden */
413
- self::load_plugin_lang();
414
-
415
- /* E-Mail-Adresse */
416
- $email = sanitize_email(self::get_option('notify_email'));
417
- $email = ( (!empty($email) && is_email($email)) ? $email : get_bloginfo('admin_email') );
418
-
419
- /* Send it! */
420
- wp_mail(
421
- $email,
422
- sprintf(
423
- '[%s] %s',
424
- get_bloginfo('name'),
425
- esc_html__('Virus suspected', 'antivirus')
426
- ),
427
- sprintf(
428
- "%s\r\n%s\r\n\r\n\r\n%s\r\n%s\r\n",
429
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
430
- get_bloginfo('url'),
431
- esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
432
- esc_html__('http://wpantivirus.com', 'antivirus')
433
- )
434
- );
435
-
436
- /* Alert speichern */
437
- self::update_option(
438
- 'cronjob_alert',
439
- 1
440
- );
441
- }
442
- }
443
-
444
-
445
- /**
446
- * Initialisierung der GUI
447
- *
448
- * @since 0.1
449
- * @change 1.2
450
- */
451
-
452
- public static function add_sidebar_menu()
453
- {
454
- /* Menü anlegen */
455
- add_options_page(
456
- 'AntiVirus',
457
- '<span id="av_sidebar_icon"></span>AntiVirus',
458
- 'manage_options',
459
- 'antivirus',
460
- array(
461
- __CLASS__,
462
- 'show_admin_menu'
463
- )
464
- );
465
- }
466
-
467
-
468
- /**
469
- * Initialisierung von JavaScript
470
- *
471
- * @since 0.8
472
- * @change 1.1
473
- */
474
-
475
- public static function add_enqueue_script()
476
- {
477
- /* Infos auslesen */
478
- $data = get_plugin_data(__FILE__);
479
-
480
- /* JS einbinden */
481
- wp_register_script(
482
- 'av_script',
483
- plugins_url('js/script.js', __FILE__),
484
- array('jquery'),
485
- $data['Version']
486
- );
487
-
488
- /* Script einbinden */
489
- wp_enqueue_script('av_script');
490
-
491
- /* Script lokalisieren */
492
- wp_localize_script(
493
- 'av_script',
494
- 'av_settings',
495
- array(
496
- 'nonce' => wp_create_nonce('av_ajax_nonce'),
497
- 'ajax' => admin_url('admin-ajax.php'),
498
- 'theme' => urlencode(self::get_theme_name()),
499
- 'msg_1' => esc_html__('There is no virus', 'antivirus'),
500
- 'msg_2' => esc_html__('View line', 'antivirus'),
501
- 'msg_3' => esc_html__('Scan finished', 'antivirus')
502
- )
503
- );
504
- }
505
-
506
-
507
- /**
508
- * Initialisierung von Stylesheets
509
- *
510
- * @since 0.8
511
- * @change 1.1
512
- */
513
-
514
- public static function add_enqueue_style()
515
- {
516
- /* Infos auslesen */
517
- $data = get_plugin_data(__FILE__);
518
-
519
- /* CSS registrieren */
520
- wp_register_style(
521
- 'av_css',
522
- plugins_url('css/style.css', __FILE__),
523
- array(),
524
- $data['Version']
525
- );
526
-
527
- /* CSS einbinden */
528
- wp_enqueue_style('av_css');
529
- }
530
-
531
-
532
- /**
533
- * Rückgabe des aktuellen Theme
534
- *
535
- * @since 0.1
536
- * @change 0.8
537
- *
538
- * @return array $themes Array mit Theme-Eigenschaften
539
- */
540
-
541
- private static function get_current_theme()
542
- {
543
- /* Themes auslesen */
544
- if ( $themes = get_themes() ) {
545
- /* Aktuelles Theme */
546
- if ($theme = get_current_theme()) {
547
- if (array_key_exists((string)$theme, $themes)) {
548
- return $themes[$theme];
549
- }
550
- }
551
- }
552
-
553
- return false;
554
- }
555
-
556
-
557
- /**
558
- * Rückgabe von Dateien des aktuellen Theme
559
- *
560
- * @since 0.1
561
- * @change 0.8
562
- *
563
- * @return array $files Array mit Dateien
564
- */
565
-
566
- private static function get_theme_files()
567
- {
568
- /* Theme vorhanden? */
569
- if ( !$theme = self::get_current_theme() ) {
570
- return false;
571
- }
572
-
573
- /* Keine Files? */
574
- if ( empty($theme['Template Files']) ) {
575
- return false;
576
- }
577
-
578
- /* Zurückgeben */
579
- return array_unique(
580
- array_map(
581
- create_function(
582
- '$v',
583
- 'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
584
- ),
585
- $theme['Template Files']
586
- )
587
- );
588
- }
589
-
590
-
591
- /**
592
- * Rückgabe des Namen des aktuellen Theme
593
- *
594
- * @since 0.1
595
- * @change 0.8
596
- *
597
- * @return string $theme Name des aktuellen Theme
598
- */
599
-
600
- private static function get_theme_name()
601
- {
602
- if ( $theme = self::get_current_theme() ) {
603
- if (!empty($theme['Name'])) {
604
- return $theme['Name'];
605
- }
606
- }
607
-
608
- return false;
609
- }
610
-
611
-
612
- /**
613
- * Rückgabe der WhiteList
614
- *
615
- * @since 0.1
616
- * @change 0.8
617
- *
618
- * @return array return Array mit MD5-Werten
619
- */
620
-
621
- private static function get_white_list()
622
- {
623
- return explode(
624
- ':',
625
- self::get_option('white_list')
626
- );
627
- }
628
-
629
-
630
- /**
631
- * Ausführung von AJAX
632
- *
633
- * @since 0.1
634
- * @change 0.8
635
- */
636
-
637
- public static function get_ajax_response()
638
- {
639
- /* Referer prüfen */
640
- check_ajax_referer('av_ajax_nonce');
641
-
642
- /* Zusätzliche Prüfung */
643
- if ( empty($_POST['_action_request']) ) {
644
- exit();
645
- }
646
-
647
- /* Init */
648
- $values = array();
649
- $output = '';
650
-
651
- /* Ausgabe starten */
652
- switch ($_POST['_action_request']) {
653
- case 'get_theme_files':
654
- self::update_option(
655
- 'cronjob_alert',
656
- 0
657
- );
658
-
659
- $values = self::get_theme_files();
660
- break;
661
-
662
- case 'check_theme_file':
663
- if ( !empty($_POST['_theme_file']) && $lines = self::check_theme_file($_POST['_theme_file']) ) {
664
- foreach ($lines as $num => $line) {
665
- foreach ($line as $string) {
666
- $values[] = $num;
667
- $values[] = htmlentities($string, ENT_QUOTES);
668
- $values[] = md5($num . $string);
669
- }
670
- }
671
- }
672
- break;
673
-
674
- case 'update_white_list':
675
- if ( !empty($_POST['_file_md5']) ) {
676
- self::update_option(
677
- 'white_list',
678
- implode(
679
- ':',
680
- array_unique(
681
- array_merge(
682
- self::get_white_list(),
683
- array($_POST['_file_md5'])
684
- )
685
- )
686
- )
687
- );
688
-
689
- $values = array($_POST['_file_md5']);
690
- }
691
- break;
692
-
693
- default:
694
- break;
695
- }
696
-
697
- /* Ausgabe starten */
698
- if ($values) {
699
- $output = sprintf(
700
- "['%s']",
701
- implode("', '", $values)
702
- );
703
-
704
- /* Header senden */
705
- header('Content-Type: plain/text');
706
-
707
- /* Ausgeben */
708
- echo sprintf(
709
- '{data:%s, nonce:"%s"}',
710
- $output,
711
- $_POST['_ajax_nonce']
712
- );
713
- }
714
-
715
- /* Raus! */
716
- exit();
717
- }
718
-
719
-
720
- /**
721
- * Rückgabe des Dateiinhaltes
722
- *
723
- * @since 0.1
724
- * @change 0.8
725
- *
726
- * @return array $file Array mit Dateizeilen
727
- */
728
-
729
- private static function get_file_content($file)
730
- {
731
- return file(WP_CONTENT_DIR . $file);
732
- }
733
-
734
-
735
- /**
736
- * Kürzung eines Strings
737
- *
738
- * @since 0.1
739
- * @change 0.1
740
- *
741
- * @param string $line Eigenetliche Zeile als String
742
- * @param string $tag Gesuchtes Tag
743
- * @param integer $max Anzahl der Zeichen rechts und links
744
- * @return string $output Gekürzter String
745
- */
746
-
747
- public static function get_dotted_line($line, $tag, $max = 100)
748
- {
749
- /* Keine Werte? */
750
- if ( !$line or !$tag ) {
751
- return false;
752
- }
753
-
754
- /* Differenz ermitteln */
755
- if ( strlen($tag) > $max ) {
756
- return $tag;
757
- }
758
-
759
- /* Differenz ermitteln */
760
- $left = round(($max - strlen($tag)) / 2);
761
-
762
- /* Wert konvertieren */
763
- $tag = preg_quote($tag);
764
-
765
- /* String kürzen */
766
- $output = preg_replace(
767
- '/(' .$tag. ')(.{' .$left. '}).{0,}$/',
768
- '$1$2 ...',
769
- $line
770
- );
771
- $output = preg_replace(
772
- '/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
773
- '... $1$2',
774
- $output
775
- );
776
-
777
- return $output;
778
- }
779
-
780
-
781
- /**
782
- * Definition des Regexp
783
- *
784
- * @since 0.1
785
- * @change 1.2
786
- *
787
- * @return string return Regulärer Ausdruck
788
- */
789
-
790
- private static function get_preg_match()
791
- {
792
- 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|include|include_once|require|require_once|file_put_contents|iframe)\s*?\(/';
793
- }
794
-
795
-
796
- /**
797
- * Prüfung einer Zeile
798
- *
799
- * @since 0.1
800
- * @change 1.1
801
- *
802
- * @param string $line Zeile zur Prüfung
803
- * @param integer $num Nummer zur Prüfung
804
- * @return string $line Zeile mit Resultaten
805
- */
806
-
807
- private static function check_file_line($line = '', $num)
808
- {
809
- /* Wert trimmen */
810
- $line = trim((string)$line);
811
-
812
- /* Leere Werte? */
813
- if ( !$line or !isset($num) ) {
814
- return false;
815
- }
816
-
817
- /* Werte initialisieren */
818
- $results = array();
819
- $output = array();
820
-
821
- /* Befehle suchen */
822
- preg_match_all(
823
- self::get_preg_match(),
824
- $line,
825
- $matches
826
- );
827
-
828
- /* Ergebnis speichern */
829
- if ( $matches[1] ) {
830
- $results = $matches[1];
831
- }
832
-
833
- /* Base64 suchen */
834
- preg_match_all(
835
- '/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/',
836
- $line,
837
- $matches
838
- );
839
-
840
- /* Ergebnis speichern */
841
- if ( $matches[1] ) {
842
- $results = array_merge($results, $matches[1]);
843
- }
844
-
845
- /* Frames suchen */
846
- preg_match_all(
847
- '/<\s*?(frame)/',
848
- $line,
849
- $matches
850
- );
851
-
852
- /* Ergebnis speichern */
853
- if ( $matches[1] ) {
854
- $results = array_merge($results, $matches[1]);
855
- }
856
-
857
- /* Option suchen */
858
- preg_match(
859
- '/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
860
- $line,
861
- $matches
862
- );
863
-
864
- /* Option prüfen */
865
- if ( $matches && $matches[1] && self::check_file_line(get_option($matches[1]), $num) ) {
866
- array_push($results, 'get_option');
867
- }
868
-
869
- /* Ergebnisse? */
870
- if ( $results ) {
871
- /* Keine Duplikate */
872
- $results = array_unique($results);
873
-
874
- /* White-Liste */
875
- $md5 = self::get_white_list();
876
-
877
- /* Resultate loopen */
878
- foreach ($results as $tag) {
879
- $string = str_replace(
880
- $tag,
881
- '@span@' .$tag. '@/span@',
882
- self::get_dotted_line($line, $tag)
883
- );
884
-
885
- /* In der Whitelist? */
886
- if (!in_array(md5($num . $string), $md5)) {
887
- $output[] = $string;
888
- }
889
- }
890
-
891
- return $output;
892
- }
893
-
894
- return false;
895
- }
896
-
897
-
898
- /**
899
- * Prüfung der Dateien des aktuellen Theme
900
- *
901
- * @since 0.1
902
- * @change 0.8
903
- *
904
- * @return array $results Array mit Ergebnissen
905
- */
906
-
907
- private static function check_theme_files()
908
- {
909
- /* Files vorhanden? */
910
- if ( !$files = self::get_theme_files() ) {
911
- return false;
912
- }
913
-
914
- /* Init */
915
- $results = array();
916
-
917
- /* Files loopen */
918
- foreach($files as $file) {
919
- if ($result = self::check_theme_file($file)) {
920
- $results[$file] = $result;
921
- }
922
- }
923
-
924
- /* Werte vorhanden? */
925
- if ( !empty($results) ) {
926
- return $results;
927
- }
928
-
929
- return false;
930
- }
931
-
932
-
933
- /**
934
- * Prüfung einer Datei
935
- *
936
- * @since 0.1
937
- * @change 0.8
938
- *
939
- * @param string $file Datei zur Prüfung
940
- * @return array $results Array mit Ergebnissen
941
- */
942
-
943
- private static function check_theme_file($file)
944
- {
945
- /* Kein File? */
946
- if ( !$file ) {
947
- return false;
948
- }
949
-
950
- /* Inhalt auslesen */
951
- if ( !$content = self::get_file_content($file) ) {
952
- return false;
953
- }
954
-
955
- /* Init */
956
- $results = array();
957
-
958
- /* Zeilen loopen */
959
- foreach($content as $num => $line) {
960
- if ($result = self::check_file_line($line, $num)) {
961
- $results[$num] = $result;
962
- }
963
- }
964
-
965
- /* Werte vorhanden? */
966
- if ( !empty($results) ) {
967
- return $results;
968
- }
969
-
970
- return false;
971
- }
972
-
973
-
974
- /**
975
- * Prüfung des Permalinks
976
- *
977
- * @since 0.1
978
- * @change 0.8
979
- *
980
- * @return mixed $matches FALSE, wenn kein Fund
981
- */
982
-
983
- private static function check_permalink_structure()
984
- {
985
- if ( $structure = get_option('permalink_structure') ) {
986
- /* Befehle suchen */
987
- preg_match_all(
988
- self::get_preg_match(),
989
- $structure,
990
- $matches
991
- );
992
-
993
- /* Ergebnis speichern */
994
- if ( $matches[1] ) {
995
- return $matches[1];
996
- }
997
- }
998
-
999
- return false;
1000
- }
1001
-
1002
-
1003
- /**
1004
- * Prüfung der Admin-Seite
1005
- *
1006
- * @since 0.1
1007
- * @change 0.8
1008
- *
1009
- * @param integer $page Gesuchte Seite
1010
- * @return boolean TRUE, wenn die aktuelle auch die gesuchte Seite ist
1011
- */
1012
-
1013
- private static function is_current_page($page)
1014
- {
1015
- switch($page) {
1016
- case 'home':
1017
- return ( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'antivirus' );
1018
-
1019
- case 'index':
1020
- case 'plugins':
1021
- return (!empty($GLOBALS['pagenow']) && $GLOBALS['pagenow'] == sprintf('%s.php', $page));
1022
-
1023
- default:
1024
- return false;
1025
- }
1026
- }
1027
-
1028
-
1029
- /**
1030
- * Anzeige des Dashboard-Hinweises
1031
- *
1032
- * @since 0.1
1033
- * @change 1.2
1034
- */
1035
-
1036
- public static function show_dashboard_notice() {
1037
- /* Kein Alert? */
1038
- if ( !self::get_option('cronjob_alert') ) {
1039
- return;
1040
- }
1041
-
1042
- /* Bereits in der Adminbar */
1043
- if ( function_exists('is_admin_bar_showing') && is_admin_bar_showing() ) {
1044
- return;
1045
- }
1046
-
1047
- /* Warnung */
1048
- echo sprintf(
1049
- '<div class="updated fade"><p><strong>%1$s:</strong> %2$s <a href="%3$s">%4$s &rarr;</a></p></div>',
1050
- esc_html__('Virus suspected', 'antivirus'),
1051
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
1052
- add_query_arg(
1053
- array(
1054
- 'page' => 'antivirus'
1055
- ),
1056
- admin_url('options-general.php')
1057
- ),
1058
- esc_html__('Manual scan', 'antivirus')
1059
- );
1060
- }
1061
-
1062
-
1063
- /**
1064
- * Anzeige des Menüs in der Adminbar
1065
- *
1066
- * @since 1.2
1067
- * @change 1.2
1068
- */
1069
-
1070
- public static function add_adminbar_menu( $wp_admin_bar ) {
1071
- /* Kein Alert? */
1072
- if ( !self::get_option('cronjob_alert') ) {
1073
- return;
1074
- }
1075
-
1076
- /* Keine Adminbar? */
1077
- if ( !function_exists('is_admin_bar_showing') or !is_admin_bar_showing() ) {
1078
- return;
1079
- }
1080
-
1081
- /* Hinzufügen */
1082
- $wp_admin_bar->add_menu(
1083
- array(
1084
- 'id' => 'av_alert',
1085
- 'title' => '<span class="ab-icon"></span><span class="ab-label">' .esc_html__('Virus suspected', 'antivirus'). '</span>',
1086
- 'href' => add_query_arg(
1087
- array(
1088
- 'page' => 'antivirus'
1089
- ),
1090
- admin_url('options-general.php')
1091
- )
1092
- )
1093
- );
1094
- }
1095
-
1096
-
1097
- /**
1098
- * Anzeige der GUI
1099
- *
1100
- * @since 0.1
1101
- * @change 0.8
1102
- */
1103
-
1104
- public static function show_admin_menu() {
1105
- /* Updates speichern */
1106
- if ( !empty($_POST) ) {
1107
- /* Referer prüfen */
1108
- check_admin_referer('antivirus');
1109
-
1110
- /* Werte zuweisen */
1111
- $options = array(
1112
- 'cronjob_enable' => (int)(!empty($_POST['av_cronjob_enable'])),
1113
- 'notify_email' => sanitize_email(@$_POST['av_notify_email'])
1114
- );
1115
-
1116
- /* Kein Cronjob? */
1117
- if (empty($options['cronjob_enable'])) {
1118
- $options['notify_email'] = '';
1119
- }
1120
-
1121
- /* Cron stoppen? */
1122
- if ($options['cronjob_enable'] && !self::get_option('cronjob_enable')) {
1123
- self::init_scheduled_hook();
1124
- } else if (!$options['cronjob_enable'] && self::get_option('cronjob_enable')) {
1125
- self::clear_scheduled_hook();
1126
- }
1127
-
1128
- /* Optionen speichern */
1129
- self::update_options($options); ?>
1130
-
1131
- <div id="message" class="updated fade">
1132
- <p>
1133
- <strong>
1134
- <?php _e('Settings saved.') ?>
1135
- </strong>
1136
- </p>
1137
- </div>
1138
- <?php } ?>
1139
-
1140
- <div class="wrap">
1141
- <div class="icon32"></div>
1142
-
1143
- <h2>
1144
- AntiVirus
1145
- </h2>
1146
-
1147
- <form method="post" action="">
1148
- <?php wp_nonce_field('antivirus') ?>
1149
-
1150
- <div id="poststuff">
1151
- <div class="postbox">
1152
- <h3>
1153
- <?php esc_html_e('Completed scan', 'antivirus') ?>
1154
- </h3>
1155
-
1156
- <div class="inside" id="av_completed">
1157
- <div class="output">
1158
- <div class="<?php echo (self::check_permalink_structure() ? 'danger' : 'done') ?>"><?php esc_html_e('Permalink back door check', 'antivirus') ?> <a href="<?php esc_html_e('http://mashable.com/2009/09/05/wordpress-attack/', 'antivirus') ?>" target="_blank">Info</a></div>
1159
- </div>
1160
-
1161
- <ul class="agenda">
1162
- <li>
1163
- <p></p>
1164
- <span>
1165
- <?php esc_html_e('All clear', 'antivirus') ?>
1166
- </span>
1167
- </li>
1168
- <li class="danger">
1169
- <p></p>
1170
- <span>
1171
- <?php esc_html_e('Danger', 'antivirus') ?>
1172
- </span>
1173
- </li>
1174
- </ul>
1175
- </div>
1176
- </div>
1177
-
1178
- <div class="postbox">
1179
- <h3>
1180
- <?php esc_html_e('Manual scan', 'antivirus') ?>
1181
- </h3>
1182
-
1183
- <div class="inside" id="av_manual">
1184
- <p>
1185
- <a href="#" class="button rbutton"><?php esc_html_e('Scan the theme templates now', 'antivirus') ?></a>
1186
- <span class="alert"></span>
1187
- </p>
1188
- <div class="output"></div>
1189
- </div>
1190
- </div>
1191
-
1192
- <div class="postbox">
1193
- <h3>
1194
- <?php _e('Settings') ?>
1195
- </h3>
1196
-
1197
- <div class="inside">
1198
- <table class="form-table">
1199
- <tr>
1200
- <td>
1201
- <label for="av_cronjob_enable">
1202
- <input type="checkbox" name="av_cronjob_enable" id="av_cronjob_enable" value="1" <?php checked(self::get_option('cronjob_enable'), 1) ?> />
1203
- <?php esc_html_e('Enable the daily antivirus scan', 'antivirus') ?>
1204
- <?php if (self::get_option('cronjob_enable') && self::get_option('cronjob_timestamp')) {
1205
- echo sprintf(
1206
- '&nbsp;(%s @ %s)',
1207
- esc_html__('Last check', 'antivirus'),
1208
- date_i18n('d.m.Y H:i:s', (self::get_option('cronjob_timestamp') + get_option('gmt_offset') * 60))
1209
- );
1210
- } ?>
1211
- </label>
1212
- <span class="shift">
1213
- <?php esc_html_e('Alternate email address', 'antivirus') ?>:&nbsp;<input type="text" name="av_notify_email" value="<?php esc_attr_e(self::get_option('notify_email')) ?>" class="regular-text" />
1214
- </span>
1215
- </td>
1216
- </tr>
1217
- </table>
1218
-
1219
- <p>
1220
- <input type="submit" name="av_submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
1221
- </p>
1222
- </div>
1223
- </div>
1224
- </div>
1225
- </form>
1226
- </div>
1227
- <?php }
1228
- }
1229
-
1230
-
1231
- /* Fire */
1232
- add_action(
1233
- 'plugins_loaded',
1234
- array(
1235
- 'AntiVirus',
1236
- 'init'
1237
- ),
1238
- 99
1239
- );
1240
-
1241
-
1242
- /* Install */
1243
- register_activation_hook(
1244
- __FILE__,
1245
- array(
1246
- 'AntiVirus',
1247
- 'install'
1248
- )
1249
- );
1250
-
1251
-
1252
- /* Uninstall */
1253
- register_uninstall_hook(
1254
- __FILE__,
1255
- array(
1256
- 'AntiVirus',
1257
- 'uninstall'
1258
- )
1259
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
antivirus.php CHANGED
@@ -7,726 +7,1272 @@ Description: Security solution as a smart, effectively plugin to protect your bl
7
  Author: Sergej M&uuml;ller
8
  Author URI: http://wpseo.de
9
  Plugin URI: http://wpantivirus.com
10
- Version: 1.2
11
  */
12
 
13
 
 
14
  if ( !class_exists('WP') ) {
15
- header('Status: 403 Forbidden');
16
- header('HTTP/1.1 403 Forbidden');
17
- exit();
18
  }
 
 
 
 
 
 
 
 
19
  class AntiVirus {
20
- private static $base;
21
- public static function init()
22
- {
23
- if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) or (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
24
- return;
25
- }
26
- self::$base = plugin_basename(__FILE__);
27
- if ( defined('DOING_CRON') ) {
28
- add_action(
29
- 'antivirus_daily_cronjob',
30
- array(
31
- __CLASS__,
32
- 'exe_daily_cronjob'
33
- )
34
- );
35
- } elseif ( is_admin() ) {
36
- if ( defined('DOING_AJAX') ) {
37
- add_action(
38
- 'wp_ajax_get_ajax_response',
39
- array(
40
- __CLASS__,
41
- 'get_ajax_response'
42
- )
43
- );
44
- } else {
45
- add_action(
46
- 'init',
47
- array(
48
- __CLASS__,
49
- 'load_plugin_lang'
50
- )
51
- );
52
- add_action(
53
- 'admin_menu',
54
- array(
55
- __CLASS__,
56
- 'add_sidebar_menu'
57
- )
58
- );
59
- add_action(
60
- 'admin_bar_menu',
61
- array(
62
- __CLASS__,
63
- 'add_adminbar_menu'
64
- ),
65
- 91
66
- );
67
- add_action(
68
- 'admin_notices',
69
- array(
70
- __CLASS__,
71
- 'show_dashboard_notice'
72
- )
73
- );
74
- add_action(
75
- 'admin_print_styles',
76
- array(
77
- __CLASS__,
78
- 'add_enqueue_style'
79
- )
80
- );
81
- if ( self::is_current_page('home') ) {
82
- add_action(
83
- 'admin_print_scripts',
84
- array(
85
- __CLASS__,
86
- 'add_enqueue_script'
87
- )
88
- );
89
- } else if ( self::is_current_page('plugins') ) {
90
- add_action(
91
- 'deactivate_' .self::$base,
92
- array(
93
- __CLASS__,
94
- 'clear_scheduled_hook'
95
- )
96
- );
97
- add_filter(
98
- 'plugin_row_meta',
99
- array(
100
- __CLASS__,
101
- 'init_row_meta'
102
- ),
103
- 10,
104
- 2
105
- );
106
- add_filter(
107
- 'plugin_action_links_' .self::$base,
108
- array(
109
- __CLASS__,
110
- 'init_action_links'
111
- )
112
- );
113
- }
114
- }
115
- }
116
- }
117
- public static function load_plugin_lang()
118
- {
119
- load_plugin_textdomain(
120
- 'antivirus',
121
- false,
122
- 'antivirus/lang'
123
- );
124
- }
125
- public static function init_action_links($data)
126
- {
127
- if ( !current_user_can('manage_options') ) {
128
- return $data;
129
- }
130
- return array_merge(
131
- $data,
132
- array(
133
- sprintf(
134
- '<a href="%s">%s</a>',
135
- add_query_arg(
136
- array(
137
- 'page' => 'antivirus'
138
- ),
139
- admin_url('options-general.php')
140
- ),
141
- __('Settings')
142
- )
143
- )
144
- );
145
- }
146
- public static function init_row_meta($data, $page)
147
- {
148
- if ( $page == self::$base ) {
149
- $data = array_merge(
150
- $data,
151
- array(
152
- sprintf(
153
- '<a href="https://flattr.com/thing/58179/Sicherheit-in-WordPress-Das-erste-AntiVirus-Plugin-fur-WordPress" target="_blank">%s</a>',
154
- esc_html__('Flattr plugin', 'antivirus')
155
- ),
156
- sprintf(
157
- '<a href="https://plus.google.com/110569673423509816572" target="_blank">%s</a>',
158
- esc_html__('Follow on Google+', 'antivirus')
159
- )
160
- )
161
- );
162
- }
163
- return $data;
164
- }
165
- public static function install()
166
- {
167
- add_option(
168
- 'antivirus',
169
- array(),
170
- '',
171
- 'no'
172
- );
173
- if ( self::get_option('cronjob_enable') ) {
174
- self::init_scheduled_hook();
175
- }
176
- }
177
- public static function uninstall()
178
- {
179
- global $wpdb;
180
- delete_option('antivirus');
181
- $wpdb->query("OPTIMIZE TABLE `" .$wpdb->options. "`");
182
- }
183
- private static function get_option($field)
184
- {
185
- if ( !$options = wp_cache_get('antivirus') ) {
186
- $options = get_option('antivirus');
187
- wp_cache_set(
188
- 'antivirus',
189
- $options
190
- );
191
- }
192
- return @$options[$field];
193
- }
194
- private static function update_option($field, $value)
195
- {
196
- self::update_options(
197
- array(
198
- $field => $value
199
- )
200
- );
201
- }
202
- private static function update_options($data)
203
- {
204
- $options = array_merge(
205
- (array)get_option('antivirus'),
206
- $data
207
- );
208
- update_option(
209
- 'antivirus',
210
- $options
211
- );
212
- wp_cache_set(
213
- 'antivirus',
214
- $options
215
- );
216
- }
217
- private static function init_scheduled_hook()
218
- {
219
- if ( !wp_next_scheduled('antivirus_daily_cronjob') ) {
220
- wp_schedule_event(
221
- time(),
222
- 'daily',
223
- 'antivirus_daily_cronjob'
224
- );
225
- }
226
- }
227
- public static function clear_scheduled_hook()
228
- {
229
- if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
230
- wp_clear_scheduled_hook('antivirus_daily_cronjob');
231
- }
232
- }
233
- public static function exe_daily_cronjob()
234
- {
235
- if ( !self::get_option('cronjob_enable') ) {
236
- return;
237
- }
238
- self::update_option(
239
- 'cronjob_timestamp',
240
- time()
241
- );
242
- if ( self::check_theme_files() or self::check_permalink_structure() ) {
243
- self::load_plugin_lang();
244
- $email = sanitize_email(self::get_option('notify_email'));
245
- $email = ( (!empty($email) && is_email($email)) ? $email : get_bloginfo('admin_email') );
246
- wp_mail(
247
- $email,
248
- sprintf(
249
- '[%s] %s',
250
- get_bloginfo('name'),
251
- esc_html__('Virus suspected', 'antivirus')
252
- ),
253
- sprintf(
254
- "%s\r\n%s\r\n\r\n\r\n%s\r\n%s\r\n",
255
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
256
- get_bloginfo('url'),
257
- esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
258
- esc_html__('http://wpantivirus.com', 'antivirus')
259
- )
260
- );
261
- self::update_option(
262
- 'cronjob_alert',
263
- 1
264
- );
265
- }
266
- }
267
- public static function add_sidebar_menu()
268
- {
269
- add_options_page(
270
- 'AntiVirus',
271
- '<span id="av_sidebar_icon"></span>AntiVirus',
272
- 'manage_options',
273
- 'antivirus',
274
- array(
275
- __CLASS__,
276
- 'show_admin_menu'
277
- )
278
- );
279
- }
280
- public static function add_enqueue_script()
281
- {
282
- $data = get_plugin_data(__FILE__);
283
- wp_register_script(
284
- 'av_script',
285
- plugins_url('js/script.js', __FILE__),
286
- array('jquery'),
287
- $data['Version']
288
- );
289
- wp_enqueue_script('av_script');
290
- wp_localize_script(
291
- 'av_script',
292
- 'av_settings',
293
- array(
294
- 'nonce' => wp_create_nonce('av_ajax_nonce'),
295
- 'ajax'=> admin_url('admin-ajax.php'),
296
- 'theme'=> urlencode(self::get_theme_name()),
297
- 'msg_1'=> esc_html__('There is no virus', 'antivirus'),
298
- 'msg_2' => esc_html__('View line', 'antivirus'),
299
- 'msg_3' => esc_html__('Scan finished', 'antivirus')
300
- )
301
- );
302
- }
303
- public static function add_enqueue_style()
304
- {
305
- $data = get_plugin_data(__FILE__);
306
- wp_register_style(
307
- 'av_css',
308
- plugins_url('css/style.css', __FILE__),
309
- array(),
310
- $data['Version']
311
- );
312
- wp_enqueue_style('av_css');
313
- }
314
- private static function get_current_theme()
315
- {
316
- if ( $themes = get_themes() ) {
317
- if ($theme = get_current_theme()) {
318
- if (array_key_exists((string)$theme, $themes)) {
319
- return $themes[$theme];
320
- }
321
- }
322
- }
323
- return false;
324
- }
325
- private static function get_theme_files()
326
- {
327
- if ( !$theme = self::get_current_theme() ) {
328
- return false;
329
- }
330
- if ( empty($theme['Template Files']) ) {
331
- return false;
332
- }
333
- return array_unique(
334
- array_map(
335
- create_function(
336
- '$v',
337
- 'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
338
- ),
339
- $theme['Template Files']
340
- )
341
- );
342
- }
343
- private static function get_theme_name()
344
- {
345
- if ( $theme = self::get_current_theme() ) {
346
- if (!empty($theme['Name'])) {
347
- return $theme['Name'];
348
- }
349
- }
350
- return false;
351
- }
352
- private static function get_white_list()
353
- {
354
- return explode(
355
- ':',
356
- self::get_option('white_list')
357
- );
358
- }
359
- public static function get_ajax_response()
360
- {
361
- check_ajax_referer('av_ajax_nonce');
362
- if ( empty($_POST['_action_request']) ) {
363
- exit();
364
- }
365
- $values = array();
366
- $output = '';
367
- switch ($_POST['_action_request']) {
368
- case 'get_theme_files':
369
- self::update_option(
370
- 'cronjob_alert',
371
- 0
372
- );
373
- $values = self::get_theme_files();
374
- break;
375
- case 'check_theme_file':
376
- if ( !empty($_POST['_theme_file']) && $lines = self::check_theme_file($_POST['_theme_file']) ) {
377
- foreach ($lines as $num => $line) {
378
- foreach ($line as $string) {
379
- $values[] = $num;
380
- $values[] = htmlentities($string, ENT_QUOTES);
381
- $values[] = md5($num . $string);
382
- }
383
- }
384
- }
385
- break;
386
- case 'update_white_list':
387
- if ( !empty($_POST['_file_md5']) ) {
388
- self::update_option(
389
- 'white_list',
390
- implode(
391
- ':',
392
- array_unique(
393
- array_merge(
394
- self::get_white_list(),
395
- array($_POST['_file_md5'])
396
- )
397
- )
398
- )
399
- );
400
- $values = array($_POST['_file_md5']);
401
- }
402
- break;
403
- default:
404
- break;
405
- }
406
- if ($values) {
407
- $output = sprintf(
408
- "['%s']",
409
- implode("', '", $values)
410
- );
411
- header('Content-Type: plain/text');
412
- echo sprintf(
413
- '{data:%s, nonce:"%s"}',
414
- $output,
415
- $_POST['_ajax_nonce']
416
- );
417
- }
418
- exit();
419
- }
420
- private static function get_file_content($file)
421
- {
422
- return file(WP_CONTENT_DIR . $file);
423
- }
424
- public static function get_dotted_line($line, $tag, $max = 100)
425
- {
426
- if ( !$line or !$tag ) {
427
- return false;
428
- }
429
- if ( strlen($tag) > $max ) {
430
- return $tag;
431
- }
432
- $left = round(($max - strlen($tag)) / 2);
433
- $tag = preg_quote($tag);
434
- $output = preg_replace(
435
- '/(' .$tag. ')(.{' .$left. '}).{0,}$/',
436
- '$1$2 ...',
437
- $line
438
- );
439
- $output = preg_replace(
440
- '/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
441
- '... $1$2',
442
- $output
443
- );
444
- return $output;
445
- }
446
- private static function get_preg_match()
447
- {
448
- 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|include|include_once|require|require_once|file_put_contents|iframe)\s*?\(/';
449
- }
450
- private static function check_file_line($line = '', $num)
451
- {
452
- $line = trim((string)$line);
453
- if ( !$line or !isset($num) ) {
454
- return false;
455
- }
456
- $results = array();
457
- $output = array();
458
- preg_match_all(
459
- self::get_preg_match(),
460
- $line,
461
- $matches
462
- );
463
- if ( $matches[1] ) {
464
- $results = $matches[1];
465
- }
466
- preg_match_all(
467
- '/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/',
468
- $line,
469
- $matches
470
- );
471
- if ( $matches[1] ) {
472
- $results = array_merge($results, $matches[1]);
473
- }
474
- preg_match_all(
475
- '/<\s*?(frame)/',
476
- $line,
477
- $matches
478
- );
479
- if ( $matches[1] ) {
480
- $results = array_merge($results, $matches[1]);
481
- }
482
- preg_match(
483
- '/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
484
- $line,
485
- $matches
486
- );
487
- if ( $matches && $matches[1] && self::check_file_line(get_option($matches[1]), $num) ) {
488
- array_push($results, 'get_option');
489
- }
490
- if ( $results ) {
491
- $results = array_unique($results);
492
- $md5 = self::get_white_list();
493
- foreach ($results as $tag) {
494
- $string = str_replace(
495
- $tag,
496
- '@span@' .$tag. '@/span@',
497
- self::get_dotted_line($line, $tag)
498
- );
499
- if (!in_array(md5($num . $string), $md5)) {
500
- $output[] = $string;
501
- }
502
- }
503
- return $output;
504
- }
505
- return false;
506
- }
507
- private static function check_theme_files()
508
- {
509
- if ( !$files = self::get_theme_files() ) {
510
- return false;
511
- }
512
- $results = array();
513
- foreach($files as $file) {
514
- if ($result = self::check_theme_file($file)) {
515
- $results[$file] = $result;
516
- }
517
- }
518
- if ( !empty($results) ) {
519
- return $results;
520
- }
521
- return false;
522
- }
523
- private static function check_theme_file($file)
524
- {
525
- if ( !$file ) {
526
- return false;
527
- }
528
- if ( !$content = self::get_file_content($file) ) {
529
- return false;
530
- }
531
- $results = array();
532
- foreach($content as $num => $line) {
533
- if ($result = self::check_file_line($line, $num)) {
534
- $results[$num] = $result;
535
- }
536
- }
537
- if ( !empty($results) ) {
538
- return $results;
539
- }
540
- return false;
541
- }
542
- private static function check_permalink_structure()
543
- {
544
- if ( $structure = get_option('permalink_structure') ) {
545
- preg_match_all(
546
- self::get_preg_match(),
547
- $structure,
548
- $matches
549
- );
550
- if ( $matches[1] ) {
551
- return $matches[1];
552
- }
553
- }
554
- return false;
555
- }
556
- private static function is_current_page($page)
557
- {
558
- switch($page) {
559
- case 'home':
560
- return ( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'antivirus' );
561
- case 'index':
562
- case 'plugins':
563
- return (!empty($GLOBALS['pagenow']) && $GLOBALS['pagenow'] == sprintf('%s.php', $page));
564
- default:
565
- return false;
566
- }
567
- }
568
- public static function show_dashboard_notice() {
569
- if ( !self::get_option('cronjob_alert') ) {
570
- return;
571
- }
572
- if ( function_exists('is_admin_bar_showing') && is_admin_bar_showing() ) {
573
- return;
574
- }
575
- echo sprintf(
576
- '<div class="updated fade"><p><strong>%1$s:</strong> %2$s <a href="%3$s">%4$s &rarr;</a></p></div>',
577
- esc_html__('Virus suspected', 'antivirus'),
578
- esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
579
- add_query_arg(
580
- array(
581
- 'page' => 'antivirus'
582
- ),
583
- admin_url('options-general.php')
584
- ),
585
- esc_html__('Manual scan', 'antivirus')
586
- );
587
- }
588
- public static function add_adminbar_menu( $wp_admin_bar ) {
589
- if ( !self::get_option('cronjob_alert') ) {
590
- return;
591
- }
592
- if ( !function_exists('is_admin_bar_showing') or !is_admin_bar_showing() ) {
593
- return;
594
- }
595
- $wp_admin_bar->add_menu(
596
- array(
597
- 'id'=> 'av_alert',
598
- 'title' => '<span class="ab-icon"></span><span class="ab-label">' .esc_html__('Virus suspected', 'antivirus'). '</span>',
599
- 'href'=> add_query_arg(
600
- array(
601
- 'page' => 'antivirus'
602
- ),
603
- admin_url('options-general.php')
604
- )
605
- )
606
- );
607
- }
608
- public static function show_admin_menu() {
609
- if ( !empty($_POST) ) {
610
- check_admin_referer('antivirus');
611
- $options = array(
612
- 'cronjob_enable' => (int)(!empty($_POST['av_cronjob_enable'])),
613
- 'notify_email'=> sanitize_email(@$_POST['av_notify_email'])
614
- );
615
- if (empty($options['cronjob_enable'])) {
616
- $options['notify_email'] = '';
617
- }
618
- if ($options['cronjob_enable'] && !self::get_option('cronjob_enable')) {
619
- self::init_scheduled_hook();
620
- } else if (!$options['cronjob_enable'] && self::get_option('cronjob_enable')) {
621
- self::clear_scheduled_hook();
622
- }
623
- self::update_options($options); ?>
624
- <div id="message" class="updated fade">
625
- <p>
626
- <strong>
627
- <?php _e('Settings saved.') ?>
628
- </strong>
629
- </p>
630
- </div>
631
- <?php } ?>
632
- <div class="wrap">
633
- <div class="icon32"></div>
634
- <h2>
635
- AntiVirus
636
- </h2>
637
- <form method="post" action="">
638
- <?php wp_nonce_field('antivirus') ?>
639
- <div id="poststuff">
640
- <div class="postbox">
641
- <h3>
642
- <?php esc_html_e('Completed scan', 'antivirus') ?>
643
- </h3>
644
- <div class="inside" id="av_completed">
645
- <div class="output">
646
- <div class="<?php echo (self::check_permalink_structure() ? 'danger' : 'done') ?>"><?php esc_html_e('Permalink back door check', 'antivirus') ?> <a href="<?php esc_html_e('http://mashable.com/2009/09/05/wordpress-attack/', 'antivirus') ?>" target="_blank">Info</a></div>
647
- </div>
648
- <ul class="agenda">
649
- <li>
650
- <p></p>
651
- <span>
652
- <?php esc_html_e('All clear', 'antivirus') ?>
653
- </span>
654
- </li>
655
- <li class="danger">
656
- <p></p>
657
- <span>
658
- <?php esc_html_e('Danger', 'antivirus') ?>
659
- </span>
660
- </li>
661
- </ul>
662
- </div>
663
- </div>
664
- <div class="postbox">
665
- <h3>
666
- <?php esc_html_e('Manual scan', 'antivirus') ?>
667
- </h3>
668
- <div class="inside" id="av_manual">
669
- <p>
670
- <a href="#" class="button rbutton"><?php esc_html_e('Scan the theme templates now', 'antivirus') ?></a>
671
- <span class="alert"></span>
672
- </p>
673
- <div class="output"></div>
674
- </div>
675
- </div>
676
- <div class="postbox">
677
- <h3>
678
- <?php _e('Settings') ?>
679
- </h3>
680
- <div class="inside">
681
- <table class="form-table">
682
- <tr>
683
- <td>
684
- <label for="av_cronjob_enable">
685
- <input type="checkbox" name="av_cronjob_enable" id="av_cronjob_enable" value="1" <?php checked(self::get_option('cronjob_enable'), 1) ?> />
686
- <?php esc_html_e('Enable the daily antivirus scan', 'antivirus') ?>
687
- <?php if (self::get_option('cronjob_enable') && self::get_option('cronjob_timestamp')) {
688
- echo sprintf(
689
- '&nbsp;(%s @ %s)',
690
- esc_html__('Last check', 'antivirus'),
691
- date_i18n('d.m.Y H:i:s', (self::get_option('cronjob_timestamp') + get_option('gmt_offset') * 60))
692
- );
693
- } ?>
694
- </label>
695
- <span class="shift">
696
- <?php esc_html_e('Alternate email address', 'antivirus') ?>:&nbsp;<input type="text" name="av_notify_email" value="<?php esc_attr_e(self::get_option('notify_email')) ?>" class="regular-text" />
697
- </span>
698
- </td>
699
- </tr>
700
- </table>
701
- <p>
702
- <input type="submit" name="av_submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
703
- </p>
704
- </div>
705
- </div>
706
- </div>
707
- </form>
708
- </div>
709
- <?php }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
710
  }
 
 
 
711
  add_action(
712
- 'plugins_loaded',
713
- array(
714
- 'AntiVirus',
715
- 'init'
716
- ),
717
- 99
718
  );
 
 
 
719
  register_activation_hook(
720
- __FILE__,
721
- array(
722
- 'AntiVirus',
723
- 'install'
724
- )
725
  );
 
 
 
726
  register_uninstall_hook(
727
- __FILE__,
728
- array(
729
- 'AntiVirus',
730
- 'uninstall'
731
- )
732
  );
7
  Author: Sergej M&uuml;ller
8
  Author URI: http://wpseo.de
9
  Plugin URI: http://wpantivirus.com
10
+ Version: 1.3.1
11
  */
12
 
13
 
14
+ /* Sicherheitsabfrage */
15
  if ( !class_exists('WP') ) {
16
+ header('Status: 403 Forbidden');
17
+ header('HTTP/1.1 403 Forbidden');
18
+ exit();
19
  }
20
+
21
+
22
+ /**
23
+ * AntiVirus
24
+ *
25
+ * @since 0.1
26
+ */
27
+
28
  class AntiVirus {
29
+
30
+
31
+ /* Save me! */
32
+ private static $base;
33
+
34
+
35
+ /**
36
+ * Konstruktor der Klasse
37
+ *
38
+ * @since 0.1
39
+ * @change 1.2
40
+ */
41
+
42
+ public static function init()
43
+ {
44
+ /* AUTOSAVE */
45
+ if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) or (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
46
+ return;
47
+ }
48
+
49
+ /* Plugin-Base */
50
+ self::$base = plugin_basename(__FILE__);
51
+
52
+ /* Cronjob */
53
+ if ( defined('DOING_CRON') ) {
54
+ add_action(
55
+ 'antivirus_daily_cronjob',
56
+ array(
57
+ __CLASS__,
58
+ 'exe_daily_cronjob'
59
+ )
60
+ );
61
+
62
+ /* Admin */
63
+ } elseif ( is_admin() ) {
64
+ /* AJAX */
65
+ if ( defined('DOING_AJAX') ) {
66
+ add_action(
67
+ 'wp_ajax_get_ajax_response',
68
+ array(
69
+ __CLASS__,
70
+ 'get_ajax_response'
71
+ )
72
+ );
73
+
74
+ /* Backend */
75
+ } else {
76
+ /* Actions */
77
+ add_action(
78
+ 'init',
79
+ array(
80
+ __CLASS__,
81
+ 'load_plugin_lang'
82
+ )
83
+ );
84
+ add_action(
85
+ 'admin_menu',
86
+ array(
87
+ __CLASS__,
88
+ 'add_sidebar_menu'
89
+ )
90
+ );
91
+ add_action(
92
+ 'admin_bar_menu',
93
+ array(
94
+ __CLASS__,
95
+ 'add_adminbar_menu'
96
+ ),
97
+ 91
98
+ );
99
+ add_action(
100
+ 'admin_notices',
101
+ array(
102
+ __CLASS__,
103
+ 'show_dashboard_notice'
104
+ )
105
+ );
106
+ add_action(
107
+ 'admin_print_styles',
108
+ array(
109
+ __CLASS__,
110
+ 'add_enqueue_style'
111
+ )
112
+ );
113
+
114
+ /* GUI */
115
+ if ( self::is_current_page('home') ) {
116
+ add_action(
117
+ 'admin_print_scripts',
118
+ array(
119
+ __CLASS__,
120
+ 'add_enqueue_script'
121
+ )
122
+ );
123
+
124
+ /* Plugins */
125
+ } else if ( self::is_current_page('plugins') ) {
126
+ add_action(
127
+ 'deactivate_' .self::$base,
128
+ array(
129
+ __CLASS__,
130
+ 'clear_scheduled_hook'
131
+ )
132
+ );
133
+ add_filter(
134
+ 'plugin_row_meta',
135
+ array(
136
+ __CLASS__,
137
+ 'init_row_meta'
138
+ ),
139
+ 10,
140
+ 2
141
+ );
142
+ add_filter(
143
+ 'plugin_action_links_' .self::$base,
144
+ array(
145
+ __CLASS__,
146
+ 'init_action_links'
147
+ )
148
+ );
149
+ }
150
+ }
151
+ }
152
+ }
153
+
154
+
155
+ /**
156
+ * Einbindung der Sprache
157
+ *
158
+ * @since 0.8
159
+ * @change 0.8
160
+ */
161
+
162
+ public static function load_plugin_lang()
163
+ {
164
+ load_plugin_textdomain(
165
+ 'antivirus',
166
+ false,
167
+ 'antivirus/lang'
168
+ );
169
+ }
170
+
171
+
172
+ /**
173
+ * Hinzufügen der Action-Links (Einstellungen links)
174
+ *
175
+ * @since 1.1
176
+ * @change 1.1
177
+ */
178
+
179
+ public static function init_action_links($data)
180
+ {
181
+ /* Rechte? */
182
+ if ( !current_user_can('manage_options') ) {
183
+ return $data;
184
+ }
185
+
186
+ return array_merge(
187
+ $data,
188
+ array(
189
+ sprintf(
190
+ '<a href="%s">%s</a>',
191
+ add_query_arg(
192
+ array(
193
+ 'page' => 'antivirus'
194
+ ),
195
+ admin_url('options-general.php')
196
+ ),
197
+ __('Settings')
198
+ )
199
+ )
200
+ );
201
+ }
202
+
203
+
204
+ /**
205
+ * Links in der Plugins-Verwaltung
206
+ *
207
+ * @since 0.1
208
+ * @change 1.1
209
+ *
210
+ * @param array $links Array mit Links
211
+ * @param string $file Name des Plugins
212
+ * @return array $links Array mit erweitertem Link
213
+ */
214
+
215
+ public static function init_row_meta($data, $page)
216
+ {
217
+ if ( $page == self::$base ) {
218
+ $data = array_merge(
219
+ $data,
220
+ array(
221
+ sprintf(
222
+ '<a href="https://flattr.com/thing/58179/Sicherheit-in-WordPress-Das-erste-AntiVirus-Plugin-fur-WordPress" target="_blank">%s</a>',
223
+ esc_html__('Flattr plugin', 'antivirus')
224
+ ),
225
+ sprintf(
226
+ '<a href="https://plus.google.com/110569673423509816572" target="_blank">%s</a>',
227
+ esc_html__('Follow on Google+', 'antivirus')
228
+ )
229
+ )
230
+ );
231
+ }
232
+
233
+ return $data;
234
+ }
235
+
236
+
237
+ /**
238
+ * Aktion bei Aktivierung des Plugins
239
+ *
240
+ * @since 0.1
241
+ * @change 0.8
242
+ */
243
+
244
+ public static function install()
245
+ {
246
+ /* Option anlegen */
247
+ add_option(
248
+ 'antivirus',
249
+ array(),
250
+ '',
251
+ 'no'
252
+ );
253
+
254
+ /* Cron aktivieren */
255
+ if ( self::get_option('cronjob_enable') ) {
256
+ self::init_scheduled_hook();
257
+ }
258
+ }
259
+
260
+
261
+ /**
262
+ * Uninstallation des Plugins pro MU-Blog
263
+ *
264
+ * @since 1.1
265
+ * @change 1.1
266
+ */
267
+
268
+ public static function uninstall()
269
+ {
270
+ /* Global */
271
+ global $wpdb;
272
+
273
+ /* Remove settings */
274
+ delete_option('antivirus');
275
+
276
+ /* Clean DB */
277
+ $wpdb->query("OPTIMIZE TABLE `" .$wpdb->options. "`");
278
+ }
279
+
280
+
281
+ /**
282
+ * Rückgabe eines Optionsfeldes
283
+ *
284
+ * @since 0.1
285
+ * @change 0.8
286
+ *
287
+ * @param string $field Name des Feldes
288
+ * @return mixed Wert des Feldes
289
+ */
290
+
291
+ private static function get_option($field)
292
+ {
293
+ if ( !$options = wp_cache_get('antivirus') ) {
294
+ $options = get_option('antivirus');
295
+ wp_cache_set(
296
+ 'antivirus',
297
+ $options
298
+ );
299
+ }
300
+
301
+ return @$options[$field];
302
+ }
303
+
304
+
305
+ /**
306
+ * Aktualisiert ein Optionsfeld
307
+ *
308
+ * @since 0.1
309
+ * @change 0.8
310
+ *
311
+ * @param string $field Name des Feldes
312
+ * @param mixed Wert des Feldes
313
+ */
314
+
315
+ private static function update_option($field, $value)
316
+ {
317
+ self::update_options(
318
+ array(
319
+ $field => $value
320
+ )
321
+ );
322
+ }
323
+
324
+
325
+ /**
326
+ * Aktualisiert mehrere Optionsfelder
327
+ *
328
+ * @since 0.1
329
+ * @change 0.8
330
+ *
331
+ * @param array $data Array mit Feldern
332
+ */
333
+
334
+ private static function update_options($data)
335
+ {
336
+ /* Option zuweisen */
337
+ $options = array_merge(
338
+ (array)get_option('antivirus'),
339
+ $data
340
+ );
341
+
342
+ /* DB updaten */
343
+ update_option(
344
+ 'antivirus',
345
+ $options
346
+ );
347
+
348
+ /* Cache updaten */
349
+ wp_cache_set(
350
+ 'antivirus',
351
+ $options
352
+ );
353
+ }
354
+
355
+
356
+ /**
357
+ * Initialisierung des Cronjobs
358
+ *
359
+ * @since 0.1
360
+ * @change 0.8
361
+ */
362
+
363
+ private static function init_scheduled_hook()
364
+ {
365
+ if ( !wp_next_scheduled('antivirus_daily_cronjob') ) {
366
+ wp_schedule_event(
367
+ time(),
368
+ 'daily',
369
+ 'antivirus_daily_cronjob'
370
+ );
371
+ }
372
+ }
373
+
374
+
375
+ /**
376
+ * Beendigung des Cronjobs
377
+ *
378
+ * @since 0.1
379
+ * @change 0.8
380
+ */
381
+
382
+ public static function clear_scheduled_hook()
383
+ {
384
+ if ( wp_next_scheduled('antivirus_daily_cronjob') ) {
385
+ wp_clear_scheduled_hook('antivirus_daily_cronjob');
386
+ }
387
+ }
388
+
389
+
390
+ /**
391
+ * Ausführung des Cronjobs
392
+ *
393
+ * @since 0.1
394
+ * @change 1.0
395
+ */
396
+
397
+ public static function exe_daily_cronjob()
398
+ {
399
+ /* Kein Cronjob? */
400
+ if ( !self::get_option('cronjob_enable') ) {
401
+ return;
402
+ }
403
+
404
+ /* Timestamp updaten */
405
+ self::update_option(
406
+ 'cronjob_timestamp',
407
+ time()
408
+ );
409
+
410
+ /* Files prüfen */
411
+ if ( self::check_theme_files() or self::check_permalink_structure() ) {
412
+ /* Sprache laden */
413
+ self::load_plugin_lang();
414
+
415
+ /* E-Mail-Adresse */
416
+ $email = sanitize_email(self::get_option('notify_email'));
417
+ $email = ( (!empty($email) && is_email($email)) ? $email : get_bloginfo('admin_email') );
418
+
419
+ /* Send it! */
420
+ wp_mail(
421
+ $email,
422
+ sprintf(
423
+ '[%s] %s',
424
+ get_bloginfo('name'),
425
+ esc_html__('Virus suspected', 'antivirus')
426
+ ),
427
+ sprintf(
428
+ "%s\r\n%s\r\n\r\n\r\n%s\r\n%s\r\n",
429
+ esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
430
+ get_bloginfo('url'),
431
+ esc_html__('Notify message by AntiVirus for WordPress', 'antivirus'),
432
+ esc_html__('http://wpantivirus.com', 'antivirus')
433
+ )
434
+ );
435
+
436
+ /* Alert speichern */
437
+ self::update_option(
438
+ 'cronjob_alert',
439
+ 1
440
+ );
441
+ }
442
+ }
443
+
444
+
445
+ /**
446
+ * Initialisierung der GUI
447
+ *
448
+ * @since 0.1
449
+ * @change 1.3.1
450
+ */
451
+
452
+ public static function add_sidebar_menu()
453
+ {
454
+ /* Menü anlegen */
455
+ add_options_page(
456
+ 'AntiVirus',
457
+ 'AntiVirus',
458
+ 'manage_options',
459
+ 'antivirus',
460
+ array(
461
+ __CLASS__,
462
+ 'show_admin_menu'
463
+ )
464
+ );
465
+ }
466
+
467
+
468
+ /**
469
+ * Initialisierung von JavaScript
470
+ *
471
+ * @since 0.8
472
+ * @change 1.1
473
+ */
474
+
475
+ public static function add_enqueue_script()
476
+ {
477
+ /* Infos auslesen */
478
+ $data = get_plugin_data(__FILE__);
479
+
480
+ /* JS einbinden */
481
+ wp_register_script(
482
+ 'av_script',
483
+ plugins_url('js/script.js', __FILE__),
484
+ array('jquery'),
485
+ $data['Version']
486
+ );
487
+
488
+ /* Script einbinden */
489
+ wp_enqueue_script('av_script');
490
+
491
+ /* Script lokalisieren */
492
+ wp_localize_script(
493
+ 'av_script',
494
+ 'av_settings',
495
+ array(
496
+ 'nonce' => wp_create_nonce('av_ajax_nonce'),
497
+ 'ajax' => admin_url('admin-ajax.php'),
498
+ 'theme' => urlencode(self::get_theme_name()),
499
+ 'msg_1' => esc_html__('There is no virus', 'antivirus'),
500
+ 'msg_2' => esc_html__('View line', 'antivirus'),
501
+ 'msg_3' => esc_html__('Scan finished', 'antivirus')
502
+ )
503
+ );
504
+ }
505
+
506
+
507
+ /**
508
+ * Initialisierung von Stylesheets
509
+ *
510
+ * @since 0.8
511
+ * @change 1.1
512
+ */
513
+
514
+ public static function add_enqueue_style()
515
+ {
516
+ /* Infos auslesen */
517
+ $data = get_plugin_data(__FILE__);
518
+
519
+ /* CSS registrieren */
520
+ wp_register_style(
521
+ 'av_css',
522
+ plugins_url('css/style.css', __FILE__),
523
+ array(),
524
+ $data['Version']
525
+ );
526
+
527
+ /* CSS einbinden */
528
+ wp_enqueue_style('av_css');
529
+ }
530
+
531
+
532
+ /**
533
+ * Rückgabe des aktuellen Theme
534
+ *
535
+ * @since 0.1
536
+ * @change 1.3.1
537
+ *
538
+ * @return array $themes Array mit Theme-Eigenschaften
539
+ */
540
+
541
+ private static function get_current_theme()
542
+ {
543
+ /* Ab WP 3.4 */
544
+ if ( function_exists('wp_get_theme') ) {
545
+ /* Init */
546
+ $name = wp_get_theme()->get('Name');
547
+ $files = glob(get_template_directory(). '/*.php', GLOB_NOSORT|GLOB_ERR);
548
+
549
+ /* Leer? */
550
+ if ( empty($name) or empty($files) ) {
551
+ return false;
552
+ }
553
+
554
+ /* Rückgabe */
555
+ return array(
556
+ 'Name' => $name,
557
+ 'Template Files' => $files
558
+ );
559
+ /* Bis WP 3.4 */
560
+ } else {
561
+ if ( $themes = get_themes() ) {
562
+ /* Aktuelles Theme */
563
+ if ( $theme = get_current_theme() ) {
564
+ if ( array_key_exists((string)$theme, $themes) ) {
565
+ return $themes[$theme];
566
+ }
567
+ }
568
+ }
569
+
570
+ }
571
+
572
+ return false;
573
+ }
574
+
575
+
576
+ /**
577
+ * Rückgabe von Dateien des aktuellen Theme
578
+ *
579
+ * @since 0.1
580
+ * @change 0.8
581
+ *
582
+ * @return array $files Array mit Dateien
583
+ */
584
+
585
+ private static function get_theme_files()
586
+ {
587
+ /* Theme vorhanden? */
588
+ if ( !$theme = self::get_current_theme() ) {
589
+ return false;
590
+ }
591
+
592
+ /* Keine Files? */
593
+ if ( empty($theme['Template Files']) ) {
594
+ return false;
595
+ }
596
+
597
+ /* Zurückgeben */
598
+ return array_unique(
599
+ array_map(
600
+ create_function(
601
+ '$v',
602
+ 'return str_replace(array(WP_CONTENT_DIR, "wp-content"), "", $v);'
603
+ ),
604
+ $theme['Template Files']
605
+ )
606
+ );
607
+ }
608
+
609
+
610
+ /**
611
+ * Rückgabe des Namen des aktuellen Theme
612
+ *
613
+ * @since 0.1
614
+ * @change 0.8
615
+ *
616
+ * @return string $theme Name des aktuellen Theme
617
+ */
618
+
619
+ private static function get_theme_name()
620
+ {
621
+ if ( $theme = self::get_current_theme() ) {
622
+ if (!empty($theme['Name'])) {
623
+ return $theme['Name'];
624
+ }
625
+ }
626
+
627
+ return false;
628
+ }
629
+
630
+
631
+ /**
632
+ * Rückgabe der WhiteList
633
+ *
634
+ * @since 0.1
635
+ * @change 0.8
636
+ *
637
+ * @return array return Array mit MD5-Werten
638
+ */
639
+
640
+ private static function get_white_list()
641
+ {
642
+ return explode(
643
+ ':',
644
+ self::get_option('white_list')
645
+ );
646
+ }
647
+
648
+
649
+ /**
650
+ * Ausführung von AJAX
651
+ *
652
+ * @since 0.1
653
+ * @change 0.8
654
+ */
655
+
656
+ public static function get_ajax_response()
657
+ {
658
+ /* Referer prüfen */
659
+ check_ajax_referer('av_ajax_nonce');
660
+
661
+ /* Zusätzliche Prüfung */
662
+ if ( empty($_POST['_action_request']) ) {
663
+ exit();
664
+ }
665
+
666
+ /* Init */
667
+ $values = array();
668
+ $output = '';
669
+
670
+ /* Ausgabe starten */
671
+ switch ($_POST['_action_request']) {
672
+ case 'get_theme_files':
673
+ self::update_option(
674
+ 'cronjob_alert',
675
+ 0
676
+ );
677
+
678
+ $values = self::get_theme_files();
679
+ break;
680
+
681
+ case 'check_theme_file':
682
+ if ( !empty($_POST['_theme_file']) && $lines = self::check_theme_file($_POST['_theme_file']) ) {
683
+ foreach ($lines as $num => $line) {
684
+ foreach ($line as $string) {
685
+ $values[] = $num;
686
+ $values[] = htmlentities($string, ENT_QUOTES);
687
+ $values[] = md5($num . $string);
688
+ }
689
+ }
690
+ }
691
+ break;
692
+
693
+ case 'update_white_list':
694
+ if ( !empty($_POST['_file_md5']) ) {
695
+ self::update_option(
696
+ 'white_list',
697
+ implode(
698
+ ':',
699
+ array_unique(
700
+ array_merge(
701
+ self::get_white_list(),
702
+ array($_POST['_file_md5'])
703
+ )
704
+ )
705
+ )
706
+ );
707
+
708
+ $values = array($_POST['_file_md5']);
709
+ }
710
+ break;
711
+
712
+ default:
713
+ break;
714
+ }
715
+
716
+ /* Ausgabe starten */
717
+ if ($values) {
718
+ $output = sprintf(
719
+ "['%s']",
720
+ implode("', '", $values)
721
+ );
722
+
723
+ /* Header senden */
724
+ header('Content-Type: plain/text');
725
+
726
+ /* Ausgeben */
727
+ echo sprintf(
728
+ '{data:%s, nonce:"%s"}',
729
+ $output,
730
+ $_POST['_ajax_nonce']
731
+ );
732
+ }
733
+
734
+ /* Raus! */
735
+ exit();
736
+ }
737
+
738
+
739
+ /**
740
+ * Rückgabe des Dateiinhaltes
741
+ *
742
+ * @since 0.1
743
+ * @change 0.8
744
+ *
745
+ * @return array $file Array mit Dateizeilen
746
+ */
747
+
748
+ private static function get_file_content($file)
749
+ {
750
+ return file(WP_CONTENT_DIR . $file);
751
+ }
752
+
753
+
754
+ /**
755
+ * Kürzung eines Strings
756
+ *
757
+ * @since 0.1
758
+ * @change 0.1
759
+ *
760
+ * @param string $line Eigenetliche Zeile als String
761
+ * @param string $tag Gesuchtes Tag
762
+ * @param integer $max Anzahl der Zeichen rechts und links
763
+ * @return string $output Gekürzter String
764
+ */
765
+
766
+ public static function get_dotted_line($line, $tag, $max = 100)
767
+ {
768
+ /* Keine Werte? */
769
+ if ( !$line or !$tag ) {
770
+ return false;
771
+ }
772
+
773
+ /* Differenz ermitteln */
774
+ if ( strlen($tag) > $max ) {
775
+ return $tag;
776
+ }
777
+
778
+ /* Differenz ermitteln */
779
+ $left = round(($max - strlen($tag)) / 2);
780
+
781
+ /* Wert konvertieren */
782
+ $tag = preg_quote($tag);
783
+
784
+ /* String kürzen */
785
+ $output = preg_replace(
786
+ '/(' .$tag. ')(.{' .$left. '}).{0,}$/',
787
+ '$1$2 ...',
788
+ $line
789
+ );
790
+ $output = preg_replace(
791
+ '/^.{0,}(.{' .$left. ',})(' .$tag. ')/',
792
+ '... $1$2',
793
+ $output
794
+ );
795
+
796
+ return $output;
797
+ }
798
+
799
+
800
+ /**
801
+ * Definition des Regexp
802
+ *
803
+ * @since 0.1
804
+ * @change 1.2
805
+ *
806
+ * @return string return Regulärer Ausdruck
807
+ */
808
+
809
+ private static function get_preg_match()
810
+ {
811
+ 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|include|include_once|require|require_once|file_put_contents|iframe)\s*?\(/';
812
+ }
813
+
814
+
815
+ /**
816
+ * Prüfung einer Zeile
817
+ *
818
+ * @since 0.1
819
+ * @change 1.1
820
+ *
821
+ * @param string $line Zeile zur Prüfung
822
+ * @param integer $num Nummer zur Prüfung
823
+ * @return string $line Zeile mit Resultaten
824
+ */
825
+
826
+ private static function check_file_line($line = '', $num)
827
+ {
828
+ /* Wert trimmen */
829
+ $line = trim((string)$line);
830
+
831
+ /* Leere Werte? */
832
+ if ( !$line or !isset($num) ) {
833
+ return false;
834
+ }
835
+
836
+ /* Werte initialisieren */
837
+ $results = array();
838
+ $output = array();
839
+
840
+ /* Befehle suchen */
841
+ preg_match_all(
842
+ self::get_preg_match(),
843
+ $line,
844
+ $matches
845
+ );
846
+
847
+ /* Ergebnis speichern */
848
+ if ( $matches[1] ) {
849
+ $results = $matches[1];
850
+ }
851
+
852
+ /* Base64 suchen */
853
+ preg_match_all(
854
+ '/[\'\"\$\\ \/]*?([a-zA-Z0-9]{' .strlen(base64_encode('sergej + swetlana = love.')). ',})/',
855
+ $line,
856
+ $matches
857
+ );
858
+
859
+ /* Ergebnis speichern */
860
+ if ( $matches[1] ) {
861
+ $results = array_merge($results, $matches[1]);
862
+ }
863
+
864
+ /* Frames suchen */
865
+ preg_match_all(
866
+ '/<\s*?(frame)/',
867
+ $line,
868
+ $matches
869
+ );
870
+
871
+ /* Ergebnis speichern */
872
+ if ( $matches[1] ) {
873
+ $results = array_merge($results, $matches[1]);
874
+ }
875
+
876
+ /* Option suchen */
877
+ preg_match(
878
+ '/get_option\s*\(\s*[\'"](.*?)[\'"]\s*\)/',
879
+ $line,
880
+ $matches
881
+ );
882
+
883
+ /* Option prüfen */
884
+ if ( $matches && $matches[1] && self::check_file_line(get_option($matches[1]), $num) ) {
885
+ array_push($results, 'get_option');
886
+ }
887
+
888
+ /* Ergebnisse? */
889
+ if ( $results ) {
890
+ /* Keine Duplikate */
891
+ $results = array_unique($results);
892
+
893
+ /* White-Liste */
894
+ $md5 = self::get_white_list();
895
+
896
+ /* Resultate loopen */
897
+ foreach ($results as $tag) {
898
+ $string = str_replace(
899
+ $tag,
900
+ '@span@' .$tag. '@/span@',
901
+ self::get_dotted_line($line, $tag)
902
+ );
903
+
904
+ /* In der Whitelist? */
905
+ if (!in_array(md5($num . $string), $md5)) {
906
+ $output[] = $string;
907
+ }
908
+ }
909
+
910
+ return $output;
911
+ }
912
+
913
+ return false;
914
+ }
915
+
916
+
917
+ /**
918
+ * Prüfung der Dateien des aktuellen Theme
919
+ *
920
+ * @since 0.1
921
+ * @change 0.8
922
+ *
923
+ * @return array $results Array mit Ergebnissen
924
+ */
925
+
926
+ private static function check_theme_files()
927
+ {
928
+ /* Files vorhanden? */
929
+ if ( !$files = self::get_theme_files() ) {
930
+ return false;
931
+ }
932
+
933
+ /* Init */
934
+ $results = array();
935
+
936
+ /* Files loopen */
937
+ foreach($files as $file) {
938
+ if ($result = self::check_theme_file($file)) {
939
+ $results[$file] = $result;
940
+ }
941
+ }
942
+
943
+ /* Werte vorhanden? */
944
+ if ( !empty($results) ) {
945
+ return $results;
946
+ }
947
+
948
+ return false;
949
+ }
950
+
951
+
952
+ /**
953
+ * Prüfung einer Datei
954
+ *
955
+ * @since 0.1
956
+ * @change 0.8
957
+ *
958
+ * @param string $file Datei zur Prüfung
959
+ * @return array $results Array mit Ergebnissen
960
+ */
961
+
962
+ private static function check_theme_file($file)
963
+ {
964
+ /* Kein File? */
965
+ if ( !$file ) {
966
+ return false;
967
+ }
968
+
969
+ /* Inhalt auslesen */
970
+ if ( !$content = self::get_file_content($file) ) {
971
+ return false;
972
+ }
973
+
974
+ /* Init */
975
+ $results = array();
976
+
977
+ /* Zeilen loopen */
978
+ foreach($content as $num => $line) {
979
+ if ($result = self::check_file_line($line, $num)) {
980
+ $results[$num] = $result;
981
+ }
982
+ }
983
+
984
+ /* Werte vorhanden? */
985
+ if ( !empty($results) ) {
986
+ return $results;
987
+ }
988
+
989
+ return false;
990
+ }
991
+
992
+
993
+ /**
994
+ * Prüfung des Permalinks
995
+ *
996
+ * @since 0.1
997
+ * @change 0.8
998
+ *
999
+ * @return mixed $matches FALSE, wenn kein Fund
1000
+ */
1001
+
1002
+ private static function check_permalink_structure()
1003
+ {
1004
+ if ( $structure = get_option('permalink_structure') ) {
1005
+ /* Befehle suchen */
1006
+ preg_match_all(
1007
+ self::get_preg_match(),
1008
+ $structure,
1009
+ $matches
1010
+ );
1011
+
1012
+ /* Ergebnis speichern */
1013
+ if ( $matches[1] ) {
1014
+ return $matches[1];
1015
+ }
1016
+ }
1017
+
1018
+ return false;
1019
+ }
1020
+
1021
+
1022
+ /**
1023
+ * Prüfung der Admin-Seite
1024
+ *
1025
+ * @since 0.1
1026
+ * @change 0.8
1027
+ *
1028
+ * @param integer $page Gesuchte Seite
1029
+ * @return boolean TRUE, wenn die aktuelle auch die gesuchte Seite ist
1030
+ */
1031
+
1032
+ private static function is_current_page($page)
1033
+ {
1034
+ switch($page) {
1035
+ case 'home':
1036
+ return ( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'antivirus' );
1037
+
1038
+ case 'index':
1039
+ case 'plugins':
1040
+ return (!empty($GLOBALS['pagenow']) && $GLOBALS['pagenow'] == sprintf('%s.php', $page));
1041
+
1042
+ default:
1043
+ return false;
1044
+ }
1045
+ }
1046
+
1047
+
1048
+ /**
1049
+ * Anzeige des Dashboard-Hinweises
1050
+ *
1051
+ * @since 0.1
1052
+ * @change 1.2
1053
+ */
1054
+
1055
+ public static function show_dashboard_notice() {
1056
+ /* Kein Alert? */
1057
+ if ( !self::get_option('cronjob_alert') ) {
1058
+ return;
1059
+ }
1060
+
1061
+ /* Bereits in der Adminbar */
1062
+ if ( function_exists('is_admin_bar_showing') && is_admin_bar_showing() ) {
1063
+ return;
1064
+ }
1065
+
1066
+ /* Warnung */
1067
+ echo sprintf(
1068
+ '<div class="updated fade"><p><strong>%1$s:</strong> %2$s <a href="%3$s">%4$s &rarr;</a></p></div>',
1069
+ esc_html__('Virus suspected', 'antivirus'),
1070
+ esc_html__('The daily antivirus scan of your blog suggests alarm.', 'antivirus'),
1071
+ add_query_arg(
1072
+ array(
1073
+ 'page' => 'antivirus'
1074
+ ),
1075
+ admin_url('options-general.php')
1076
+ ),
1077
+ esc_html__('Manual scan', 'antivirus')
1078
+ );
1079
+ }
1080
+
1081
+
1082
+ /**
1083
+ * Anzeige des Menüs in der Adminbar
1084
+ *
1085
+ * @since 1.2
1086
+ * @change 1.2
1087
+ */
1088
+
1089
+ public static function add_adminbar_menu( $wp_admin_bar ) {
1090
+ /* Kein Alert? */
1091
+ if ( !self::get_option('cronjob_alert') ) {
1092
+ return;
1093
+ }
1094
+
1095
+ /* Keine Adminbar? */
1096
+ if ( !function_exists('is_admin_bar_showing') or !is_admin_bar_showing() ) {
1097
+ return;
1098
+ }
1099
+
1100
+ /* Hinzufügen */
1101
+ $wp_admin_bar->add_menu(
1102
+ array(
1103
+ 'id' => 'antivirus',
1104
+ 'title' => '<span class="ab-icon"></span><span class="ab-label">' .esc_html__('Virus suspected', 'antivirus'). '</span>',
1105
+ 'href' => add_query_arg(
1106
+ array(
1107
+ 'page' => 'antivirus'
1108
+ ),
1109
+ admin_url('options-general.php')
1110
+ )
1111
+ )
1112
+ );
1113
+ }
1114
+
1115
+
1116
+ /**
1117
+ * Anzeige der GUI
1118
+ *
1119
+ * @since 0.1
1120
+ * @change 1.2
1121
+ */
1122
+
1123
+ public static function show_admin_menu() {
1124
+ /* Updates speichern */
1125
+ if ( !empty($_POST) ) {
1126
+ /* Referer prüfen */
1127
+ check_admin_referer('antivirus');
1128
+
1129
+ /* Werte zuweisen */
1130
+ $options = array(
1131
+ 'cronjob_enable' => (int)(!empty($_POST['av_cronjob_enable'])),
1132
+ 'notify_email' => sanitize_email(@$_POST['av_notify_email'])
1133
+ );
1134
+
1135
+ /* Kein Cronjob? */
1136
+ if (empty($options['cronjob_enable'])) {
1137
+ $options['notify_email'] = '';
1138
+ }
1139
+
1140
+ /* Cron stoppen? */
1141
+ if ($options['cronjob_enable'] && !self::get_option('cronjob_enable')) {
1142
+ self::init_scheduled_hook();
1143
+ } else if (!$options['cronjob_enable'] && self::get_option('cronjob_enable')) {
1144
+ self::clear_scheduled_hook();
1145
+ }
1146
+
1147
+ /* Optionen speichern */
1148
+ self::update_options($options); ?>
1149
+
1150
+ <div id="message" class="updated fade">
1151
+ <p>
1152
+ <strong>
1153
+ <?php _e('Settings saved.') ?>
1154
+ </strong>
1155
+ </p>
1156
+ </div>
1157
+ <?php } ?>
1158
+
1159
+ <div class="wrap" id="av_main">
1160
+ <div class="icon32"></div>
1161
+
1162
+ <h2>
1163
+ AntiVirus
1164
+ </h2>
1165
+
1166
+ <form method="post" action="">
1167
+ <?php wp_nonce_field('antivirus') ?>
1168
+
1169
+ <div id="poststuff">
1170
+ <div class="postbox">
1171
+ <h3>
1172
+ <?php esc_html_e('Completed scan', 'antivirus') ?>
1173
+ </h3>
1174
+
1175
+ <div class="inside" id="av_completed">
1176
+ <div class="output">
1177
+ <div class="<?php echo (self::check_permalink_structure() ? 'danger' : 'done') ?>"><?php esc_html_e('Permalink back door check', 'antivirus') ?> <a href="<?php esc_html_e('http://mashable.com/2009/09/05/wordpress-attack/', 'antivirus') ?>" target="_blank">Info</a></div>
1178
+ </div>
1179
+
1180
+ <ul class="agenda">
1181
+ <li>
1182
+ <p></p>
1183
+ <span>
1184
+ <?php esc_html_e('All clear', 'antivirus') ?>
1185
+ </span>
1186
+ </li>
1187
+ <li class="danger">
1188
+ <p></p>
1189
+ <span>
1190
+ <?php esc_html_e('Danger', 'antivirus') ?>
1191
+ </span>
1192
+ </li>
1193
+ </ul>
1194
+ </div>
1195
+ </div>
1196
+
1197
+ <div class="postbox">
1198
+ <h3>
1199
+ <?php esc_html_e('Manual scan', 'antivirus') ?>
1200
+ </h3>
1201
+
1202
+ <div class="inside" id="av_manual">
1203
+ <p>
1204
+ <a href="#" class="button rbutton"><?php esc_html_e('Scan the theme templates now', 'antivirus') ?></a>
1205
+ <span class="alert"></span>
1206
+ </p>
1207
+ <div class="output"></div>
1208
+ </div>
1209
+ </div>
1210
+
1211
+ <div class="postbox">
1212
+ <h3>
1213
+ <?php _e('Settings') ?>
1214
+ </h3>
1215
+
1216
+ <div class="inside">
1217
+ <table class="form-table">
1218
+ <tr>
1219
+ <td>
1220
+ <label for="av_cronjob_enable">
1221
+ <input type="checkbox" name="av_cronjob_enable" id="av_cronjob_enable" value="1" <?php checked(self::get_option('cronjob_enable'), 1) ?> />
1222
+ <?php esc_html_e('Enable the daily antivirus scan', 'antivirus') ?>
1223
+ <?php if (self::get_option('cronjob_enable') && self::get_option('cronjob_timestamp')) {
1224
+ echo sprintf(
1225
+ '&nbsp;(%s @ %s)',
1226
+ esc_html__('Last check', 'antivirus'),
1227
+ date_i18n('d.m.Y H:i:s', (self::get_option('cronjob_timestamp') + get_option('gmt_offset') * 3600))
1228
+ );
1229
+ } ?>
1230
+ </label>
1231
+ <span class="shift">
1232
+ <?php esc_html_e('Alternate email address', 'antivirus') ?>:&nbsp;<input type="text" name="av_notify_email" value="<?php esc_attr_e(self::get_option('notify_email')) ?>" class="regular-text" />
1233
+ </span>
1234
+ </td>
1235
+ </tr>
1236
+ </table>
1237
+
1238
+ <p>
1239
+ <input type="submit" name="av_submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
1240
+ </p>
1241
+ </div>
1242
+ </div>
1243
+ </div>
1244
+ </form>
1245
+ </div>
1246
+ <?php }
1247
  }
1248
+
1249
+
1250
+ /* Fire */
1251
  add_action(
1252
+ 'plugins_loaded',
1253
+ array(
1254
+ 'AntiVirus',
1255
+ 'init'
1256
+ ),
1257
+ 99
1258
  );
1259
+
1260
+
1261
+ /* Install */
1262
  register_activation_hook(
1263
+ __FILE__,
1264
+ array(
1265
+ 'AntiVirus',
1266
+ 'install'
1267
+ )
1268
  );
1269
+
1270
+
1271
+ /* Uninstall */
1272
  register_uninstall_hook(
1273
+ __FILE__,
1274
+ array(
1275
+ 'AntiVirus',
1276
+ 'uninstall'
1277
+ )
1278
  );
css/style.css CHANGED
@@ -1 +1 @@
1
- #av_sidebar_icon{width:11px;height:9px;border:0;display:inline-block;background:url(../img/icon.png) no-repeat;}#wp-admin-bar-av_alert .ab-label{color:#e66f00;margin-left:4px;}#wp-admin-bar-av_alert .ab-icon{position:relative;float:left;width:16px;height:16px;margin-top:6px;background:url(../img/icon16.png) no-repeat 0 -1px;}div.icon32{background:url(../img/icon32.png) no-repeat;}div.postbox h3{cursor:default;}#poststuff>.postbox:first-child{margin-top:20px;}table.form-table{clear:none;width:auto;margin:0;}table.form-table #antivirus_cronjob_enable{margin:-3px 0 0;}table.form-table span.shift{display:block;margin:2px 0 0 18px;*margin-left:26px;}#av_completed{height:1%;overflow:hidden;}#av_completed .output{float:left;}#av_completed .output div{margin-top:8px;}#av_completed .output div a{margin:0 0 -1px 5px;padding:1px 4px 2px;font-size:10px;background:#FFF;text-decoration:none;border-radius:2px;-o-border-radius:2px;-ms-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}#av_completed .agenda{float:right;border:1px solid #dfdfdf;margin:4px 6px 0;padding:2px 5px 2px 6px;border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}#av_completed .agenda li{clear:both;height:1%;margin:0 !important;overflow:hidden;}#av_completed .agenda li p{float:left;width:10px;height:10px;margin:3px 3px 0 0 !important;background:green;border-radius:2px;-o-border-radius:2px;-ms-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}#av_completed .agenda li.danger p{background:red;}#av_completed .agenda li span{float:left;font-size:10px;}#av_manual{height:1%;overflow:hidden;}#av_manual a.button{float:left;}#av_manual .alert{float:left;color:green;margin:1px 10px 0;border:1px solid green;display:none;padding:2px 5px;border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}.inside .output{clear:both;height:1%;padding:0 0 6px;overflow:hidden;}.inside .output div{float:left;color:#FFF;margin:12px 6px 0;padding:8px 12px 10px;font-size:11px !important;background:orange;line-height:1.2em;border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;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;}.inside .output div.done{background:green;}.inside .output div.danger{width:97%;background:red;}.inside .output div p{padding:10px;overflow:hidden;background:#f9f9f9;white-space:nowrap;border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;}.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:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}.inside .output div p a:hover{color:#000;border:1px solid #646464;}.inside .output div p code{clear:both;float:left;color:#000;padding:2px 5px;border-radius:2px;-o-border-radius:2px;-o-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}.inside .output div p code span{padding:2px;background:yellow;}
1
+ #wp-admin-bar-antivirus .ab-label{color:#e66f00;margin-left:4px;}#wp-admin-bar-antivirus .ab-icon{float:left;width:16px;height:16px;position:relative;margin-top:5px;background:url(../img/warning@2x.png);background-size:100%;}#av_main .icon32{width:32px;height:32px;background:url('../img/icon@2x.png');background-size:100%;}#av_main .postbox h3{cursor:default;}#av_main #poststuff>.postbox:first-child{margin-top:10px;}#av_main table.form-table{clear:none;width:auto;margin:0;}#av_main table.form-table #antivirus_cronjob_enable{margin:-3px 0 0;}#av_main table.form-table span.shift{display:block;margin:2px 0 0 18px;*margin-left:26px;}#av_completed{height:1%;overflow:hidden;}#av_completed .output{float:left;}#av_completed .output div{margin-top:8px;}#av_completed .output div a{margin:0 0 -1px 5px;padding:1px 4px 2px;font-size:10px;background:#FFF;text-decoration:none;border-radius:2px;-o-border-radius:2px;-ms-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}#av_completed .agenda{float:right;border:1px solid #dfdfdf;margin:4px 6px 0;padding:2px 5px 2px 6px;border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}#av_completed .agenda li{clear:both;height:1%;margin:0 !important;overflow:hidden;}#av_completed .agenda li p{float:left;width:10px;height:10px;margin:3px 3px 0 0 !important;background:green;border-radius:2px;-o-border-radius:2px;-ms-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}#av_completed .agenda li.danger p{background:red;}#av_completed .agenda li span{float:left;font-size:10px;}#av_manual{height:1%;overflow:hidden;}#av_manual a.button{float:left;}#av_manual .alert{float:left;color:green;margin:1px 10px 0;border:1px solid green;display:none;padding:2px 5px;border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}#av_main .inside .output{clear:both;height:1%;padding:0 0 6px;overflow:hidden;}#av_main .inside .output div{float:left;color:#FFF;margin:12px 6px 0;padding:8px 12px 10px;font-size:11px !important;background:orange;line-height:1.2em;border-radius:8px;-o-border-radius:8px;-ms-border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;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:8px;-o-border-radius:8px;-ms-border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px;}#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:5px;-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;}#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:2px;-o-border-radius:2px;-o-border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;}#av_main .inside .output div p code span{padding:2px;background:yellow;}
css/{style.orginal.css → style.dev.css} RENAMED
@@ -1,29 +1,17 @@
1
- /* @group Sidebar */
2
-
3
- #av_sidebar_icon {
4
- width: 11px;
5
- height: 9px;
6
- border: 0;
7
- display: inline-block;
8
- background: url(../img/icon.png) no-repeat;
9
- }
10
-
11
- /* @end group */
12
-
13
-
14
  /* @group Adminbar */
15
 
16
- #wp-admin-bar-av_alert .ab-label {
17
  color: #E66F00;
18
  margin-left: 4px;
19
  }
20
- #wp-admin-bar-av_alert .ab-icon {
21
- position: relative;
22
  float: left;
23
  width: 16px;
24
  height: 16px;
25
- margin-top: 6px;
26
- background: url(../img/icon16.png) no-repeat 0 -1px;
 
 
27
  }
28
 
29
  /* @end group */
@@ -31,14 +19,17 @@
31
 
32
  /* @group GUI */
33
 
34
- div.icon32 {
35
- background: url(../img/icon32.png) no-repeat;
 
 
 
36
  }
37
- div.postbox h3 {
38
  cursor: default;
39
  }
40
- #poststuff > .postbox:first-child {
41
- margin-top: 20px;
42
  }
43
 
44
  /* @end group */
@@ -46,15 +37,15 @@ div.postbox h3 {
46
 
47
  /* @group Tabelle */
48
 
49
- table.form-table {
50
  clear: none;
51
  width: auto;
52
  margin: 0;
53
  }
54
- table.form-table #antivirus_cronjob_enable {
55
  margin: -3px 0 0;
56
  }
57
- table.form-table span.shift {
58
  display: block;
59
  margin: 2px 0 0 18px;
60
  *margin-left: 26px;
@@ -154,13 +145,13 @@ table.form-table span.shift {
154
  -webkit-border-radius: 5px;
155
  }
156
 
157
- .inside .output {
158
  clear: both;
159
  height: 1%;
160
  padding: 0 0 6px;
161
  overflow: hidden;
162
  }
163
- .inside .output div {
164
  float: left;
165
  color: #FFF;
166
  margin: 12px 6px 0;
@@ -181,14 +172,14 @@ table.form-table span.shift {
181
  -moz-transition: background-color 0.5s linear;
182
  -webkit-transition: background-color 0.5s linear;
183
  }
184
- .inside .output div.done {
185
  background: green;
186
  }
187
- .inside .output div.danger {
188
  width: 97%;
189
  background: red;
190
  }
191
- .inside .output div p {
192
  padding: 10px;
193
  overflow: hidden;
194
  background: #F9F9F9;
@@ -200,7 +191,7 @@ table.form-table span.shift {
200
  -moz-border-radius: 8px;
201
  -webkit-border-radius: 8px;
202
  }
203
- .inside .output div p a {
204
  float: left;
205
  color: #646464;
206
  margin: 0 6px 12px 0;
@@ -216,11 +207,11 @@ table.form-table span.shift {
216
  -moz-border-radius: 5px;
217
  -webkit-border-radius: 5px;
218
  }
219
- .inside .output div p a:hover {
220
  color: #000;
221
  border: 1px solid #646464;
222
  }
223
- .inside .output div p code {
224
  clear: both;
225
  float: left;
226
  color: #000;
@@ -232,7 +223,7 @@ table.form-table span.shift {
232
  -moz-border-radius: 2px;
233
  -webkit-border-radius: 2px;
234
  }
235
- .inside .output div p code span {
236
  padding: 2px;
237
  background: yellow;
238
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /* @group Adminbar */
2
 
3
+ #wp-admin-bar-antivirus .ab-label {
4
  color: #E66F00;
5
  margin-left: 4px;
6
  }
7
+ #wp-admin-bar-antivirus .ab-icon {
 
8
  float: left;
9
  width: 16px;
10
  height: 16px;
11
+ position: relative;
12
+ margin-top: 5px;
13
+ background: url(../img/warning@2x.png);
14
+ background-size: 100%;
15
  }
16
 
17
  /* @end group */
19
 
20
  /* @group GUI */
21
 
22
+ #av_main .icon32 {
23
+ width: 32px;
24
+ height: 32px;
25
+ background: url('../img/icon@2x.png');
26
+ background-size: 100%;
27
  }
28
+ #av_main .postbox h3 {
29
  cursor: default;
30
  }
31
+ #av_main #poststuff > .postbox:first-child {
32
+ margin-top: 10px;
33
  }
34
 
35
  /* @end group */
37
 
38
  /* @group Tabelle */
39
 
40
+ #av_main table.form-table {
41
  clear: none;
42
  width: auto;
43
  margin: 0;
44
  }
45
+ #av_main table.form-table #antivirus_cronjob_enable {
46
  margin: -3px 0 0;
47
  }
48
+ #av_main table.form-table span.shift {
49
  display: block;
50
  margin: 2px 0 0 18px;
51
  *margin-left: 26px;
145
  -webkit-border-radius: 5px;
146
  }
147
 
148
+ #av_main .inside .output {
149
  clear: both;
150
  height: 1%;
151
  padding: 0 0 6px;
152
  overflow: hidden;
153
  }
154
+ #av_main .inside .output div {
155
  float: left;
156
  color: #FFF;
157
  margin: 12px 6px 0;
172
  -moz-transition: background-color 0.5s linear;
173
  -webkit-transition: background-color 0.5s linear;
174
  }
175
+ #av_main .inside .output div.done {
176
  background: green;
177
  }
178
+ #av_main .inside .output div.danger {
179
  width: 97%;
180
  background: red;
181
  }
182
+ #av_main .inside .output div p {
183
  padding: 10px;
184
  overflow: hidden;
185
  background: #F9F9F9;
191
  -moz-border-radius: 8px;
192
  -webkit-border-radius: 8px;
193
  }
194
+ #av_main .inside .output div p a {
195
  float: left;
196
  color: #646464;
197
  margin: 0 6px 12px 0;
207
  -moz-border-radius: 5px;
208
  -webkit-border-radius: 5px;
209
  }
210
+ #av_main .inside .output div p a:hover {
211
  color: #000;
212
  border: 1px solid #646464;
213
  }
214
+ #av_main .inside .output div p code {
215
  clear: both;
216
  float: left;
217
  color: #000;
223
  -moz-border-radius: 2px;
224
  -webkit-border-radius: 2px;
225
  }
226
+ #av_main .inside .output div p code span {
227
  padding: 2px;
228
  background: yellow;
229
  }
img/icon.png DELETED
Binary file
img/icon16.png DELETED
Binary file
img/icon32.png DELETED
Binary file
img/icon@2x.png ADDED
Binary file
img/warning@2x.png ADDED
Binary file
readme.txt CHANGED
@@ -1,37 +1,57 @@
1
  === AntiVirus ===
2
  Contributors: sergej.mueller
3
- Tags: antivirus, virus, antispam, spam, scanner, malware
4
- Donate link: http://flattr.com/profile/sergej.mueller
5
  Requires at least: 2.8
6
- Tested up to: 3.3
7
  Stable tag: trunk
8
 
9
- AntiVirus for WordPress is a smart and effective solution to protect your blog against exploits and spam injections.
10
 
11
 
12
- == Description ==
13
- *AntiVirus for WordPress* is a smart and effective solution to protect your blog against exploits and spam injections. Malware protection for your blog.
14
 
15
 
16
- = Features =
17
- * [NEW] Virus alert in the admin bar
18
- * WordPress 3.x ready: Design as well as technical
19
- * Detect the [WordPress permalink back door](http://mashable.com/2009/09/05/wordpress-attack/ "WordPress permalink back door")
20
- * Quick & Dirty: activate, check, done!
21
- * Manual testing with immediate result of the infected files
22
- * Daily automatic check with email notification
23
- * Whitelist: Mark the suspicion as "No virus"
24
- * Clean up after uninstall the plugin
25
- * English, German, Italian, Persian, Russian
26
 
 
27
 
28
- = Related Links =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  * [Google+](https://plus.google.com/110569673423509816572 "Google+")
30
- * [Plugin page](http://wpantivirus.com "WordPress Antivirus Plugin")
31
- * [Other plugins](http://wordpress.org/extend/plugins/profile/sergejmueller "Other plugins")
 
32
 
33
 
34
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
35
  = 1.2 =
36
  * "Virus suspected" alert in the admin bar
37
  * Fix for the manual scan link on dashboard
@@ -89,16 +109,7 @@ AntiVirus for WordPress is a smart and effective solution to protect your blog a
89
  * AntiVirus for WordPress goes online
90
 
91
 
92
- == Screenshots ==
93
-
94
- 1. WordPress AntiVirus settings
95
 
 
96
 
97
- == Installation ==
98
- 1. Download *AntiVirus* plugin
99
- 1. Unzip the archive
100
- 1. Upload the folder *antivirus* into *../wp-content/plugins/*
101
- 1. Go to tab *Plugins*
102
- 1. Activate *AntiVirus*
103
- 1. Edit settings
104
- 1. Ready
1
  === AntiVirus ===
2
  Contributors: sergej.mueller
3
+ Tags: antivirus, malware, scanner
4
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RDDW9FEHGLG6
5
  Requires at least: 2.8
6
+ Tested up to: 3.4
7
  Stable tag: trunk
8
 
 
9
 
10
 
11
+ Useful plugin that will scan your theme templates for malicious injections. Automatically. Every day. For more blog security.
 
12
 
13
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ == Description ==
16
 
17
+ = Scan & Notify =
18
+ *AntiVirus for WordPress* is a easy and safe tool to protect your blog install against exploits, malware and spam injections. Scan your templates now!
19
+
20
+ = Features =
21
+ * Virus alert in the admin bar
22
+ * Cleaning up after plugin removal
23
+ * Translations into many languages​​
24
+ * Daily scan with email notifications
25
+ * Database tables and theme templates checks
26
+ * WordPress 3.x ready: both visually and technically
27
+ * Whitelist solution: Mark suspected cases as "no virus"
28
+ * Manual check of template files with alerts on suspected cases
29
+
30
+ = Requirements =
31
+ * PHP 5.1
32
+ * WordPress 2.8
33
+
34
+ = Documentation =
35
+ * [Sicherheit: AntiVirus für WordPress](http://playground.ebiene.de/antivirus-wordpress-plugin/ "AntiVirus für WordPress") (DE)
36
+
37
+ = Author =
38
  * [Google+](https://plus.google.com/110569673423509816572 "Google+")
39
+ * [Plugins](http://wpcoder.de "Plugins")
40
+ * [Portfolio](http://ebiene.de "Portfolio")
41
+
42
 
43
 
44
  == Changelog ==
45
+
46
+ = 1.3.1 =
47
+ * Compatibility with WordPress 3.4
48
+ * High-resolution plugin icon for retina displays
49
+ * Remove icon from the admin sidebar
50
+ * System requirements: From PHP 5.0 to PHP 5.1
51
+
52
+ = 1.3 =
53
+ * Xmas Edition
54
+
55
  = 1.2 =
56
  * "Virus suspected" alert in the admin bar
57
  * Fix for the manual scan link on dashboard
109
  * AntiVirus for WordPress goes online
110
 
111
 
 
 
 
112
 
113
+ == Screenshots ==
114
 
115
+ 1. WordPress AntiVirus settings
 
 
 
 
 
 
 
screenshot-1.png CHANGED
Binary file