Perl WWW::Mechanize JSESSION issue - perl

I am having a problem getting/staying logged in with perl mechanize to a website
Looking at the headers, it appears that the JSESSIONID keeps changing. I am using a cookie jar, but I think it's getting overwritten somehow.
#!/usr/bin/perl
use strict;
use warnings;
use WWW::Mechanize;
use HTTP::Cookies;
use Crypt::SSLeay;
use LWP::UserAgent;
use Crypt::SSLeay::CTX;
use Crypt::SSLeay::Conn;
use Crypt::SSLeay::X509;
use LWP::Simple qw(get);
use LWP::Debug;
my $cookie_jar = HTTP::Cookies->new(ignore_discard => 1);
my $agent = WWW::Mechanize->new(cookie_jar => $cookie_jar, noproxy=>0);
$agent->agent_alias('Linux Mozilla');
$ENV{HTTPS_CA_DIR} = 'cert/';
my $user = 'xxxx';
my $pass = 'xxxx';
my $url = '';
print "\n\n=========================================================\nGOING TO LOGIN PAGE:\n";
my $res = $agent->get($url);
for my $key ( $res->header_field_names() ) {
print $key, " : ", $res->header( $key ), "\n";
}
print "cookie: ".$agent->cookie_jar->as_string();
$agent->form_name('loginForm');
$agent->set_fields(
userId => $user,
password => $pass
);
$agent->submit();
print "\n\n=========================================================\nREDIRECT:\n";
my $res = $agent->submit();
for my $key ( $res->header_field_names() ) {
print $key, " : ", $res->header( $key ), "\n";
}
print "cookie: ".$agent->cookie_jar->as_string();
my $cUrl = '';
$cookie_jar->revert;
print "\n\n=========================================================\nGOING TO CAMPAIGN PAGE:\n";
my $res = $agent->get($cUrl);
for my $key ( $res->header_field_names() ) {
print $key, " : ", $res->header( $key ), "\n";
}
print "cookie: ".$agent->cookie_jar->as_string();

I am not sure why this worked, but I was able to resolve this by utilizing LWP::ConnCache
$agent->conn_cache(LWP::ConnCache->new());

Related

Error Cisco Prime HTTP GET request

