File Coverage

blib/lib/Parse/Nessus/Plugin.pm
Criterion Covered Total %
statement 6 392 1.5
branch 0 210 0.0
condition 0 171 0.0
subroutine 2 26 7.6
pod 19 24 79.1
total 27 823 3.2


line stmt bran cond sub pod time code
1             #
2             # OO methods to parse Nessus plugins
3             #
4             # Author: Roberto Alamos Moreno
5             #
6             # Copyright (c) 2005 Roberto Alamos Moreno. All rights reserved.
7             # This program is free software; you can redistribute it and/or
8             # modify it under the same terms as Perl itself.
9             #
10             # June 2005. Antofagasta, Chile.
11             #
12             package Parse::Nessus::Plugin;
13              
14             require 5.004;
15              
16             $VERSION = '0.4';
17              
18 1     1   12729 use strict;
  1         3  
  1         45  
19 1     1   6 use warnings;
  1         1  
  1         4552  
20              
21             =head1 NAME
22              
23             Parse::Nessus::Plugin - OO methods to parse Nessus plugins
24              
25             =head1 SYNOPSIS
26              
27             use Parse::Nessus::Plugin;
28              
29             $plugin = Parse::Nessus::Plugin->new || undef;
30             if(!$plugin) {
31             die("It wasn't posible to initialize parser");
32             }
33              
34             $plugin->parse_file($nasl_file); # Parse from a filename
35             $plugin->parse_string($nasl_string); # Parse from a string
36              
37             $plugin->description; # Get description
38             $plugin->solution; # Get solution
39              
40              
41             =head1 DESCRIPTION
42              
43             Parse::Nessus::Plugin provides OO methods that easily parse Nessus plugins written in NASL. With this
44             module you can get the script id, solution, description, risk factor and many other information in your
45             NASL plugin with a simple call to an OO method.
46              
47             =cut
48              
49             =head1 METHODS
50              
51             =over 4
52              
53             =item Method B
54              
55             Usage :
56              
57             my $plugin = Parse::Nessus::Plugin->new;
58              
59             This method returns an instance of the Parse::Nessus::Plugin class.
60              
61             =cut
62             sub new {
63 0   0 0 1   my $class = shift || undef;
64 0 0         if(!defined $class) {
65 0           return undef;
66             }
67              
68 0           my $objref = { RAWERROR => '',
69             ERROR => '',
70             NASL => 1, # By now we only allow .nasl files
71             FILE => '',
72             FILENAME => '',
73             PLUGIN_ID => '',
74             };
75 0           bless $objref, $class;
76              
77 0           return $objref;
78             }
79              
80             =item Method B
81              
82             Usage :
83              
84             $plugin->parse_file($nasl_filename);
85              
86             This method tells Parse::Nessus::Plugin to be ready to parse $nasl_filename, where $nasl_filename is the path to the
87             .nasl plugin (for example /usr/nessus/cifs445.nasl). If this method returns true, then you can continue with the parsing,
88             otherwise, the argument given wasn't a valid .nasl plugin.
89              
90             =cut
91             sub parse_file {
92 0   0 0 1   my $self = shift || undef;
93 0 0         if(!$self) {
94 0           return undef;
95             }
96              
97 0           $self->clean;
98 0           $self->cleanfilename;
99              
100 0   0       my $namefile = shift || undef;
101 0 0         if(!$namefile) {
102 0           $self->error('NO_FILE');
103 0           return undef;
104             }
105              
106 0           $self->filename($namefile);
107              
108 0           my $file = '';
109             # Open file
110 0 0         if(open(FILE,$namefile)) {
111 0           while(my $line = ) {
112 0           $file .= $line;
113             }
114 0           close(FILE);
115             } else {
116 0           $self->error('NO_FILE');
117 0           return undef;
118             }
119              
120 0 0         if($file eq '') {
121 0           $self->error('NO_FILE');
122 0           return undef;
123             }
124              
125 0           return $self->parse_string($file);
126             }
127              
128             =item Method B
129              
130             Usage :
131              
132             $plugin->parse_string($nasl_string);
133              
134             This method tells Parse::Nessus::Plugin to be ready to parse $nasl_string, where $nasl_string is a SCALAR variable
135             that contains the code of a Nessus plugin written in NASL. If this method returns true, then you can continue with the parsing,
136             otherwise, the string given as argument isn't a valid .nasl plugin.
137              
138             =cut
139             sub parse_string {
140 0   0 0 1   my $self = shift || undef;
141 0 0         if(!$self) {
142 0           return undef;
143             }
144              
145 0           $self->clean;
146              
147 0   0       my $string = shift || undef;
148 0 0 0       if(!$string || $string eq '') {
149 0           return undef;
150             }
151              
152             # We'll to determine if we have a .nasl or .c plugin
153             # Check if we have a script id
154 0 0         if($string =~ /script\_id\(([^\)]*)\);/) {
    0          
155 0           my $id = $1;
156 0           $id =~ s/\D//go;
157 0 0 0       if(!$id || $id eq '') {
158 0           $self->error('NO_NESSUS_PLUGIN');
159 0           return undef;
160             }
161 0           $self->id($id);
162 0           $self->is_nasl(1);
163             } elsif($string =~ /plug\_set\_id\(([^\,]*),([^\)]*)\)/) {
164 0           my $id = $2;
165 0           $id =~ s/\D//go;
166 0 0 0       if(!$id || $id eq '') {
167 0           $self->error('NO_NESSUS_PLUGIN');
168 0           return undef;
169             }
170 0           $self->id($id);
171 0           $self->is_nasl(0);
172             } else {
173 0           $self->error('NO_NESSUS_PLUGIN');
174 0           return undef;
175             }
176            
177 0           $self->{FILE} = $string;
178              
179 0           return 1;
180             }
181              
182             =item Method B
183              
184             Usage :
185              
186             my $id = $plugin->id;
187              
188             This method returns the plugin id of the last plugin processed with parse_file or parse_string, as SCALAR variable.
189              
190             =cut
191             sub id {
192 0   0 0 1   my $self = shift || undef;
193 0 0         if(!$self) {
194 0           return undef;
195             }
196              
197 0           $self->cleanerror;
198              
199 0 0         if(@_) {
200 0           $self->{PLUGIN_ID} = shift @_;
201             } else {
202 0 0 0       if(exists $self->{PLUGIN_ID} && $self->{PLUGIN_ID} ne '') {
203 0           return $self->{PLUGIN_ID};
204             } else {
205 0           return undef;
206             }
207             }
208             }
209              
210             =item Method B
211              
212             Usage :
213              
214             my $filename = $plugin->filename;
215              
216             This method returns the name of the plugin's file (only if you used B method).
217              
218             =cut
219             sub filename {
220 0   0 0 1   my $self = shift || undef;
221 0 0         if(!$self) {
222 0           return undef;
223             }
224              
225 0           $self->cleanerror;
226              
227 0 0         if(@_) {
228 0           my $filename = shift @_;
229 0           $filename =~ /([^\/]*)$/;
230 0           $self->{FILENAME} = $1;
231             } else {
232 0 0 0       if(exists $self->{FILENAME} && $self->{FILENAME} ne '') {
233 0           return $self->{FILENAME};
234             } else {
235 0           return undef;
236             }
237             }
238             }
239              
240             =item Method B
241              
242             Usage :
243              
244             my @cve = $plugin->cve;
245              
246             This method returns the list of CVE names associated with the current plugin.
247              
248             =cut
249             sub cve {
250 0   0 0 1   my $self = shift || undef;
251 0 0         if(!$self) {
252 0           return undef;
253             }
254              
255 0           $self->cleanerror;
256              
257 0   0       my $file = $self->{FILE} || undef;
258 0 0 0       if(!$file || $file eq '') {
259 0           $self->error('NO_FILE');
260 0           return undef;
261             }
262              
263 0 0         if($file =~ /script\_cve\_id\(\"([^\)]*)\"\)/o) {
264 0           my $cve = $1;
265 0           $cve =~ s/\"//g;$cve =~ s/\s//g;
  0            
266 0 0 0       if(my $cve || $cve eq '') {
267 0           $self->error('NO_CVE');
268 0           return undef;
269             }
270 0           my @cve = split(/,/,$cve);
271 0           return \@cve;
272             } else {
273 0           $self->error('NO_CVE');
274 0           return undef;
275             }
276             }
277              
278             =item Method B
279              
280             Usage :
281              
282             my @bugtraq = $plugin->bugtraq;
283              
284             This method returns the list of bugtraq ids associated with the current plugin.
285              
286             =cut
287             sub bugtraq {
288 0   0 0 1   my $self = shift || undef;
289 0 0         if(!$self) {
290 0           return undef;
291             }
292              
293 0           $self->cleanerror;
294              
295 0   0       my $file = $self->{FILE} || undef;
296 0 0 0       if(!$file || $file eq '') {
297 0           $self->error('NO_FILE');
298 0           return undef;
299             }
300              
301 0 0         if($file =~ /script\_bugtraq\_id\(([^\)]*)\)/o) {
302 0           my $bid = $1;
303 0           $bid =~ s/\s//go;
304 0 0 0       if(!$bid || $bid eq '') {
305 0           $self->error('NO_BUGTRAQID');
306 0           return undef;
307             }
308 0           my @bid = split(/,/,$bid);
309 0           return \@bid;
310             } else {
311 0           $self->error('NO_BUGTRAQID');
312 0           return undef;
313             }
314             }
315              
316             =item Method B
317              
318             Usage :
319              
320             my $version = $plugin->version;
321              
322             This method returns the version of the current plugin.
323              
324             =cut
325             sub version {
326 0   0 0 1   my $self = shift || undef;
327 0 0         if(!$self) {
328 0           return undef;
329             }
330              
331 0           $self->cleanerror;
332              
333 0   0       my $file = $self->{FILE} || undef;
334 0 0 0       if(!$file || $file eq '') {
335 0           $self->error('NO_FILE');
336 0           return undef;
337             }
338              
339 0 0         if($file =~ /script\_version\s*\(\s*(\"|\')([^\1\)]*)\1\s*\)\s*\;/mo) {
340 0           my $version = $2;
341 0           $version =~ s/\$//go;
342 0 0 0       if(!$version || $version eq '') {
343 0           $self->error('NO_VERSION');
344 0           return undef;
345             }
346 0           return $version;
347             } else {
348 0           $self->error('NO_VERSION');
349 0           return undef;
350             }
351             }
352              
353             =item Method B
354              
355             Usage :
356              
357             my $name = $plugin->name;
358              
359             This method returns the name of the current plugin.
360              
361             =cut
362             sub name {
363 0   0 0 1   my $self = shift || undef;
364 0 0         if(!$self) {
365 0           return undef;
366             }
367              
368 0           $self->cleanerror;
369              
370 0   0       my $file = $self->{FILE} || undef;
371 0 0 0       if(!$file || $file eq '') {
372 0           $self->error('NO_FILE');
373 0           return undef;
374             }
375              
376 0 0         if($file =~ /name\[\"english\"\]\s*\=\s*\"([^\"]*)\"\s*\;/mo) {
    0          
377 0           my $name = $1;
378 0           $name =~ s/\'//go;
379 0 0 0       if(!$name || $name eq '') {
380 0           $self->error('NO_NAME');
381 0           return undef;
382             }
383 0           return $name;
384             } elsif($file =~ /script\_name\s*\(.*english\:\s*\"([^\"]*)\"\s*,?/mo) {
385 0           my $name = $1;
386 0           $name =~ s/\'//go;
387 0 0 0       if(!$name || $name eq '') {
388 0           $self->error('NO_NAME');
389 0           return undef;
390             }
391 0           return $name;
392             } else {
393 0           $self->error('NO_NAME');
394 0           return undef;
395             }
396             }
397              
398             =item Method B
399              
400             Usage :
401              
402             my $summary = $plugin->summary;
403              
404             This method returns the summary of the current plugin.
405              
406             =cut
407             sub summary {
408 0   0 0 1   my $self = shift || undef;
409 0 0         if(!$self) {
410 0           return undef;
411             }
412              
413 0           $self->cleanerror;
414              
415 0   0       my $file = $self->{FILE} || undef;
416 0 0 0       if(!$file || $file eq '') {
417 0           $self->error('NO_FILE');
418 0           return undef;
419             }
420              
421 0 0         if($file =~ /summary\[\"english\"\]\s*\=\s*\"([^\"]*)\"\s*\;/mo) {
    0          
422 0           my $summary = $1;
423 0 0 0       if(!$summary || $summary eq '') {
424 0           $self->error('NO_SUMMARY');
425 0           return undef;
426             }
427 0           return $summary;
428             } elsif($file =~ /script\_summary\s*\(.*english\:\s*\"([^\"]*)\"\s*,?/mo) {
429 0           my $summary = $1;
430 0 0 0       if(!$summary || $summary eq '') {
431 0           $self->error('NO_SUMMARY');
432 0           return undef;
433             }
434 0           return $summary;
435             } else {
436 0           $self->error('NO_SUMMARY');
437 0           return undef;
438             }
439             }
440              
441             =item Method B
442              
443             Usage :
444              
445             my $description = $plugin->description;
446              
447             This method returns the description of the current plugin. Attention: JUST the description. Other data
448             as solution, risk factor, etc. can be reached via their own methods.
449              
450             =cut
451             sub description {
452 0   0 0 1   my $self = shift || undef;
453 0 0         if(!$self) {
454 0           return undef;
455             }
456              
457 0           $self->cleanerror;
458              
459 0   0       my $file = $self->{FILE} || undef;
460 0 0 0       if(!$file || $file eq '') {
461 0           $self->error('NO_FILE');
462 0           return undef;
463             }
464              
465 0           my $desc = '';
466 0 0         if($file =~ /desc\[\"english\"\]\s*\=\s*\'\s*([^\']*)\'\s*\;/so) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
467 0           $desc = $1;
468             } elsif ($file =~ /desc\[\"english\"\]\s*\=\s*\"\s*([^\"]*)\"\s*\;/so) {
469 0           $desc = $1;
470             } elsif ($file =~ /desc\[\"english\"\]\s*\=\s*string\s*\(\s*\"\s*([^\)]*)\"\s*\)\s*\;/so) {
471 0           $desc = $1;
472             } elsif ($file =~ /desc\[\"english\"\]\s*\=\s*string\s*\(\s*\"\s*([^\)]*)\"\s*\)\s*\;/so) {
473 0           $desc = $1;
474             } elsif ($file =~ /desc\s*\=\s*string\s*\(\s*\"\s*([^\)]*)\"\s*\)\s*\;/so) {
475 0           $desc = $1;
476             } elsif ($file =~ /desc\s*\=\s*string\s*\(\s*\'\s*([^\)]*)\'\s*\)\s*\;/so) {
477 0           $desc = $1;
478             } elsif ($file =~ /desc\s*\=\s*\"\s*([^\"]*)\"\s*\;/so) {
479 0           $desc = $1;
480             } elsif ($file =~ /desc\s*\=\s*\'\s*([^\']*)\'\s*\;/so) {
481 0           $desc = $1;
482             } elsif ($file =~ /script\_description\s*\(.*english\:\s*string\s*\(\s*\"\s*([^\"\)]*)\"\s*\),?/so) {
483 0           $desc = $1;
484             } elsif ($file =~ /script\_description\s*\(.*english\:\s*string\s*\(\s*\'\s*([^\'\)]*)\'\s*\),?/so) {
485 0           $desc = $1;
486             } elsif ($file =~ /script\_description\s*\(\s*english\:\s*[^\"]*\"\s*([^\"\)]*)\"\s*,?/sxo) {
487 0           $desc = $1;
488             } elsif ($file =~ /script\_description\s*\(\s*english\:\s*[^\']*\'\s*([^\'\)]*)\'\s*,?/sxo) {
489 0           $desc = $1;
490             } else {
491 0           $self->error('NO_DESCRIPTION');
492 0           return undef;
493             }
494              
495             # Check if we get something
496 0 0         if($desc eq '') {
497 0           $self->error('NO_DESCRIPTION');
498 0           return undef;
499             }
500              
501 0 0         if($desc =~ /\bSolutions?\s*:\s*/sio) {
502 0           $desc =~ s/Solutions?\s*:\s*.*//sio;
503             }
504 0 0         if($desc =~ /\bSee also\s*:\s*/sio) {
505 0           $desc =~ s/See also\s*:\s*.*//sio;
506             }
507 0 0         if($desc =~ /\bRisk Factor\s*:\s*/sio) {
    0          
508 0           $desc =~ s/Risk Factor\s*:\s*.*//sio;
509             } elsif($desc =~ /\bRisk\s*:\s*/sio) {
510 0           $desc =~ s/Risk\s*:\s*.*//sio;
511             }
512 0           $desc =~ s/^\s*//o;
513 0           $desc =~ s/\s*$//o;
514 0           $desc =~ s/\"$//go;
515 0           $desc =~ s/^\"//go;
516 0           $desc =~ s/;$//go;
517              
518 0           return $desc;
519             }
520              
521             =item Method B
522              
523             Usage :
524              
525             my $solution = $plugin->solution;
526              
527             This method returns the solution of the current plugin.
528              
529             =cut
530             sub solution {
531 0   0 0 1   my $self = shift || undef;
532 0 0         if(!$self) {
533 0           return undef;
534             }
535              
536 0           $self->cleanerror;
537              
538 0   0       my $file = $self->{FILE} || undef;
539 0 0 0       if(!$file || $file eq '') {
540 0           $self->error('NO_FILE');
541 0           return undef;
542             }
543              
544 0           my $sol = '';
545 0 0         if($file =~ /\bSolutions?\s*:\s*([^\"]*)\"\s*\)?\s*\;/sio) {
    0          
546 0           $sol = $1;
547             } elsif($file =~ /\bSolutions?\s*:\s*([^\']*)\'\s*\)?\s*\;/sio) {
548 0           $sol = $1;
549             } else {
550 0           $self->error('NO_SOLUTION');
551 0           return undef;
552             }
553              
554             # Check if we have something
555 0 0         if($sol eq '') {
556 0           $self->error('NO_SOLUTION');
557 0           return undef;
558             }
559              
560 0 0         if($sol =~ /\bSee also\s*:\s*/sio) {
561 0           $sol =~ s/See also\s*:\s*.*//sio;
562             }
563 0 0         if($sol =~ /\bRisk Factor\s*:\s*/sio) {
    0          
564 0           $sol =~ s/Risk Factor\s*:\s*.*//sio;
565             } elsif($sol =~ /\bRisk\s*:\s*/sio) {
566 0           $sol =~ s/Risk\s*:\s*.*//sio;
567             }
568 0           $sol =~ s/^\s*//o;
569 0           $sol =~ s/\s*$//o;
570 0           $sol =~ s/\"$//go;
571 0           $sol =~ s/^\"//go;
572 0           $sol =~ s/;$//go;
573              
574 0           return $sol;
575             }
576              
577             =item Method B
578              
579             Usage :
580              
581             my $risk = $plugin->risk;
582              
583             This method returns the risk factor of the current plugin.
584              
585             =cut
586             sub risk {
587 0   0 0 1   my $self = shift || undef;
588 0 0         if(!$self) {
589 0           return undef;
590             }
591              
592 0           $self->cleanerror;
593              
594 0   0       my $file = $self->{FILE} || undef;
595 0 0 0       if(!$file || $file eq '') {
596 0           $self->error('NO_FILE');
597 0           return undef;
598             }
599              
600 0           my $risk = '';
601 0 0         if($file =~ /\bRisk Factor\s*:\s*(critical|high|serious|medium|low|none)/mio) {
    0          
602 0           $risk = $1;
603             } elsif($file =~ /\bRisk\s*:\s*(critical|high|serious|medium|low|none)/mio) {
604 0           $risk = $1;
605             } else {
606 0           $self->error('NO_RISK');
607 0           return undef;
608             }
609              
610              
611             # Check if we have something
612 0 0         if($risk eq '') {
613 0           $self->error('NO_RISK');
614 0           return undef;
615             }
616              
617 0           return $risk;
618             }
619              
620             =item Method B
621              
622             Usage :
623              
624             my $family = $plugin->family;
625              
626             This method returns the family of the current plugin.
627              
628             =cut
629             sub family {
630 0   0 0 1   my $self = shift || undef;
631 0 0         if(!$self) {
632 0           return undef;
633             }
634              
635 0           $self->cleanerror;
636              
637 0   0       my $file = $self->{FILE} || undef;
638 0 0 0       if(!$file || $file eq '') {
639 0           $self->error('NO_FILE');
640 0           return undef;
641             }
642              
643 0           my $family = '';
644 0 0         if($file =~ /family\[\"english\"\]\s*\=\s*\"([^\"]*)\"\s*\;/mo) {
    0          
645 0           $family = $1;
646             } elsif ($file =~ /script\_family\s*\(.*english\:\s*\"([^\"]*)\"\s*,?/mo) {
647 0           $family = $1;
648             } else {
649 0           $self->error('NO_FAMILY');
650 0           return undef;
651             }
652              
653             # Check if we have something
654 0 0         if($family eq '') {
655 0           $self->error('NO_FAMILY');
656 0           return undef;
657             }
658              
659 0           $family =~ s/\'//go;
660 0           $family =~ s/^\s*//o;
661 0           $family =~ s/\s*$//o;
662 0           $family =~ s/\"$//go;
663 0           $family =~ s/^\"//go;
664 0           $family =~ s/;$//go;
665              
666 0           return $family;
667             }
668              
669             =item Method B
670              
671             Usage :
672              
673             my $category = $plugin->category;
674              
675             This method returns the category of the current plugin.
676              
677             =cut
678             sub category {
679 0   0 0 1   my $self = shift || undef;
680 0 0         if(!$self) {
681 0           return undef;
682             }
683              
684 0           $self->cleanerror;
685              
686 0   0       my $file = $self->{FILE} || undef;
687 0 0 0       if(!$file || $file eq '') {
688 0           $self->error('NO_FILE');
689 0           return undef;
690             }
691              
692 0 0         if($file =~ /script\_category\s*\((ACT\_(INIT|SCANNER|SETTINGS|GATHER\_INFO|ATTACK|MIXED\_ATTACK|DESTRUCTIVE\_ATTACK|DENIAL|KILL\_HOST))\)/mo) {
693 0           my $categ = $1;
694 0 0 0       if(!$categ || $categ eq '') {
695 0           $self->error('NO_CATEGORY');
696 0           return undef;
697             }
698 0           return $categ;
699             } else {
700 0           $self->error('NO_CATEGORY');
701 0           return undef;
702             }
703             }
704              
705             =item Method B
706              
707             Usage :
708              
709             my $copyright = $plugin->copyright;
710              
711             This method returns the copyright of the current plugin.
712              
713             =cut
714             sub copyright {
715 0   0 0 1   my $self = shift || undef;
716 0 0         if(!$self) {
717 0           return undef;
718             }
719              
720 0           $self->cleanerror;
721              
722 0   0       my $file = $self->{FILE} || undef;
723 0 0 0       if(!$file || $file eq '') {
724 0           $self->error('NO_FILE');
725 0           return undef;
726             }
727              
728 0 0         if($file =~ /script\_copyright\s*\([^\"]*\"([^\"]*)\"/mo) {
729 0           my $cright = $1;
730 0 0 0       if(!$cright || $cright eq '') {
731 0           $self->error('NO_COPYRIGHT');
732 0           return undef;
733             }
734 0           return $cright;
735             } else {
736 0           $self->error('NO_COPYRIGHT');
737 0           return undef;
738             }
739             }
740              
741             sub is_nasl {
742 0   0 0 0   my $self = shift || undef;
743 0 0         if(!$self) {
744 0           return undef;
745             }
746              
747 0           $self->cleanerror;
748              
749 0 0         if(@_) {
750 0           $self->{NASL} = shift @_;
751             } else {
752 0 0 0       if(exists $self->{NASL} && $self->{NASL} != 0) {
753 0           return $self->{NASL};
754             } else {
755 0           return 0;
756             }
757             }
758             }
759              
760             =item Method B
761              
762             Usage :
763              
764             my $is_fs = $plugin->register_service;
765              
766             This method returns True if the plugin registers a service or False if it doesn't
767              
768             =cut
769             sub register_service {
770 0   0 0 1   my $self = shift || undef;
771 0 0         if(!$self) {
772 0           return undef;
773             }
774              
775 0           $self->cleanerror;
776              
777 0   0       my $file = $self->{FILE} || undef;
778 0 0 0       if(!$file || $file eq '') {
779 0           $self->error('NO_FILE');
780 0           return undef;
781             }
782              
783 0 0         if($file =~ /register\_service/mo) {
784 0           return 1;
785             }
786              
787 0           $self->error('NO_REGISTER_SERVICE');
788 0           return 0;
789             }
790              
791             =item Method B
792              
793             Usage:
794              
795             my $proto = $plugin->register_service_proto;
796              
797             This method return the 'proto' argument of a call to the register_service function
798              
799             =cut
800             sub register_service_proto {
801 0   0 0 1   my $self = shift || undef;
802 0 0         if(!$self) {
803 0           return undef;
804             }
805              
806 0           $self->cleanerror;
807              
808 0   0       my $file = $self->{FILE} || undef;
809 0 0 0       if(!$file || $file eq '') {
810 0           $self->error('NO_FILE');
811 0           return undef;
812             }
813              
814 0 0         if($self->register_service) {
815 0           $file =~ /register\_service\s*\(\s*.*proto\:\s*\"([^\"]*)\"/mo;
816 0 0 0       if(!$1 || $1 eq '') {
817 0           $self->error('NO_REGISTER_SERVICE_PROTO');
818 0           return undef;
819             }
820 0           return $1;
821             }
822              
823 0           $self->error('NO_REGISTER_SERVICE');
824 0           return undef;
825             }
826              
827             =item Method B
828              
829             Usage :
830              
831             my $error = $plugin->error;
832              
833             This method returns the last error happened during the parsing of the current plugin.
834              
835             List of errors:
836              
837             NO_FILE: The filename gived to parse_file method doesn't exist or it's empty.
838             NO_NESSUS_PLUGIN: The string gived to parse_string method isn't a valid NASL plugin.
839             NO_CVE: The current plugin hasn't an associated a CVE names list.
840             NO_BUGTRAQID: The current plugin hasn't associated a BUGTRAQIDs list.
841             NO_NAME: The current plugin hasn't a script_name field.
842             NO_SUMMARY: The current plugin hasn't a script_summary field.
843             NO_DESCRIPTION: The current plugin hasn't a script_description field.
844             NO_SOLUTION: The current plugin hasn't a solution field inside the script_description field.
845             NO_RISK: The current plugin hasn't a risk factor field inside the script_description field.
846             NO_FAMILY: The current plugin hasn't a script_family field.
847             NO_CATEGORY: The current plugin hasn't a script_category field.
848             NO_COPYRIGHT: The current plugin hasn't a script_copyright field.
849             NO_REGISTER_SERVICE: The current plugin doesn't execute the register_service function
850             NO_REGISTER_SERVICE_PROTO: The current plugin does execute the register_service function but it doesn't specify a proto
851              
852             =cut
853             sub error {
854 0   0 0 1   my $self = shift || undef;
855 0 0         if(!defined $self) {
856 0           return undef;
857             }
858              
859 0 0         if(@_) {
860 0           $self->{ERROR} = shift @_;
861             } else {
862 0 0 0       if(exists $self->{ERROR} && $self->{ERROR} ne '') {
863 0           return $self->{ERROR};
864             } else {
865 0           return undef;
866             }
867             }
868             }
869              
870             sub rawerror {
871 0   0 0 0   my $self = shift || undef;
872 0 0         if(!defined $self) {
873 0           return undef;
874             }
875              
876 0 0         if(@_) {
877 0           $self->{RAWERROR} = shift @_;
878             } else {
879 0 0 0       if(exists $self->{RAWERROR} && $self->{RAWERROR} ne '') {
880 0           return $self->{RAWERROR};
881             } else {
882 0           return undef;
883             }
884             }
885             }
886              
887             sub cleanfilename {
888 0   0 0 0   my $self = shift || undef;
889 0 0         if(!defined $self) {
890 0           return undef;
891             }
892              
893 0           $self->{FILENAME} = '';
894              
895 0           return 1;
896             }
897              
898             sub cleanerror {
899 0   0 0 0   my $self = shift || undef;
900 0 0         if(!defined $self) {
901 0           return undef;
902             }
903              
904 0           $self->{ERROR} = '';
905 0           $self->{RAWERROR} = '';
906              
907 0           return 1;
908             }
909              
910             sub clean {
911 0   0 0 0   my $self = shift || undef;
912 0 0         if(!defined $self) {
913 0           return undef;
914             }
915              
916 0           $self->{ERROR} = '';
917 0           $self->{RAWERROR} = '';
918 0           $self->{NASL} = 1;
919 0           $self->{FILE} = '';
920 0           $self->{PLUGIN_ID} = '';
921              
922 0           return 1;
923             }
924              
925             =back 4
926              
927             =head1 EXAMPLE
928              
929             # This example takes a .nasl file and prints its file name, plugin id, name and CVE list
930             use Parse::Nessus::Plugin;
931              
932             my $plugin = Parse::Nessus::Plugin->new;
933             if($plugin->error) {
934             die ("There were an error. Reason: ".$plugin->error);
935             }
936              
937             if(!$plugin->parse_file('/path/to/plugin.nasl') {
938             die ("There were an error. Reason: ".$plugin->error);
939             }
940              
941             print "FILENAME:".$plugin->filename."\n";
942             print "PLUGIN ID:".$plugin->id."\n";
943             print "NAME:".$plugin->name."\n";
944             my $cve = $plugin->cve;
945             if($cve) {
946             print " CVE:\n";
947             foreach my $cve (@{$cve}) {
948             print " $cve\n";
949             }
950             }
951              
952             Check the examples directory to see more examples.
953              
954             =head1 BUGS
955              
956             There aren't reported bugs yet, but that doesn't mean that it's free of them :)
957              
958             =head1 AUTHOR
959              
960             Roberto Alamos Moreno
961              
962             =head1 COPYRIGHT
963              
964             Copyright (c) 2005-2007 Roberto Alamos Moreno. All rights reserved.
965             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
966              
967             =cut
968             1;