Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#!/usr/bin/perl -w # setpassCat.pl # pod at tail use strict; use Net::Telnet::Cisco; # simplify telnet to Cisco devices use Term::ReadKey; # disable screen echo during password ent +ry use Tie::IxHash; # insertion-order hash of passwords+promp +ts use Time::localtime; # timestamp of each target device use vars qw( $target $input $newpass $newenablepass $ntc @cmd_output ); my %file = ( in => 'spC.in', sessionlog => 'spC.log', sessionsummary => 'spC.summ', NTClog => 'spC.input_log', ); my %parm = ( pwtimeout => 120, # seconds to wait for password from keybo +ard NTCtimeout => 5, # seconds to wait for response from devic +e NTCerrmode => 'return', # Net::Telnet::Cisco not die on problem d +evice targetcount => 0, # start with device count at zero ); ###################################################################### +##### umask oct 177; # $input_log file accessible to only this + user PrintBar(); print " Change passwords for multiple Cisco CatOS LAN switches\n"; PrintBar(); ###################################################################### +##### if (-e $file{sessionlog} and -f _) { unlink ($file{sessionlog}) or die " Error unlinking $file{sessionlog}: $!" } open (LOG, "> $file{sessionlog}") or die " Error opening $file{sessionlog}: $!"; ###################################################################### +##### unless (@ARGV) { unless (-r $file{in} && -T_) { Usage(); } @ARGV = "$file{in}" or die " Error opening $file{in}: $!"; chomp (@ARGV = <>); } ###################################################################### +##### print " Validating target list.\n"; foreach $target (@ARGV) { chomp $target; print (" $target\n"); unless ($target =~ (/^(\w|-|\.)+$/)) { print( "\n Error reading $file{in}:\n", " \"$target\" is an improperly formatted device name.\n", " Only alphanumeric, underscore, dash and dot allowed.\n\ +n", " Edit $file{in} to remove puctuation,", " blank lines and/or blank spaces.\n", ); WrapItUp(); exit; } } print ("\n"); ###################################################################### +##### print " Prompting for existing passwords\n", " (keystrokes *not* echoed to screen or written to disk)\n"; tie my %prompts, "Tie::IxHash"; %prompts = ( 'Enter existing password:' => 'oldpass', 'Enter existing enable password:' => 'olden', ); tie my %passwds, "Tie::IxHash"; foreach my $prompt (keys %prompts) { print " $prompt "; ReadMode('noecho'); # don't echo password to s +creen &WaitForPassword(); $passwds{$prompts{$prompt}} = $input; ReadMode('restore'); # re-activate screen + echo print "\n"; } print "\n"; my $oldpass = ($passwds{"oldpass"}); my $oldenablepass = ($passwds{"olden"}); ###################################################################### +##### print " Prompting for new passwords\n", " (keystrokes *not* echoed to screen or written to disk)\n"; tie my %newprompts, "Tie::IxHash"; %newprompts = ( 'Enter new password:' => 'newpass', ' Retype to confirm:' => 'confpass', 'Enter new enable password:' => 'newen', ' Retype to confirm: ' => 'confen', ); tie my %newpasswds, "Tie::IxHash"; foreach my $newprompt(keys %newprompts) { print " $newprompt "; ReadMode('noecho'); # don't echo password to scre +en &WaitForPassword(); $newpasswds{$newprompts{$newprompt}} = $input; ReadMode(0); # re-activate screen ec +ho print "\n"; } print "\n"; $newpass = ($newpasswds{"newpass"}); my $confirmpass = ($newpasswds{"confpass"}); $newenablepass = ($newpasswds{"newen"}); my $confirmenablepass = ($newpasswds{"confen"}); unless ( ("$newpass" eq "$confirmpass") and ("$newenablepass" eq "$confirmenablepass")) { PasswordsMismatch(); } ###################################################################### +##### PrintLogConsole (" Passwords will be updated on these devices:\n"); for(@ARGV) { PrintLogConsole (" $_\n"); } PrintLogConsole ("\n"); Pause (); PrintBar(); ###################################################################### +##### foreach $target (@ARGV) { ShowPcTime(); ++$parm{targetcount}; if ($ntc = Net::Telnet::Cisco->new ( host => $target, errmode => $parm{NTCerrmode}, timeout => $parm{NTCtimeout}, input_log => $file{NTClog}, )) { $ntc -> login('',$oldpass); PrintLastPrompt(4); if ($ntc -> enable($oldenablepass)) { PrintLastPrompt(2); ChangePass(); } else { PrintLogConsole ("Error accessing $target\n"); PrintLastPrompt(2); } $ntc -> cmd('disa'); print (@cmd_output); PrintLastPrompt(2); $ntc -> disable; PrintLastPrompt(4); $ntc -> close; } else { PrintLogConsole ("Error connecting to $target\n"); } } ShowPcTime(); WrapItUp(); ParseLog2Summary(); ###################################################################### +##### # print most recent telnet session prompt to log and console # param is number of spaces to precede device prompt sub PrintLastPrompt { PrintLogConsole (' 'x $_[0], $ntc -> last_prompt, "\n"); } ###################################################################### +##### # Summarize results sub ParseLog2Summary { my $loglines = 0; my $pwschanged = 0; my $errors = 0; open (LOG, "< $file{sessionlog}") or die " Error opening $file{sessionlog}: $!"; open (SUMMARY, "> $file{sessionsummary}") or die " Error opening $file{sessionsummary}: $!"; for (<LOG>) { ++$loglines; ++$errors if /^Error /; ++$pwschanged if /^\s+Password changed/; } printf " $^O %d:%d:%d %d-%d-%d\n", localtime -> hour(), localtime -> min(), localtime -> sec(), localtime -> mon()+1, localtime -> mday(), localtime -> year()+1900, ; printf SUMMARY " $^O %d:%d:%d %d-%d-%d\n", localtime -> hour(), localtime -> min(), localtime -> sec(), localtime -> mon()+1, localtime -> mday(), localtime -> year()+1900, ; PrintSummConsole (" Parsed $loglines line logfile\n\n"); PrintSummConsole (" $parm{targetcount} device(s)\n"); PrintSummConsole (" $pwschanged passwords changed\n"); PrintSummConsole (" $errors error(s)\n\n"); PrintSummConsole (" Review $file{sessionlog} for details.\n"); PrintSummConsole (" Search for \"Error\" if any errors indicated. +\n"); PrintBar(); close LOG or die " Error closing $file{sessionlog}: $!"; close SUMMARY or die " Error closing $file{sessionsummary}: $!"; } ###################################################################### +##### # print() instead of cmd() because 'set password' does not return std +prompt sub ChangePass { my $old; my $new; my @commands = ( 'set password', 'set enablepass' ); foreach my $command (@commands) { if ($ntc -> print("$command")) { PrintLogConsole (" $command\n"); } else { return ("Error sending '$command' command to $target.\n +"); } # "$ntc -> getline" must be here to populate @getlines properl +y # I don't understand it, but is what made it work |^( my $getline = $ntc -> getline; # print "\$getline = $getl +ine\n"; my @getlines = $ntc -> getlines; # print ("\$getlines = $ge +tlines\n"); foreach my $getlines (@getlines) { if ($getlines =~ /% Invalid input/) { PrintLogConsole ("Error running '$command' command at +$target.\n"); PrintLastPrompt(2); return(); # skip to next target if c +ommand fails } } if ($command =~ $commands[0]) { $old = "$oldpass"; $new + = "$newpass"; } if ($command =~ $commands[1]) { $old = "$oldenablepass"; $new + = "$newenablepass"; } # Additional error checking still needed here. if ($ntc -> waitfor('/Enter old password:/')) { PrintLastPrompt(2); $ntc -> print($old); print (@cmd_output); } else { return PrintLogConsole ("Error getting 'Enter old password' pr +ompt.\n"); } if ($ntc ->waitfor('/Enter new password:/')) { PrintLastPrompt(2); $ntc -> print($new); print (@cmd_output); } else { return PrintLogConsole ("Error getting 'Enter new password +' prompt.\n"); } if ($ntc ->waitfor('/Retype new password:/')) { PrintLastPrompt(2); $ntc -> print($new); print (@cmd_output); } else { return PrintLogConsole ("Error getting 'Retype new passwor +d' prompt.\n"); } if ($ntc ->waitfor('/Password changed./')) { PrintLastPrompt(2); } else { return PrintLogConsole ("Error getting 'Password changed' +prompt.\n"); } } } ###################################################################### +##### # Subroutines start here ###################################################################### +##### sub WaitForPassword { eval { local $SIG{ALRM} = sub { die "ALARUM" }; alarm("$parm{pwtimeout}"); chomp($input = <STDIN>); alarm(0); }; if ($@ =~ /ALARUM/) { print "\n\n"; print " Sorry - You waited too long before entering a passwor +d.\n"; print " Try again, if you want.\n\n"; ReadMode(0); # re-activate screen ec +ho exit; # "exit" instead of "die" so no error to conso +le } } ###################################################################### +##### sub PasswordsMismatch { print( " D'oh! Password confirmation(s) didn't match!\n", " Run this program again if you want, ", "and try not to fatfinger it next time!\n\n" ); exit; # "exit" instead of "die" so no error to cons +ole } ###################################################################### +##### sub WrapItUp { close LOG or die " Error closing $file{sessionlog}: $!"; PrintBar(); } ###################################################################### +##### sub Pause { print " Ctrl+c to abort or <enter> to continue."; (<STDIN>); } ###################################################################### +##### sub ShowPcTime { printf " $^O %d:%d:%d %d-%d-%d\n", localtime -> hour(), localtime -> min(), localtime -> sec(), localtime -> mon()+1, localtime -> mday(), localtime -> year()+1900, ; printf LOG " $^O %d:%d:%d %d-%d-%d\n", localtime -> hour(), localtime -> min(), localtime -> sec(), localtime -> mon()+1, localtime -> mday(), localtime -> year()+1900, ; } ###################################################################### +##### # print to console *and* logfile # param is text string to be printed sub PrintLogConsole { print @_; print(LOG @_) or die " Error printing to $file{sessionlog}: $!"; } ###################################################################### +##### # print to console *and* logfile # param is text string to be printed sub PrintSummConsole { print @_; print(SUMMARY @_) or die " Error printing to $file{sessionsummary}: $!"; } ###################################################################### +##### sub PrintBar { # Visual divider for ou +tput print "\n ", '=' x 54, "\n\n"; } ###################################################################### +##### sub Usage { print <<EOF Oops - you forgot to specify *what* CatOS switches to reset password +s on! Usage : setpassCat.pl device1 device2...<enter> or : setpassCat.pl<enter> where $file{in} = textfile list of devices address/name, one per line. "perldoc setpassCat.pl" for a bit more info. EOF ; #my @modules = ( # "Term::ReadKey", # "Tie::IxHash", # "Time::localtime", # "Net::Telnet", # "Net::Telnet::Cisco", # ); #foreach my $module (@modules) { # print ("$module $module::VERSION\n"); # } print( " Net::Telnet::Cisco $Net::Telnet::Cisco::VERSION\n", " Net::Telnet $Net::Telnet::VERSION\n", " Term::ReadKey $Term::ReadKey::VERSION\n", " Tie::IxHash $Tie::IxHash::VERSION\n", " Time::localtime $Time::localtime::VERSION\n", " Perl $]\n", " OS $^O\n", " Program $0\n\n", ); exit; } ###################################################################### +##### =head1 Title setpassCat.pl =head1 Description Automate password resets for multiple Cisco CatOS LAN switches Runtime is a couple seconds for each CatOS device CatOS = 2948g plus 4000, 5000 and 6000 family chassis IOS = 2916, 2924, 3548, and routers ??? = 1900 =head1 Usage Usage : setpassCat.pl device1 device2...<enter> or : setpassCat.pl<enter> where $file{in} = textfile list of devices address/name, one per line. =head1 Tested with: pass - Debian 2.2r2 "Espy" Perl 5.00503 Term::ReadKey 2.14 Tie::IxHash 1.21 Time::localtime 1.01 Net::Telnet 3.02 Net::Telnet::Cisco 1.03 fail - Windows 2000pro SiePerl 5.00503 install fails for Term::ReadKey Net::Telnet::Cisco against: CatOS 4.5(4) on Cisco Catalyst 2948g 5.5(1) 4006 4.5(2) 5500 5.3(5a)CSX 6009 5.5(1) 6509 =head1 Updated 2001-04-30 16:15 Hashamafy file and ntc param scalar variables. Un-subify to eliminate unecessary global variables. Mixed-case subroutine names, without ampersan. Format for 75 chars/line (well, mostly). 2001-04-10 15:00 Insignificant tweaks 2001-03-29 Changed doublequote to singlequote around "=" in PrintBar() 2001-03-28 Removed unecessary quotes around "$_ [0]" in PrintLastPrompt() Commented function parameters 2001-03-27 Commented reason for extra "$ntc -> getline" in ChangePass() Removed surrounding quotes from variable definitions Eliminated unecessary "my $continue" from Pause() Reduced copy+paste redundancy by adding PrintLastPrompt() Removed surrounding single quotes from numeric variables Fixed inconsistant indentation Tweaked console messages 2001-03-12 Added ParseLog2Summary to count (Password changed|Error)s and PrintSummConsole for output of above Simplified output syntax with 'print "=" x 54' 2001-03-09 Simplified ChangePass() with $command =~ $commands[0] Closed $file{sessionlog} in WrapItUp() 2001-03-08 Added check for 'Invalid input detected' Moved password timeout to function Improved error handling if device unreachable Tweaked console messages Replaced die"\n" with exit 2001-03-05 Added working timeout for passwords entry 2001-03-04 Initial post to Perl Monks 2001-02-26 Start rewrite of CiscoPassMass using waitfor() =head1 Comments The regex to sanity-check infile is very limited. But it should suffice for most $file{in} problems. =head1 Todos Figure out array for installed modules::VERSIONS. Improve (DNS name|IP address) check for infile sanity-checking. Net::IPv4Addr - ipv4_checkip Untaint infile instead of just sanity check. User.pm to save (log|summary) files to home dir. =head1 Author ybiC =head1 Credits Thanks to: Petruchio for mondo suggestions and help chromatic for $command =~ $commands[0] suggestion on a different post ar0n for timeout example at [id://30092] tilly for tips on functions strredwolf, jcwren, boo_radley, danger, crazyinsomniac, OeufMayo, azatoth and deprecated for suggestions in CB Oh yeah, and some guy named vroom {grin} =cut

In reply to (code)) Cisco Pass Mass - CatOS (deprecated by node 123464) by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (13)
    As of 2015-07-30 21:28 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (273 votes), past polls