I'm trying to make an HTTP GET request with Cisco Prime:
#!/opt/local/bin/perl -w
use strict;
use JSON-support_by_pp;
use LWP 5.64;
use LWP::UserAgent;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $ua = LWP::UserAgent->new;
my $BASE_URL = 'https://Host_name/webacs/api/v1/';
my $UN = "Username";
my $PW = "Password";
sub fetch ($) {
my ( $url ) = #_;
my $req = HTTP::Request->new( GET => $BASE_URL . $url );
$req->authorization_basic( $UN, $PW );
return $ua->request( $req )->content or die( "Cannot read from " . $BASE_URL . $url );
}
my $content = fetch( 'data/AccessPoints.json?.full=true' );
my $json = new JSON;
# these are some nice json options to relax restrictions a bit:
my $json_text =
$json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode( $content );
foreach my $ap ( #{ $json_text->{queryResponse}->{'entity'} } ) {
print "------------------------\nAccess Point " . $ap->{'accessPointsDTO'}->{'#id'} . "\n";
print "Model:" . $ap->{'accessPointsDTO'}->{'model'} . "\n";
print "MAC Address:" . $ap->{'accessPointsDTO'}->{'macAddress'} . "\n";
print "Serial Number:" . $ap->{'accessPointsDTO'}->{'serialNumber'} . "\n";
print "Software Version:" . $ap->{'accessPointsDTO'}->{'softwareVersion'} . "\n";
print "Status:" . $ap->{'accessPointsDTO'}->{'status'} . "\n";
print "Location:" . $ap->{'accessPointsDTO'}->{'location'} . "\n";
What do I do wrong? I have already tried with curl in shell and it works:
curl --tlsv1 --user USER:PASSWORD--insecure https://Host_name/webacs/api/v1/data/AccessPoints.json?.full=true
but my Perl script doesn't work.
I have this error:
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "Can't connect to 10....") at ersteProbe.pl line 28.
Fix already. Thank you Borodin :)
New question:
I need authentication for Cisco Prime.
Code works already, but authentication doesn't work.
I have with error
500 Can't connect to 10.10.10.10:443 (certificate verify failed) at ersteProbeAuth.pl line 27.
Line 27:
die $res->status_line unless $res->is_success;
I'm rather new in Perl und cann't fix this myself. If you have Idee, I'll be happy :)
#!/opt/local/bin/perl -w
use strict;
use warnings;
use JSON -support_by_pp;
use LWP 5.64;
use LWP::UserAgent;
use MIME::Base64;
use REST::Client;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $ua = LWP::UserAgent->new;
my $BASE_URL = 'https://10.10.10.10/webacs/api/v1/';
my $UN='admin';
my $PW='admin';
# coding with Base 64
my $sys_id='Balalalalalal';
my $encoded_auth = encode_base64("$UN:$PW", '');
sub fetch {
my ($url) = #_;
my $res = $ua->get($BASE_URL . $url,
{'Authorization' => "Basic $encoded_auth",
'Accept' => 'application/json'});
die $res->status_line unless $res->is_success;
my $json = $res->decoded_content;
return $json
}
my $content = fetch('data/AccessPoints.json?.full=true/$sys_id');
my $json = new JSON;
# these are some nice json options to relax restrictions a bit: my$json_text=$json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($content);
foreach my $ap (#{$json_text->{queryResponse}->{'entity'}}){
print "------------------------\nAccess Point ".$ap->{'accessPointsDTO'}->{'#id'}."\n";
print "Model:".$ap->{'accessPointsDTO'}->{'model'}."\n";
print "MAC Address:".$ap->{'accessPointsDTO'}->{'macAddress'}."\n";
print "Serial Number:".$ap->{'accessPointsDTO'}->{'serialNumber'}."\n";
print "Software Version:".$ap->{'accessPointsDTO'}->{'softwareVersion'}."\n";
print "Status:".$ap->{'accessPointsDTO'}->{'status'}."\n";
print "Location:".$ap->{'accessPointsDTO'}->{'location'}."\n";
}
It's hard to tell what's wrong without access to the web page, but almost certainly your request has failed
I suggest you replace your fetch subroutine with this
sub fetch {
my ( $url ) = #_;
my $res = $ua->get( $BASE_URL . $url );
die $res->status_line unless $res->is_success;
my $json = $res->decoded_content;
return $json;
}
Print your raw answer from server in console.
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "Can't connect to 10....")
"Can't connect to 10...."
Maybe, your code is not have connect

Moving gmail messages with Net::IMAP::Simple

