SNMP v3 with NET::SNMP working, but snmpwalk/snmpget not? - perl

I have the following (working) perl script:
use Net::SNMP;
# create session to the host
my ($session, $error) = Net::SNMP->session(
-hostname => $hostname,
-version => 'snmpv3',
-username => 'my_user_name',
-authkey => 'my_authkey',#actually, here stands the real authkey as configured on the switch
-privkey => 'my_privkey',#same as on switch
-authprotocol => 'sha',
-privProtocol => 'des'
);
if (!defined($session)) {
print $error . "\n";
last;
}
# retrieve a table from the remote agent
my $result = $session->get_table(
-baseoid => $MAC_OID
);
if (!defined($result)) {
print $session->error . "\n";
$session->close;
last;
}
#print out the result of the snmp query
#....
Now I wanted to use snmpwalk or snmpget with the same keys. For that, I created a snmp.conf file in .snmp of my home directory with the following content:
defSecurityName my_user_name
defContext ""
defAuthType SHA
defSecurityLevel authPriv
defAuthPassphrase my_auth_key here
defVersion 3
defPrivPassphrase my_privkey here
defPrivType DES
As I see it, I use the same credentials in the script and for snmpget. Why do I get snmpget: Authentication failure (incorrect password, community or key) ?

That depends on the version of snmpget and snmpset you use. When I tested an older version of net-snmp against my C# based SNMP agent http://sharpsnmplib.codeplex.com I noticed that for SHA authen mode + DES privacy mode a bug prevented the net-snmp command line tools from generating the correct message bytes (the encryption is wrong so that no agent can decrypt it).
My suggestion is that you try to use Net::SNMP instead, as like you found out, it is not affected by the same bug.

Your problem is that you're using an authentication key for Net::SNMP and a password for the command-line net-snmp tools. Based on your Net::SNMP usage you're actually using 'localized' keys. Which means the right tokens for your snmp.conf file are:
defAuthLocalizedKey 0xHEXSTRING
defPrivLocalizedKey 0xHEXSTRING
See the snmp.conf manual page for further details.

Related

Perl and Selenium::Remote::Driver

