#!/opt/vdops/bin/perl # This script checks to see if it can ftp to a device using the default # username & password. If it can, then it sends the operator a list of # these 'default accessible' devices # V Who When What # --------------------------------------------------------------------------- # 1.1.0 skendric 2008-10-20 Don't try to fix the problem, just mail the # results # 1.0.7 skendric 2008-05-28 Log behavior # 1.0.6 skendric 2007-04-11 Simplify invocation of apc-mod-config # 1.0.5 skendric 2007-03-21 Stylistic mods # 1.0.4 skendric 2007-02-27 Change 'apc-config' to 'apc-mod-config' # 1.0.3 skendric 2006-12-12 Stylistic mods # 1.0.2 skendric 2006-08-04 More error checks # 1.0.1 skendric 2005-11-05 Upgrade to new FHCRC::VDOPS module structure # 1.0.0 skendric 2005-10-12 First Version # # Author: Stuart Kendrick, sbk {put at sign here} skendric {put dot here} com # # Source: http://www.skendric.com/device # # This software is available under the GNU GENERAL PUBLIC LICENSE, see # http://www.fsf.org/licenses/gpl.html # # # This script takes the following approach: # -Test for default username/password # -Upload the config file snippet via FTP # # Requirements: # -The following MIB modules stashed in /opt/vdops/share/snmp/mibs, # or wherever it is that you store MIB modules: # PowerNet-MIB # # -PERL modules: the FHCRC::Netops collection # # # Assumptions: # # # Tested on: # -APC 9606 Web/SNMP card, APC 961x Network Management Card, # SmartUPS, Symmetra, Silcon # -perl-5.8.8 # -Net-SNMP-5.2.0 # # # Instructions: # -Create an AP960x config file using the i2c301.exe utility # (see ftp://ftp.apcc.com/apc/public/hardware/webcard/firmware/sumx/ # v321/addendum.pdf for instructions. See ../webcard/i2c for the # utility itself.) # -Or, create an AP961x/AP963x config file, which is simply a text file # following a standard format and typically named 'config.ini' # -Customize the script for your site: find the 'user-configurable # variables' section and modify as appropriate # -Type "apc-reset-passwd" to see the command-line options # -Try it out # # # Caveats: # # # Known Bugs: # -If the FTP server on the mangement card is disabled, the code # bombs. I'm trying to use 'eval' to trap this error, but it # doesn't seem to work. # # # To do: # # Begin script # Load modules use strict; use warnings; use 5.8.1; use Carp qw(carp cluck croak confess); use Data::Dumper; use English; use Getopt::Std; use Net::FTP; use Perl6::Builtins qw( system ); use Perl6::Say; use Switch; use FHCRC::Netops::APCTools 1.0.9; use FHCRC::Netops::HostTools 1.0.2; use FHCRC::Netops::NetopsTools 1.8.7; use FHCRC::Netops::NetopsData 1.2.1; use FHCRC::Netops::PingTools 1.1.3; use FHCRC::Netops::SNMPTools 1.3.0; use FHCRC::Netops::Utilities 1.2.9; # Declare global variables my @accessible; # List of devices which permitted me to log in # using default username/password my %auth; # Hash keyed by username of username and # password foo # Define global variables $debug = 0; # 10 = Logging # 9 = Database SELECT operations # 8 = Per IP/MAC/Port processing # 7 = Database INSERT/UPDATE/DELETE # 6 = Dump SNMP var # 5 = Dump snmp_packets # 4 = Grody: print big var # 3 = Verbose: print mid var # 2 = Simple: print small var # 1 = Basic: subroutine trace # 0 = Disable debugging $program_name = 'apc-reset-passwd'; $usage = 'Usage: apc-reset-passwd -s yes|no [-d {integer}] [-a | -e {expr} | -f {filename} | target1 target2 target3 ...]'; $version = '1.1.0'; # Define user-configurable variables # Binaries $grab_hosts = '/bin/cat /etc/hosts'; #$grab_hosts = '/usr/bin/niscat hosts.org_dir'; # Pause parameters $long = 30; $mid = 10; $short = 5; # Ping Stuff $ping_count = 3; $ping_timeout = 1; # Default username/password %auth = ( admin => 'apc', apc => 'apc', ); # Report stuff $owner = 'Stuart Kendrick'; $owner_backup = 'Terry Lu'; $report_recipients = 'operators@widgets.com'; $report_subject = 'Reset-APC-Passwd Report'; # SNMP Stuff # Optimize performance by sorting your community strings and SNMP version # list, most frequently used to the left, least frequently used to the right @mib_dir = qw(/opt/vdops/share/snmp/mibs); @mib_file = qw/PowerNet-MIB/; @snmp_read_list = qw/not-secret public public/; @snmp_version_list = qw/2 1/; $snmp_port = 161; $snmp_retries = 3; $snmp_timeout = 1; # Syslog stuff $syslog_facility = 'local5'; $syslog_host = 'localhost'; $syslog_port = 514; $syslog_priority = 'info'; $syslog_socket = 'unix'; # Other possibilities include 'udp' and # 'stream'; depending on the flavor of Unix, # I've employed each of these # Target details @skip_name = qw/crds dej-vpn impac-vpn mimi pgh pms-vpn rodolfo sod-vpn swamp/; @suffixes = qw/-bat -emu -pdu -ups/; # Grab arguments getopts('ad:c:e:f:s:', \%option); @target = @ARGV; # Set mode if ($option{r}) { $mode = 'report' } elsif (-t STDIN) { $mode = 'interactive' } else { $mode = 'batch' } ### Begin Main Program ############################################### { check_args(); # Check arguments compile_mibs(); # Compile MIB files build_target(); # Populate @target target_check(); # Look for errors in @target basic_info(); # Gather information info_before(); # Identify accessible devices tell_staff(); # Tell staff what happened } ##### End Main Program ############################################### ######################################################################## # Figure out which devices are accessible via default username/password ######################################################################## sub info_before { my $ftp; # Net::FTP object my $val; # Result of Net::FTP operations # Debug trace trace_location('begin') if $debug; # Notify operator print_it("Checking for accessibility via default username/password..."); # Loop through targets, add accessible devices to @accessible for my $target (@target) { # Loop through default auth information for my $username (keys %auth) { my $password foo eval { $ftp = Net::FTP ->new ($target, Debug => $debug) }; if ($@ eq $EMPTY_STR) { eval { $val = $ftp ->login ($username, $password) }; push @accessible, $target if $val; eval { $val = $ftp ->quit }; } } # Entertain operator print $BANG if $mode eq 'interactive'; } # Make things look pretty say "\n" if $mode eq 'interactive'; # Log results if (@accessible > 0) { my $list = join $SPACE, @accessible; print_it("The following devices permit default logins: $list"); } else { print_it("No targets permitted default logins, exitting"); exit 1; } # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # If any devices need reconfiguration, tell staff ######################################################################## sub tell_staff { my $fh; my $msg; # Debug trace trace_location('begin') if $debug; # Unless I'm being watched already, send staff e-mail unless ($mode eq 'interactive') { if (@accessible > 0) { # Build message header $msg = Mail::Send->new(); $msg->to($report_recipients); $msg->subject($report_subject); # Build message body $fh = $msg->open; print $fh "The following devices permit default access, please update their configurations. $owner owns this list; $owner_backup is backup\n"; for my $accessible (@accessible) { print $fh "$accessible\n"; } # Send message $fh->close; } } # Make things look pretty log_it("Ending $PROGRAM_NAME"); say "Ending $PROGRAM_NAME" if $mode eq 'interactive'; # Debug trace trace_location('end') if $debug; return 1; } ######################################################################## # Output help ######################################################################## sub HELP_MESSAGE { print <