I am trying to use Net::IMAP::Simple to move mail to an old_messages folder after I have read and stripped the attachments from them, but when I do it all of the moved messages are blank and from "unknown sender", and the inbox is unchanged. I've checked around and nobody seems to have had this problem before.
I have also tried this using both Email::Simple and Email::MIME as the $es object passed as an argument in the statement
$imap->put( 'OLD_MESSAGES', $es, "") or warn $imap->errstr
but neither worked.
Here's my code using Email::MIME
use strict;
use warnings;
# required modules
use Net::IMAP::Simple;
use Email::MIME;
use IO::Socket::SSL;
use Email::MIME::Attachment::Stripper;
# fill in your details here
my $username = 'usersite.com';
my $password = 'password';
my $mailhost = 'imap.gmail.com';
# Connect
my $imap = Net::IMAP::Simple->new( $mailhost, port => 993, use_ssl => 1, )
|| die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";
# Log in
if ( !$imap->login( $username, $password ) ) {
print STDERR "Login failed: " . $imap->errstr . "\n";
exit( 64 );
}
# Look in the the INBOX
my $nm = $imap->select( 'INBOX' );
# How many messages are there?
my ( $unseen, $recent, $num_messages ) = $imap->status();
print "unseen: $unseen, recent: $recent, total: $num_messages\n\n";
my $filepath = "C:/Users/doug/Desktop/gmail/";
## Iterate through unseen messages
for ( my $i = 1 ; $i <= $nm ; $i++ ) {
if ( !$imap->seen( $i ) ) {
next;
}
else {
my $es = Email::MIME->new( join '', #{ $imap->get( $i ) } );
#my $es = Email::MIME->new( join '', #{ $imap->top($i) } );
my $text = $es->body;
my $stripper = Email::MIME::Attachment::Stripper->new( $es );
my #attachments = $stripper->attachments;
printf(
"[%03d] %s\n\t%s\n%s",
$i,
$es->header( 'From' ),
$es->header( 'Subject' ), $text
);
my $l = 0;
foreach $_ ( #attachments ) {
my $fh = IO::File->new();
binmode( $fh );
open( $fh, '>', "$filepath" . "$_->{filename}" );
print $fh "$_->{payload}\n";
$fh->close;
}
$imap->put( 'OLD_MESSAGES', $es, "" ) or warn $imap->errstr;
}
}
# Disconnect
$imap->quit;
exit;
I had to strip down my code, but below is the gist of it. Works for me before I cut it out and pasted here, lemme know if it works else i'll edit it
use Mail::IMAPClient;
use Email::MIME::Attachment::Stripper;
use other stuff as needed....
# login
my $sock = IO::Socket::SSL->new(PeerAddr=>'imap.gmail.com',PeerPort=>993);
my $imap = Mail::IMAPClient->new(Socket => $sock, User => $user, Password => $pass, Ignoresizeerrors => 1);
die $imap->LastError() unless $imap->IsAuthenticated();
# decoding mime (you can probably skip)
my $message = $imap->message_string(123);
my $decoded_mime = "";
my #decoded_list = MIME::Words::decode_mimewords($message);
for(my $i=0; $i<scalar(#decoded_list); ++$i) {
my #set = #{$decoded_list[$i]};
if(scalar(#set) == 1) {
$decoded_mime .= $set[0];
}
else {
eval {
Encode::from_to($set[0],$set[1],'utf-8');
};
if($#) { eval {}; }
$decoded_mime .= $set[0];
}
}
$message = $decoded_mime;
# Strip attachments
$mime = Email::MIME::Attachment::Stripper->new($message);
$mime = $mime->message; # convert to regular Email::MIME

Manually add parameters in perl cgi

I've written a cgi script and it does the following:
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw(:cgi-lib :standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
my $q = new CGI;
print $q->header;
print "<center>";
print $q->h1('Let\'s do something!');
print "</center>";
print $q->start_html(-title => 'Do something');
print $q->end_form;
our %in;
&ReadParse(%in);
my #keys = keys %in;
my #values = values %in;
main();
sub main{
print "<center>";
my $q0 = new CGI;
print $q0->start_form(
-name => 'sniff_button',
-method => 'POST',
-enctype => &CGI::URL_ENCODED,
);
print $q0->submit(
-name => 'button',
-value => 'Do something',
);
print $q0->end_form;
print "</center>";
}
What I want to do is add some parameters manually, because the next that depends on the previous state and not only on the current state (So I have to pass a parameter twice.).
I've done stuff with param() and URI, but none of them work. Any advice?
A hidden field is the answer:
sub main{
print "<center>";
my $q0 = new CGI;
print $q0->start_form(
-name => 'sniff_button',
-method => 'POST',
-enctype => &CGI::URL_ENCODED,
);
print $q0->hidden(
-name => 'machine_state',
-default => 'some_previous_value');
print $q0->submit(
-name => 'button',
-value => 'Do something',
);
print $q0->end_form;
print "</center>";
}

formatting output data to an excel file

This program gets numeric values from the web for each of the values in my #values array
I want these values to be printed out in a table which looks like
il9 il8 il7
2012 v1 b1
2011 v2 b2
2010 v3 b3
.
.
2000 v12 b12
where v1 .. v12 are values for the first variable in #values etc. here is my program please help me structure it. Is there an escape character that could take me back to the first line of the program in perl
thanks
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use URI;
my $browser = LWP::UserAgent->new;
$browser->timeout(10);
$browser->env_proxy;
open(OUT, ">out");
my $i = 2013;
while ($i-- > 2000){print OUT "$i\n"}
my $a = 2013 ;
my $base = 'http://webtools.mf.uni-lj.si/public/summarisenumbers.php';
my #values = ('il9', 'il8', 'il6' );
foreach my $value (#values) {
print OUT "$value \n"
while ($a-- > 2000){
my $b = $a + 1;
my $c = $b + 1;
my $query = '?query=('.$value.')'.$a.'[dp] NOT '.$b.'[dp] NOT '.$c.'[dp]';
my $add = $base.$query;
#my $url = URI->new($add);
#my $response = $browser->get($url);
#if($response->is_success) {print OUT $response->decoded_content;}
#else {die $response->status_line};
print OUT "$query\n";
} $a = 2013; print OUT
}
close(OUT);
Pay more attention to formatting/indentation and variable naming - it will help you a lot.
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
my $base_url = 'http://webtools.mf.uni-lj.si/public/summarisenumbers.php';
my #values = ( 'il9', 'il8', 'il6' );
my $stat_data = {};
my $browser = LWP::UserAgent->new;
$browser->timeout(10);
$browser->env_proxy;
for my $value ( #values ) {
for my $year ( 2010 .. 2013 ) {
my $query = '?query=(' . $value . ')' . $year .'[dp] NOT ' . ($year+1) . '[dp] NOT ' . ($year+2) .'[dp]';
my $url = "$base_url$query";
my $response = $browser->get( $url );
if( $response->is_success ) {
## store the fetched content in a hash structure
$stat_data->{$year}->{$value} = $response->decoded_content;
}
else {
die $response->status_line;
}
}
}
## print the header
print "\t", join( "\t", #values ), "\n";
## print the data by the years in reverse order
for my $year ( reverse sort keys %{$stat_data} ) {
print $year;
for my $value ( #values ) {
print "\t", $stat_data->{$year}->{$value};
}
print "\n";
}

Perl: WWW:Mechanize, getting Facebook profile image?

#!/usr/bin/perl
#USE DECLARATIONS
use strict;
use warnings;
use WWW::Mechanize;
use Term::ANSIColor;
#VARIABLE DECLARATIONS
my $mech = WWW::Mechanize->new();
my $img;
my $title;
my $pic_page;
my $url;
my $count;
my #links;
#CONNECT TO FACEBOOK
$url = 'https://www.facebook.com/';
$mech = WWW::Mechanize->new();
$mech->agent_alias( 'Linux Mozilla' );
$mech->get( $url );
$title = $mech->title();
#LOGIN FORM
print "Connected to Facebook.\n";
print "Logging in...";
$mech->form_id("login_form");
$mech->field("email",'my#email.com');
$mech->field("pass",'mypass');
$mech->click();
print "done!\n";
#NAVIGATE TO USER PAGE
$mech->get("https://www.facebook.com/some.profile1234");
$title = $mech->title();
print "Finding $title 's profile pictue...\n";
#FIND PROFILE PICTURE
$img = $mech->find_image(url_regex => qr/s160x160/, );
print $img->url();
downloadImage($img->url(),$mech->title().".jpg");
sub downloadImage
{
my $local_file_name = $_[1];
my $b = WWW::Mechanize->new;
print "Downloading: $_[1]...";
$b->get( $_[0], ":content_file" => $local_file_name );
print "done!\n";
}
With this code I just want to download profile picture of a given person (#NAVIGATE TO USER PAGE) and save it. However, I get an error saying essentially that no images could be found! WHYYY? (I am using the $mech->find_image(url_regex => qr/s160x160/,) to find the image on the profile page.)
You are using new instance of Mechanize in your downloadImage sub. And this instance is not authorized by Facebook.
Try this:
downloadImage($img->url(),$mech->clone() );
sub downloadImage
{
my $mech = $_[1];
print "Downloading: $_[1]...";
$mech->get( $_[0], ":content_file" => $mech->title() . ".jpg" );
print "done!\n";
}