EDITED AGAIN
I have a server on AWS somewhere in Northern Virginia and this is my monitoring server. I ssh into this Ubuntu server from another State to do system administration. I want to do web automation tests on this server which will test a web application on the Internet hitting a URL and verify that I can selenium test a login and authenticate successfully. This server is on an AWS cloud I'm not quite sure which Perl module to use since I'm accessing it remotely.
There are two CPAN modules: Selenium::Remote::Driver and WWW::Selenium. I have tried both and they are giving me issues. And I really don't know which is appropriate for my scenario. When I use Selenium::Remote::Driver, I get the following error:
Selenium server did not return proper status at /usr/local/share/perl/5.18.2/Selenium/Remote/Driver.pm line 401.
When I use WWW::Selenium, I get this error:
Failed to start new browser session: org.openqa.selenium.server.RemoteCommandException: Error while launching browser
I was able to launch firefox manually from the AWS monitoring server by exporting the DISPLAY but it was really slow. I have heard that I can use a headless browser but I would have to export the DISPLAY by:
export DISPLAY=:5
But remember, I'm sshing into this AWS/Selenium server from my desktop so I'm assuming I use the above command on the AWS/Selenium Server while I'm ssh into it from my desktop? Actually, at this point, I'm not sure I'm doing here. Can somebody help?
The problem in this type of questions is that the variety of configurations and binaries in your setup might be so broad that the it is hard to actually provide a straight and correct answer for YOUR SETUP.
This answer has the following assumptions:
you have downloaded the selenium-server-standalone.jar into /usr/lib/
you have jdk 1.8 ( run the java -version in the shell
you have installed and configured the xvfb-run ( it is a fight on it's own )
So :
```
# ssh to your server , obs the -X !
ssh -X user-name#server-name
# start the selenium-server-standalone on the server
xvfb-run -e /dev/stdout java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/lib/selenium-server-standalone.jar &
# one liner test - this is one veery long one
perl -e 'use strict ; use warnings ; use Data::Printer ; my $host="127.0.0.1"; use Selenium::Remote::Driver;my $driver = Selenium::Remote::Driver->new( "browser_name" =>"chrome", "error_handler" => sub { print $_[1]; croak 'goodbye'; }, "remote_server_addr" => "$host","port"=> "4444");$driver->debug_on();$driver->get("http://www.google.com"); print $driver->get_title();$driver->quit();' &
```
Here is the code in the one-liner as a perl script
#!/usr/bin/env perl
use strict ;
use warnings ;
use Carp ;
use Data::Printer ;
use Selenium::Remote::Driver;
my $host="127.0.0.1";
my $driver = Selenium::Remote::Driver->new(
"browser_name" =>"chrome"
, "error_handler" => sub { print $_[1]; croak 'goodbye' ; }
, "remote_server_addr" => "$host"
, "port"=> "4444") ;
$driver->debug_on() ;
$driver->get("http://www.google.com");
print $driver->get_title();
$driver->quit();
The output should look something like:
```
Prepping get
Executing get
REQ: POST, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/url, {"url":"http://www.google.com"}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
Prepping getTitle
Executing getTitle
REQ: GET, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b/title, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":"Google"}
GooglePrepping quit
Executing quit
REQ: DELETE, http://127.0.0.1:4444/wd/hub/session/ddb9c2575ab026cdb8c640bdc554181b, {}
RES: {"sessionId":"ddb9c2575ab026cdb8c640bdc554181b","status":0,"value":null}
```
Try running the below code:
#!/usr/bin/perl
use warnings;
use strict;
use Selenium::Remote::Driver;
my $host = "10.10.1.1"; //Enter your server IP in this place
my $driver = new Selenium::Remote::Driver('remote_server_addr' => $host,
'port' => '4444',
'auto_close' => 0);
$driver->get('http://www.google.com');

IO/Pty error when compiling PERL script

It has been awhile since I have done any PERL programming and I am working on a project where I need to connect to a remote server and get a listing of files. The script is being developed on a Windows 2012 server using ActivePerl.
This is the script that I have put together, from other examples -
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use autodie;
use Net::SFTP::Foreign;
# US Server Configuration
use constant {
HOST => "samplehost",
REMOTE_DIR => "sample/remote",
LOCAL_DIR => "sample/local",
PORT => "3235",
USER_NAME => "username",
PASSWORD => "D%password",
DEBUG => "0",
};
my $stfp = Net::SFTP::Foreign->new (
HOST,
timeout => 240,
user => USER_NAME,
password => PASSWORD,
port => PORT,
autodie => 1,
);
#
# List remote directory contents
#
my $remotefiles;
$remotefiles = $stfp->ls(REMOTE_DIR);
#
# Loop through remote files and print each filename
#
foreach ($remotefiles){
my $file = $_;
my $filename = $file->{filename};
if($filename ne "." && $filename ne ".."){
print"the filename is $filename";
}
}
I am receiving an error when I compile it -
C:\development>perl ConvertPDFs.pl
password authentication not available, IO::Pty is not installed or failed to loa
d: Can't locate IO/Pty.pm in #INC (#INC contains: C:/Perl64/site/lib C:/Perl64/l
ib .) at C:/Perl64/site/lib/Net/SFTP/Foreign/Backend/Unix.pm line 256.
at ConvertPDFs.pl line 20.
Not sure what the problem is.
Pseudo-ttys are a unix construct. If a module requires IO::Pty, it won't run on Windows (though maybe on cygwin). On the plus side, the error message makes it sound like Net::SFTP::Foreign only uses IO::Pty for password-based authentication, so you could avoid the problem by switching to key-based authentication.

Why do I get the error "Missing required arguments: personality, transport" when using Net::Appliance::Session?

After playing dependency hell with a server that does not have internet access I finally was able to get a script running. Problem is I get the following error and I have no idea how to find what is missing or wrong:
Missing required arguments: personality, transport at (eval 50) line 75.
The code is:
#!/usr/bin/perl
use Net::Appliance::Session;
my $s = Net::Appliance::Session->new( Host => '10.9.217.144', Transport => 'SSH', );
$s->connect( Name => 'cworks', Password => '****' );
print $s->cmd('show dialer | i :');
print "*********************\n**********************\n";
print $s->cmd('show ISDN stat | i ACTIV');
print "*********************\n**********************\n";
print $s->cmd('show ver');
$s->close;
According to the documentation, the new method has two required arguments:
personality => $name (required)
Tells the module which "language" to use when talking to the connected device, for example ios for Cisco IOS devices. There's a list of all the supported platforms in the Phrasebook documentation. It's also possible to write new phrasebooks.
transport => $backend (required)
The name of the transport backend used for the session, which may be one of Telnet, SSH, or Serial.
You need to change Transport to transport and add a personality option, as in the example in the docs:
my $s = Net::Appliance::Session->new({
personality => 'ios',
transport => 'SSH',
host => 'hostname.example',
});

Perl WWW::Mechanize methods not working in AIX

I have a simple requirement of screen scraping a web-page (simple URL based reports) and direct the HTML response to an output file. The URL will however redirect to an authentication (HTTPS Login) page with "form based" authentication (no javascript) and upon authentication the report I am trying to view should show up in the $response (as HTML). Interestingly, my code is working just fine in a Windows machine, however the same code below is not working in AIX machine and it looks like the click_button() function call does nothing. I have tried click(), submit(), but none is working so instead of getting the actual report all I get is the logon screen in the HTML output file. Any ideas, what can be wrong?
use WWW::Mechanize;
use strict;
my $username = "admin";
my $password = "welcome1";
my $outpath = "/home/data/output";
my $fromday = 7;
my $url = "https://www.myreports.com/tax_report.php";
my $name = "tax_report";
my $outfile = "$outpath/$name.html";
my $mech = WWW::Mechanize->new(noproxy =>'0');
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon++; # since it will start from 0
$mday--; # yesterdays date (to day)
$fromday = $mday - $days; #(from day)
#Create URL extension for generating report with previous date
my $dt_range = "?Y&dc_date1=$mon%2F$fromday%2F$year&dc_date2=$mon%2F$mday%2F$year";
my $url = $url . $dt_range;
$mech->get($url);
$mech->field(login => "$username");
$mech->field(passwd => "$password");
$mech->add_handler("request_send", sub { shift->dump; return });
$mech->add_handler("response_done", sub { shift->dump; return });
$mech->click_button(value=>"Login now");
my $response = $mech->content();
print "Generating report: $name...\n";
open (OUT, ">>$outfile")|| die "Cannot create report file $outfile";
print OUT "$response";
close OUT;
The WWW::Mechanize version in both the Machines are same i.e. 1.54 but the Win machine perl version is 5.10.1 whereas the AIX machine's Perl version is 5.8.8.
Other Alternatives Used -
my $inputobject=$mech->current_form()->find_input( undef,'submit' );
print $inputobject->value . "\n";
$mech->click_button(input => $inputobject);
print $mech->status() . "\n";
The $inputobject shows the correct button element as in the HTML source and the second print returns a status of 200 which apparently stands for OK. But its still not working in the AIX machine.
UPDATE- It seems that the site I am trying to connect to has an un-trusted SSL certificate. I tried the program on three different machines Windows PC, Mac and AIX. On the Windows Machine the program works and I was able to login to the website through the browsers (Chrome, Firefox,IE). However in Mac, the login just won't work (through the browsers) and it shows an un-trusted certificate error (or warning!) this probably means the proxy settings are not set up, the Perl program won't work either. And lastly the AIX where the Perl is not working as well. Not sure how to bypass this un-trusted SSL certificate issue here. Any help will be appreciated.
UPDATE2: Included below lines of code in the script to see logging details and found that I was being re-directed (HTTP 302) since my IP was filtered by the server Firewall. Once the AIX ip was added to the server's firewall exception the script worked perfectly. The two lines below were the life saver-
$mech->add_handler("request_send", sub { shift->dump; return });
$mech->add_handler("response_done", sub { shift->dump; return });
Can you use the following line before my $mech = WWW::Mechanize->new(noproxy =>'0'); of your perl code and try again ?
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;

Why can't I connect to my CAS server with Perl's AuthCAS?

I'm attempting to use an existing CAS server to authenticate login for a Perl CGI web script and am using the AuthCAS Perl module (v 1.3.1). I can connect to the CAS server to get the service ticket but when I try to connect to validate the ticket my script returns with the following error from the IO::Socket::SSL module:
500 Can't connect to [CAS Server]:443 (Bad hostname '[CAS Server]')
([CAS Server] substituted for real server name)
Symptoms/Tests:
If I type the generated URL for the authentication into the web browser's location bar it returns just fine with the expected XML snippet. So it is not a bad host name.
If I generate a script without using the AuthCAS module but using the IO::Socket::SSL module directly to query the CAS server for validation on the generated service ticket the Perl script will run fine from the command line but not in the browser.
If I add the AuthCAS module into the script in item 2, the script no longer works on the command line and still doesn't work in the browser.
Here is the bare-bones script that produces the error:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use AuthCAS;
use CGI::Carp qw( fatalsToBrowser );
my $id = $ENV{QUERY_STRING};
my $q = new CGI;
my $target = "http://localhost/cgi-bin/testCAS.cgi";
my $cas = new AuthCAS(casUrl => 'https://cas_server/cas');
if ($id eq ""){
my $login_url = $cas->getServerLoginURL($target);
printf "Location: $login_url\n\n";
exit 0;
} else {
print $q->header();
print "CAS TEST<br>\n";
## When coming back from the CAS server a ticket is provided in the QUERY_STRING
print "QUERY_STRING = " . $id . "</br>\n";
## $ST should contain the received Service Ticket
my $ST = $q->param('ticket');
my $user = $cas->validateST($target, $ST); #### This is what fails
printf "Error: %s\n", &AuthCAS::get_errors() unless (defined $user);
}
Any ideas on where the conflict might be?
The error is coming from the line directly above the snippet Cebjyre quoted namely
$ssl_socket = new IO::Socket::SSL(%ssl_options);
namely the socket creation. All of the input parameters are correct. I had edited the module to put in debug statements and print out all the parameters just before that call and they are all fine. Looks like I'm going to have to dive deeper into the IO::Socket::SSL module.
As usually happens when I post questions like this, I found the problem. It turns out the Crypt::SSLeay module was not installed or at least not up to date. Of course the error messages didn't give me any clues. Updating it and all the problems go away and things are working fine now.
Well, from the module source it looks like that IO::Socket error is coming from get_https2
[...]
unless ($ssl_socket) {
$errors = sprintf "error %s unable to connect https://%s:%s/\n",&IO::Socket::SSL::errstr,$host,$port;
return undef;
}
[...]
which is called by callCAS, which is called by validateST.
One option is to temporarily edit the module file to put some debug statements in if you can, but if I had to guess, I'd say the casUrl you are supplying isn't matching up to the _parse_url regex properly - maybe you have three slashes after the https?