Changeset 737

Show
Ignore:
Timestamp:
07/23/07 15:17:56 (1 year ago)
Author:
kindlund
Message:

Cleaned up IE module, extensively. Working on reliable unit tests.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/exp/kindlund-firefox/lib/HoneyClient/Agent/Driver/Browser/IE.pm

    r735 r737  
    3131####################################################################### 
    3232 
    33 #TODO: Documentation below 
    34  
    3533=pod 
    3634 
    3735=head1 NAME 
    3836 
    39 HoneyClient::Agent::Driver::Browser::IE - Perl extension to fetch the conten
    40 of a given web page.  This extends the Browser class by implementing 
    41 the getContent() function
     37HoneyClient::Agent::Driver::Browser::IE - Perl extension to drive Microsof
     38Internet Explorer to a given web page.  This package extends the Browser 
     39package, by overridding the drive() method
    4240 
    4341=head1 VERSION 
     
    4947  use HoneyClient::Agent::Driver::Browser::IE; 
    5048 
     49  # TODO: Need more here. 
     50 
     51=head1 DESCRIPTION 
     52 
     53# TODO: Need more here. 
     54 
    5155=cut 
    5256 
    5357package HoneyClient::Agent::Driver::Browser::IE; 
    5458 
    55 # XXX: Disabled version check, Honeywall does not have Perl v5.8 installed. 
    56 #use 5.008006; 
    5759use strict; 
    5860use warnings; 
    59 use Config; 
    6061use Carp (); 
    6162 
     
    105106    @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); 
    106107 
    107 # XXX: Fix this! 
    108 # Check to make sure our OS is Windows-based. 
    109 #if ($Config{osname} !~ /^MSWin32$/) { 
    110 #    Carp::croak "Error: " . __PACKAGE__ . " will only run on Win32 platforms!\n"; 
    111 #} 
    112  
    113108    $SIG{PIPE} = 'IGNORE';    # Do not exit on broken pipes. 
    114109} 
    115110our ( @EXPORT_OK, $VERSION ); 
    116111 
    117 #TODO: Rewrite the test module 
    118  
    119112=pod 
    120113 
    121114=begin testing 
    122115 
     116# Make sure Log::Log4perl loads 
     117BEGIN { use_ok('Log::Log4perl', qw(:nowarn)) 
     118        or diag("Can't load Log::Log4perl package. Check to make sure the package library is correctly listed within the path."); 
     119        
     120        # Suppress all logging messages, since we need clean output for unit testing. 
     121        Log::Log4perl->init({ 
     122            "log4perl.rootLogger"                               => "DEBUG, Buffer", 
     123            "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
     124            "log4perl.appender.Buffer.min_level"                => "fatal", 
     125            "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
     126            "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
     127        }); 
     128} 
     129require_ok('Log::Log4perl'); 
     130use Log::Log4perl qw(:easy); 
     131 
     132# Make sure HoneyClient::Util::Config loads. 
     133BEGIN { use_ok('HoneyClient::Util::Config', qw(getVar)) 
     134        or diag("Can't load HoneyClient::Util::Config package.  Check to make sure the package library is correctly listed within the path.");  
     135 
     136        # Suppress all logging messages, since we need clean output for unit testing. 
     137        Log::Log4perl->init({ 
     138            "log4perl.rootLogger"                               => "DEBUG, Buffer", 
     139            "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
     140            "log4perl.appender.Buffer.min_level"                => "fatal", 
     141            "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
     142            "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
     143        }); 
     144         
     145} 
     146require_ok('HoneyClient::Util::Config'); 
     147can_ok('HoneyClient::Util::Config', 'getVar'); 
     148use HoneyClient::Util::Config qw(getVar); 
     149 
     150# Make sure the module loads properly, with the exportable 
     151# functions shared. 
     152BEGIN { use_ok('HoneyClient::Agent::Driver::Browser::IE') or diag("Can't load HoneyClient::Agent::Driver::Browser::IE package.  Check to make sure the package library is correctly listed within the path."); } 
     153require_ok('HoneyClient::Agent::Driver::Browser::IE'); 
     154can_ok('HoneyClient::Agent::Driver::Browser::IE', 'new'); 
     155can_ok('HoneyClient::Agent::Driver::Browser::IE', 'drive'); 
     156can_ok('HoneyClient::Agent::Driver::Browser::IE', 'isFinished'); 
     157can_ok('HoneyClient::Agent::Driver::Browser::IE', 'next'); 
     158can_ok('HoneyClient::Agent::Driver::Browser::IE', 'status'); 
     159can_ok('HoneyClient::Agent::Driver::Browser::IE', 'getNextLink'); 
     160use HoneyClient::Agent::Driver::Browser::IE; 
     161 
     162# Suppress all logging messages, since we need clean output for unit testing. 
     163Log::Log4perl->init({ 
     164    "log4perl.rootLogger"                               => "DEBUG, Buffer", 
     165    "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer", 
     166    "log4perl.appender.Buffer.min_level"                => "fatal", 
     167    "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout", 
     168    "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n", 
     169}); 
     170 
     171# Make sure Win32::Job loads. 
     172BEGIN { use_ok('Win32::Job') or diag("Can't load Win32::Job package.  Check to make sure the package library is correctly listed within the path."); } 
     173require_ok('Win32::Job'); 
     174use Win32::Job; 
     175 
    123176=end testing 
    124177 
     
    126179 
    127180####################################################################### 
    128  
    129 #TODO: Remove any of these use statements that aren't needed 
    130181 
    131182# Include the Global Configuration Processing Library 
    132183use HoneyClient::Util::Config qw(getVar); 
    133184 
    134 # Use ISO 8601 DateTime Libraries 
    135 use DateTime::HiRes; 
    136  
    137 # Use fractional second sleeping. 
    138 # TODO: Need unit testing. 
    139 use Time::HiRes qw(sleep); 
    140  
    141 # Use Storable Library 
    142 use Storable qw(dclone); 
    143  
    144 # Use threads Library 
    145 # TODO: Need unit testing. 
    146 use threads; 
    147  
    148 # TODO: Need unit testing. 
    149 use threads::shared; 
    150  
    151 # TODO: Need unit testing. 
    152 use HoneyClient::Util::SOAP qw(getClientHandle); 
    153  
    154 # TODO: Need unit testing. 
     185# Include Win32 Job Library 
    155186use Win32::Job; 
    156187 
     
    161192our $LOG = get_logger(); 
    162193 
    163 # TODO: clean this up. 
    164 #my %PARAMS = ( 
    165 #); 
    166  
    167 ####################################################################### 
    168 # Private Methods Implemented                                         # 
    169 ####################################################################### 
    170  
    171 #sub new { 
    172 #    
    173 #    # - This function takes in an optional hashtable, 
    174 #    #   that contains various key => 'value' configuration 
    175 #    #   parameters. 
    176 #    # 
    177 #    # - For each parameter given, it overwrites any corresponding 
    178 #    #   parameters specified within the default hashtable, %PARAMS, 
    179 #    #   with custom entries that were given as parameters. 
    180 #    # 
    181 #    # - Finally, it returns a blessed instance of the 
    182 #    #   merged hashtable, as an 'object'. 
    183 
    184 #    # Get the class name. 
    185 #    my $self = shift; 
    186 
    187 #    # Get the rest of the arguments, as a hashtable. 
    188 #    # Hash-based arguments are used, since HoneyClient::Util::SOAP is unable to handle 
    189 #    # hash references directly.  Thus, flat hashtables are used throughout the code 
    190 #    # for consistency. 
    191 #    my %args = @_; 
    192 
    193 #    # Check to see if the class name is inherited or defined. 
    194 #    my $class = ref($self) || $self; 
    195 
    196 #    # Initialize default parameters. 
    197 #    my %params = %{dclone(\%PARAMS)}; 
    198 #    $self = $class->SUPER::new(); 
    199 #    @{$self}{keys %params} = values %params; 
    200 
    201 #    # Now, overwrite any default parameters that were redefined 
    202 #    # in the supplied arguments. 
    203 #    @{$self}{keys %args} = values %args; 
    204 
    205 #    # Now, assign our object the appropriate namespace. 
    206 #    bless $self, $class; 
    207 
    208 #    # Finally, return the blessed object. 
    209 #    return $self; 
    210 #} 
     194####################################################################### 
     195# Public Methods Implemented                                          # 
     196####################################################################### 
     197 
     198=pod 
     199 
     200=head1 METHODS OVERRIDDEN 
     201 
     202The following functions have been overridden by the IE driver.  All other 
     203methods were implemented by the generic Browser driver.  For further 
     204information about the Browser driver, see the L<HoneyClient::Agent::Driver::Browser> 
     205documentation. 
     206 
     207=head2 $object->drive(url => $url) 
     208 
     209=over 4 
     210 
     211Drives an instance of Microsoft Internet Explorer for one iteration, 
     212navigating either to the specified URL or to the next URL computed within 
     213the Browser driver's internal hashtables. 
     214 
     215For a description of which hashtable is consulted upon each iteration of 
     216drive(), see the B<next_link_to_visit> description of the  
     217L<HoneyClient::Agent::Driver::Browser> documentation, in the 
     218"DEFAULT PARAMETER LIST" section. 
     219 
     220Once a drive() iternation has completed, the corresponding browser process 
     221is terminated.  Thus, each call to drive() invokes a new instance of the 
     222browser. 
     223 
     224I<Inputs>: 
     225 B<$url> is an optional argument, specifying the next immediate URL the browser 
     226must drive to. 
     227 
     228I<Output>: The updated IE driver B<$object>, containing state information from driving the 
     229browser for one iteration. 
     230 
     231B<Warning>: This method will B<croak>, if the IE driver object is B<unable> 
     232to navigate to a new link, because its list of links to vist is empty and no new 
     233URL was supplied. 
     234 
     235=back 
     236 
     237=begin testing 
     238 
     239# TODO: Implement this. 
     2401; 
     241 
     242=end testing 
     243 
     244=cut 
    211245 
    212246sub drive { 
     
    256290 
    257291    # Spawn the job. 
    258     #$job->spawn(undef, "\"C:\\Program Files\\Internet Explorer\\iexplore.exe\"" . $args{'url'}); 
    259292    my $processExec = getVar(name => "process_exec"); 
    260293    my $processName = getVar(name => "process_name"); 
     
    270303    $job->run($timeout); 
    271304 
    272     # TODO: check to see if run fails. 
     305    # Check to see if run fails. 
    273306    $status = $job->status(); 
    274307 
     
    292325    } 
    293326 
     327    # TODO: We may want to report this suspicious activity back to the Agent; 
     328    # perhaps force the Agent to do an early integrity check, to make sure nothing 
     329    # sketchy is going on. 
     330 
    294331    # Check to make sure the exitcode is '293', meaning, that the 
    295332    # application didn't unexpectedly die early. 
    296333    if ($status->{$processID}->{'exitcode'} != 293) { 
    297         $LOG->warn("'" . $processName . "' process (ID = " . $processID . ") unexpectedly terminated early!"); 
     334        $LOG->warn("Unexpected: '" . $processName . "' process (ID = " . $processID . ") terminated early!"); 
    298335    } 
    299336 
     
    3063431; 
    307344 
     345####################################################################### 
     346# Additional Module Documentation                                     # 
     347####################################################################### 
     348 
     349__END__ 
     350 
     351=head1 BUGS & ASSUMPTIONS 
     352 
     353This package will only run on Win32 platforms.  Furthermore, it has 
     354only been tested to work reliably within a Cygwin environment. 
     355 
     356In a nutshell, this object is nothing more than a blessed anonymous 
     357reference to a hashtable, where (key => value) pairs are defined in 
     358the L<DEFAULT PARAMETER LIST>, as well as fed via the new() function 
     359during object initialization.  As such, this package does B<not> 
     360perform any rigorous B<data validation> prior to accepting any new 
     361or overriding (key => value) pairs. 
     362 
     363However, additional links can be fed to any IE driver at any time, by 
     364simply adding new hashtable entries to the B<links_to_visit> hashtable 
     365within the B<$object>. 
     366 
     367For example, if you wanted to add the URL "http://www.mitre.org" 
     368to the IE driver B<$object>, simply use the following code: 
     369 
     370  $object->{links_to_visit}->{'http://www.mitre.org'} = 1; 
     371 
     372In general, the IE driver does B<not> know how many links it will 
     373ultimately end up browsing to, until it conducts an exhaustive 
     374spider of all initial URLs supplied.  As such, expect the output 
     375of $object->status() to change significantly, upon each 
     376$object->drive() iteration. 
     377 
     378For example, if at one given point, the status of B<percent_complete> 
     379is 30% and then this value drops to 15% upon another iteration, then 
     380this means that the total number of links to drive to has greatly 
     381increased. 
     382 
     383Lastly, we assume that the Microsoft Internet Explorer browser has 
     384been preconfigured to B<not cache any data>.  This ensures the browser 
     385will render the most recent version of the content hosted at each URL. 
     386 
     387=head1 SEE ALSO 
     388 
     389L<http://www.honeyclient.org/trac> 
     390 
     391=head1 REPORTING BUGS 
     392 
     393L<http://www.honeyclient.org/trac/newticket> 
     394 
     395=head1 AUTHORS 
     396 
     397Kathy Wang, E<lt>knwang@mitre.orgE<gt> 
     398 
     399Thanh Truong, E<lt>ttruong@mitre.orgE<gt> 
     400 
     401Darien Kindlund, E<lt>kindlund@mitre.orgE<gt> 
     402 
     403Brad Stephenson, E<lt>stephenson@mitre.orgE<gt> 
     404 
     405=head1 COPYRIGHT & LICENSE 
     406 
     407Copyright (C) 2007 The MITRE Corporation.  All rights reserved. 
     408 
     409This program is free software; you can redistribute it and/or 
     410modify it under the terms of the GNU General Public License 
     411as published by the Free Software Foundation, using version 2 
     412of the License. 
     413 
     414This program is distributed in the hope that it will be useful, 
     415but WITHOUT ANY WARRANTY; without even the implied warranty of 
     416MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     417GNU General Public License for more details. 
     418 
     419You should have received a copy of the GNU General Public License 
     420along with this program; if not, write to the Free Software 
     421Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
     42202110-1301, USA. 
     423 
     424 
     425=cut 
     426