File Coverage

blib/lib/Virani/Client.pm
Criterion Covered Total %
statement 17 72 23.6
branch 0 40 0.0
condition n/a
subroutine 6 8 75.0
pod 2 2 100.0
total 25 122 20.4


line stmt bran cond sub pod time code
1             package Virani::Client;
2              
3 1     1   70132 use 5.006;
  1         12  
4 1     1   6 use strict;
  1         2  
  1         31  
5 1     1   6 use warnings;
  1         2  
  1         24  
6 1     1   738 use LWP::UserAgent;
  1         56281  
  1         49  
7 1     1   499 use HTTP::Request::Common;
  1         2438  
  1         72  
8 1     1   555 use File::Slurp;
  1         32173  
  1         679  
9              
10             =head1 NAME
11              
12             Virani::Client - Client for remotely accessing Virani vis HTTP or HTTPS.
13              
14             =head1 VERSION
15              
16             Version 0.0.1
17              
18             =cut
19              
20             our $VERSION = '0.0.1';
21              
22             =head1 SYNOPSIS
23              
24             Quick summary of what the module does.
25              
26             Perhaps a little code snippet.
27              
28             use Virani::Client;
29              
30             my $virani_client = Virani::Client->new(url=>$url);
31              
32              
33             =head1 METHODS
34              
35              
36             =head2 new
37              
38             Initiates the object.
39              
40             - url :: The URL to use to contact mojo-virani by.
41             Default :: undef
42              
43             - apikey :: The API key if needed.
44             Default :: undef
45              
46             - timeout :: Timeout for fetching it in seconds.
47             Default :: 60
48              
49             - verify_hostname :: Check the cert if using HTTPS.
50             Default :: 1
51              
52             Of the above keys, only 'url' is a requirement.
53              
54             If verify_hostname is undef, the following enviromental variables are
55             checked in the following order.
56              
57             VIRANI_VERIFY_HOSTNAME
58             HTTPS_VERIFY_HOSTNAME
59             PERL_LWP_VERIFY_HOSTNAME
60              
61             =cut
62              
63             sub new {
64 0     0 1   my ( $blank, %opts ) = @_;
65              
66 0 0         if ( !defined( $opts{url} ) ) {
67 0           die('No url defined');
68             }
69              
70 0 0         if ( !defined( $opts{verify_hostname} ) ) {
71 0 0         if ( defined( $ENV{VIRANI_VERIFY_HOSTNAME} ) ) {
    0          
    0          
72 0           $opts{verify_hostname} = $ENV{VIRANI_VERIFY_HOSTNAME};
73             }
74             elsif ( defined( $ENV{HTTPS_VERIFY_HOSTNAME} ) ) {
75 0           $opts{verify_hostname} = $ENV{HTTPS_VERIFY_HOSTNAME};
76              
77             }
78             elsif ( defined( $ENV{PERL_LWP_VERIFY_HOSTNAME} ) ) {
79 0           $opts{verify_hostname} = $ENV{PERL_LWP_VERIFY_HOSTNAME};
80             }
81             else {
82 0           $opts{verify_hostname} = 1;
83             }
84             }
85              
86             my $self = {
87             apikey => $opts{apikey},
88             url => $opts{url},
89             timeout => 60,
90             verify_hostname => $opts{verify_hostname},
91 0           };
92 0           bless $self;
93              
94 0           return $self;
95             }
96              
97             =head2 fetch
98              
99             Reaches out via HTTP or HTTPS and fetches the PCAP and JSON metadata.
100              
101             - start :: A L object of when to start looking.
102             - Default :: undef
103              
104             - end :: A L object of when to stop looking.
105             - Default :: undef
106              
107             - filter :: The BPF or tshark filter to use.
108             - Default :: undef
109              
110             - set :: The PCAP set to use. Will use what ever the default is set to if undef or blank.
111             - Default :: undef
112              
113             - file :: The file to output to. The metadata writen to a file of the same name
114             with '.json' appended.
115             - Default :: out.pcap
116              
117             - type :: 'tcpdump', 'bpf2tshark', or 'tshark', depending on what one wants the filter todo.
118             If not set, the remote system uses what ever is defined as the default for that set.
119             - Default :: undef
120              
121             The following are required
122              
123             start
124             end
125             filter
126              
127             IF the command success the raw unparsed JSON of the metadata is returned.
128              
129             my $raw_metadata_json=$virani_client->(start=>$start, end=>$end, filter=>$filter);
130              
131             =cut
132              
133             sub fetch {
134 0     0 1   my ( $self, %opts ) = @_;
135              
136 0 0         if ( !defined( $opts{filter} ) ) {
137 0           die('Nothing specified for $opts{filter}');
138             }
139              
140 0 0         if ( !defined( $opts{file} ) ) {
141 0           $opts{file} = 'out.pcap';
142             }
143              
144             # basic sanity checking
145 0 0         if ( !defined( $opts{start} ) ) {
    0          
    0          
    0          
146 0           die('$opts{start} not defined');
147             }
148             elsif ( !defined( $opts{end} ) ) {
149 0           die('$opts{start} not defined');
150             }
151             elsif ( ref( $opts{start} ) ne 'Time::Piece' ) {
152 0           die('$opts{start} is not a Time::Piece object');
153             }
154             elsif ( ref( $opts{end} ) ne 'Time::Piece' ) {
155 0           die('$opts{end} is not a Time::Piece object');
156             }
157              
158             my $ua = LWP::UserAgent->new(
159             protocols_allowed => [ 'http', 'https' ],
160             timeout => $self->{timeout},
161 0           );
162 0 0         if ( $self->{verify_hostname} ) {
163 0           $ua->ssl_opts( verify_hostname => 1 );
164             }
165             else {
166 0           $ua->ssl_opts( verify_hostname => 0, SSL_verify_mode => 0 );
167             }
168              
169 0           $opts{filter} =~ s/\ /\%20/g;
170              
171             # put the url together
172 0           my $url = $self->{url} . '?start=' . $opts{start}->epoch . '&end=' . $opts{end}->epoch;
173 0 0         if (defined($opts{type})) {
174 0           $url = $url . '&type=' . $opts{type};
175             }
176 0 0         if ( defined( $self->{apikey} ) ) {
177 0           $url = $url . '&apikey=' . $self->{apikey};
178             }
179 0 0         if ( defined( $opts{set} ) ) {
180 0           $url = $url . '&set=' . $opts{set};
181             }
182 0           $url = $url . '&bpf=' . $opts{filter};
183              
184             # get the PCAP
185 0           my $res;
186 0           eval { $res = $ua->request( GET $url); };
  0            
187 0 0         if ($@) {
188 0           die( 'Fetch failed... ' . $@ );
189             }
190 0 0         if ( $res->is_success ) {
191 0           my $pcap = $res->decoded_content;
192 0 0         write_file( $opts{file}, $pcap ) || die( 'PCAP write to "' . $opts{file} . '" failed... ' . $@ );
193             }
194             else {
195 0           die( 'Fetch failed... ' . $url . ' ... ' . $res->status_line . ' ... ' . $res->decoded_content );
196             }
197              
198             # get the meta
199 0           $url = $url . '&get_meta=1';
200 0           my $raw_json;
201 0           eval { $res = $ua->request( GET $url); };
  0            
202 0 0         if ($@) {
203 0           die( 'Fetch failed... ' . $@ );
204             }
205 0 0         if ( $res->is_success ) {
206 0           $raw_json = $res->decoded_content;
207 0           print "Metadata...\n" . $raw_json;
208             }
209             else {
210 0           die( 'Fetch failed... ' . $url . ' ... ' . $res->status_line . ' ... ' . $res->decoded_content );
211             }
212              
213 0           return $raw_json;
214             }
215              
216             =head1 AUTHOR
217              
218             Zane C. Bowers-Hadley, C<< >>
219              
220             =head1 BUGS
221              
222             Please report any bugs or feature requests to C, or through
223             the web interface at L. I will be notified, and then you'll
224             automatically be notified of progress on your bug as I make changes.
225              
226              
227              
228              
229             =head1 SUPPORT
230              
231             You can find documentation for this module with the perldoc command.
232              
233             perldoc Virani::Client
234              
235              
236             You can also look for information at:
237              
238             =over 4
239              
240             =item * RT: CPAN's request tracker (report bugs here)
241              
242             L
243              
244             =item * CPAN Ratings
245              
246             L
247              
248             =item * Search CPAN
249              
250             L
251              
252             =back
253              
254              
255             =head1 ACKNOWLEDGEMENTS
256              
257              
258             =head1 LICENSE AND COPYRIGHT
259              
260             This software is Copyright (c) 2023 by Zane C. Bowers-Hadley.
261              
262             This is free software, licensed under:
263              
264             The GNU Lesser General Public License, Version 2.1, February 1999
265              
266              
267             =cut
268              
269             1; # End of Virani::Client