How do I authenticate into Gmail using Perl? - perl

I've installed this module to gain access and controls within a Gmail inbox. However, when I try to connect through a small Perl script and test the functionality, I get this error message.
Error: Could not login with those credentials - could not find final URL
Additionally, HTTP error: 200 OK
This is an error built within the Gmail.pm module.
I can ping the URL in question ( https://www.google.com/accounts/ServiceLoginBoxAuth ) so I feel that the trouble isn't finding the URL. Furthermore, I know the credentials are correct and work at that URL because I have tried them manually.
I'm using this script for testing. I have supplied my credentials in the appropriate places.
I've also installed this module with the same type of error.
Any idea why I'm getting blocked?

Use Mail::IMAPClient as shown below. To get pass SSL authentication through Mail::IMAPClient, you should have IO::Socket::SSL from Net::SSLeay installed. If so this works like a charm.
#!/usr/bin/env perl
use strict; use warnings;
use Mail::IMAPClient;
# Connect to IMAP server
my $client = Mail::IMAPClient->new(
Server => 'imap.gmail.com',
User => 'yourusername',
Password => 'yourp4a55w0r&',
Port => 993,
Ssl => 1,
)
or die "Cannot connect through IMAPClient: $!";
# List folders on remote server (see if all is ok)
if ( $client->IsAuthenticated() ) {
print "Folders:\n";
print "- ", $_, "\n" for #{ $client->folders() };
};
# Say so long
$client->logout();

I am successfully accessing a gmail account (google apps account to be precise) using Mail::POP3Client

If you cannot access gmail through normal POP3 or IMAP either, then you have a configuration problem rather than a programming problem.
I fetch my mail from gmail (actually Google Apps, which uses the same interface), using configuration details described here: http://download.gna.org/hpr/fetchmail/FAQ/gmail-pop-howto.html
(This answer is far more appropriate for Super User though!)

You can tried with the following module
Mail::Webmail::Gmail

You can use the following code also
use warnings;
use strict;
use Mail::POP3Client;
use IO::Socket::SSL;
use CGI qw(:standard);
my $cgi = new CGI;
my $LOG ;
open $LOG , ">>filename" ;
my $username = 'name#gmail.com';
my $password = '*******' ;
chomp($password);
my $mailhost = 'pop.gmail.com';
my $port = '995';
$cgi->header();
my $pop = new Mail::POP3Client(
USER => $username,
PASSWORD => $password,
HOST => $mailhost,
PORT => $port,
USESSL => 'true',
DEBUG => 0,
);
if (($pop->Count()) < 1) {
exit;
}
print $pop->Count() . " messages found!:$!\n";
for(my $i = 1; $i <= $pop->Count(); $i++) {
foreach($pop->Head($i)) {
/^(From|Subject|Email):\s+/i && print $_, "\n";
}
$pop->BodyToFile($LOG,$i);
}
$pop->Close();
exit;

Related

How to connect to a ldap through a proxy ldap?

I've a little issue. At work, we will shortly use a proxy ldap to connect to our ldap.
However, my perl script used to connect directly to the ldap, and I can't find the right way to connect to the ldap through the ldap proxy.
The ldap team told me to simply change "my.local.ldap.org" by the url of the proxy.
But when I do that, I get nothing back except the error "Can't contact LDAP server at myscript.pl line X, < DATA> line 403."
I'm at my wits end, since I'm pretty new to perl.
How can I connect to my ldap throught the ldap proxy and get my data ?
There is my perl code :
#!/usr/bin/perl
use warnings;
use strict;
use Net::LDAP;
use Net::SMTP;
use MIME::Lite;
use Getopt::Std;
connect_ldap();
sub connect_ldap {
my #attributs = qw(uid subsidiary preferredLanguage);
my $ldap = Net::LDAP->new(
"my.local.ldap.org",
port => 389
) or die open (STDERR, ">&SDTOUT");
my $mesg = $ldap->bind (
"cn=app_readonly,ou=account,ou=security,o=oubase",
password => "mypassword"
);
$mesg = $ldap->search(
base => "o=oubase",
scope => "sub",
filter => "(&(objectclass=inetOrgPerson)(|(subsidiary=sub1)(subsidiary=sub2))(role=id=app_access,id=APP,*))",
attrs => [ #attributs ]
);
printf "COUNT : %s\n", $mesg->count;
foreach my $entry ($mesg->entries) {
$entry->dump;
}
print "==========================================\n";
$mesg = $ldap->unbind;
$ldap->unbind;
}
In general, there should not be any difference connecting through a proxy (provided that it is an LDAP proxy) compared to connecting to an LDAP server directly as long as the LDAP proxy is setup properly. Did you try telnetting to the host/port of the proxy to see if you got the correct connection information?

Resolving issue with Net::OpenSSH and passing multiple commands to a router

I'm working on moving a Perl script that pushed commands to routers. We have turned off telnet, so I'm working on getting SSH to work. After looking at a number of SSH libraries in Perl, I've opted to use Net::OpenSSH. I have no problem logging in and passing commands to the routers, but the problem I'm having is with entering config mode and subsequently passing a command.
The problem is that with each command entered, the underlying system appears to logout then reenter with the next subsequent command. For example with a Juniper router I'm trying to do the following:
edit private
set interfaces xe-1/3/2 description "AVAIL: SOMETHING GOES HERE"
commit
exit
quit
Tailing the syslog from the router I'm seeing something like this...
(...)
UI_LOGIN_EVENT: User 'tools' login, class 'j-remote-user' [65151], ssh-connection 'xxx.xxx.xxx.xxx 42247 xxx.xxx.xxx.xxx 22', client-mode 'cli'
UI_CMDLINE_READ_LINE: User 'tools', command 'edit private '
UI_DBASE_LOGIN_EVENT: User 'tools' entering configuration mode
UI_DBASE_LOGOUT_EVENT: User 'tools' exiting configuration mode
UI_LOGOUT_EVENT: User 'tools' logout
UI_AUTH_EVENT: Authenticated user 'remote' at permission level 'j-remote-user'
UI_LOGIN_EVENT: User 'tools' login, class 'j-remote-user' [65153], ssh-connection 'xxx.xxx.xxx.xxx 42247 xxx.xxx.xxx.xxx 22', client-mode 'cli'
UI_CMDLINE_READ_LINE: User 'tools', command 'set interfaces '
UI_LOGOUT_EVENT: User 'tools' logout
(...)
As you notice I'm getting a LOGOUT_EVENT after each command entered. Of course exiting config mode immediately after entering it causes the set interfaces command to fail as it's no longer in config mode.
The Perl code I'm using is as follows...
#!/usr/bin/perl -w
use strict;
use lib qw(
/usr/local/admin/protect/perl
/usr/local/admin/protect/perl/share/perl/5.10.1
);
use Net::OpenSSH;
my $hostname = "XXXXX";
my $username = "tools";
my $password = "XXXXX";
my $timeout = 60;
my $cmd1 = "edit private";
my $cmd2 = 'set interfaces xe-1/3/2 description "AVAIL: SOMETHING GOES HERE"';
my $cmd3 = "commit";
my $cmd4 = "exit";
my $ssh = Net::OpenSSH->new($hostname, user => $username, password => $password, timeout => $timeout,
master_opts => [-o => "StrictHostKeyChecking=no"]);
$ssh->error and die "Unable to connect to remote host: " . $ssh->error;
my #lines = eval { $ssh->capture($cmd1) };
foreach (#lines) {
print $_;
};
#lines = eval { $ssh->capture($cmd2) };
foreach (#lines) {
print $_;
};
#lines = eval { $ssh->capture($cmd3) };
foreach (#lines) {
print $_;
};
#lines = eval { $ssh->capture($cmd4) };
foreach (#lines) {
print $_;
};
$ssh->system("quit");
The sequence of events is the same as when telnet was used. The only real change was in using SSH objects verses Telnet objects. I'm stumped. Any ideas you could provide would be quite helpful.
[SOLVED, sort of]
The suggestion let Net::Telnet do the driving was the correct one. The following code works...
#!/usr/bin/perl -w
use strict;
use Net::OpenSSH;
use Net::Telnet;
use Data::Dumper;
my $promptEnd = '/\w+[\$\%\#\>]\s{0,1}$/o';
my $cmd1 = "show system uptime | no-more";
my $cmd2 = "show version brief | no-more";
my $hostname = "xxx.xxx";
my $username = "xxxxxxx";
my $password = "xxxxxxx";
my $timeout = 60;
my $ssh = Net::OpenSSH->new(
$hostname,
user => $username,
password => $password,
timeout => $timeout,
master_opts => [ -o => "StrictHostKeyChecking=no" ]
);
$ssh->error and die "Unable to connect to remote host: " . $ssh->error;
my ( $fh, $pid ) = $ssh->open2pty( { stderr_to_stdout => 1 } );
my %params = (
fhopen => $fh,
timeout => $timeout,
errmode => 'return',
);
$conn = Net::Telnet->new(%params);
$conn->waitfor($promptEnd);
#lines = $conn->cmd($cmd1);
foreach (#lines) {
print $_;
}
#lines = $conn->cmd($cmd2);
foreach (#lines) {
print $_;
}
$conn->cmd("quit");
The problem I'm having is that I can't seem to separate the code into subroutines. Once the $conn object is returned from a subroutine, the underlying ssh connection drops. I need to separate this logic in order to not have to rewrite many, many programs and lines of code that relay on this pusher routine. However that problem I'll direct to another question.
[Edit, fully solved]
Just an update in case anyone needs to do something similar.
While the above worked very well when run under a single subroutine, I found that any time I passed the handle to another subroutine, the telnet handle remained open, but the ssh connection dropped.
To solve this I found that if I passed the ssh handle to another subroutine, then later attached the open2pty, and attached Net::Telnet, then I could pass the Net::Telnet handle between subroutines without the underlying ssh connection dropping. This also worked for Net::Telnet::Cisco as well. I have this code working well with Cisco, Juniper, and Brocade routers.
You should also consider adding a few more parameters to the Net::Telnet->new() because it is interacting with ssh rather than a TELNET server.
-telnetmode => 0
-output_record_separator => "\r",
-cmd_remove_mode => 1,
Because there is no TELNET server on remote side, -telnetmode => 0 turns off TELNET negotiation.
The end-of-line is most likely just a carriage-return (i.e. -output_record_separator => "\r") rather than the TCP or TELNET combination of carriage-return linefeed ("\r\n").
Always strip the echoed back input -cmd_remove_mode => 1
There are several possibilities:
Some routers accept having the sequence of commands sent up front via stdin:
my $out = $ssh->capture({stdin_data => join("\r\n", #cmds, '')})
In other cases you will have to use something like Expect to send a command, wait for the prompt to appear again, send another command, etc.
If you were using Net::Telnet before, the Net::OpenSSH docs explain how to integrate both (though I have to admit that combination is not very tested).
Also, some routers provide some way to escape to a full Unix-like shell. I.e., preppending the commands with a bang:
$ssh->capture("!ls");

check cpanel authorisation with perl script and write file

i was working on a perl script that check multi cpanel accounts authorisation for weak passwords , like that a server owner can check if his users are using a weak password and when connected to one write a file in the /public_html/ dir to informe the user .
i was thinking of using cPanel::PublicAPI :
my $cp = cPanel::PublicAPI->new(
'user' => $username,
'pass' => $password,
'host' => $host,
);
but i didn't know how to check if connected and how to write file in it ( i've looked here)
i found a script that check for authorisation :
$authx = encode_base64($user.":".$passwd);
my $sock = IO::Socket::INET->new(Proto => "tcp",PeerAddr => "$host", PeerPort => "$port") || print " [-] Can not connect to the host";
print $sock "GET / HTTP/1.1";
print $sock "Authorization: Basic $authx";
print $sock "Connection: Close";
read $sock, $answer, 128;
close($sock);
if ($answer =~ /Moved/) {
print " passord is : $passwd\n";
}
but this is too slow and can't write file using it .
sorry for my english :) . regards
i didn't know how to check if connected
Just make a request/method call on the $cp object. If it fails, the $cp->{error} attribute is set.
how to write file
use autodie qw(:all);
open my $fh, '>', '/home/user/message_from_the_admin';
$fh->print('You made a boo-boo.');
See chapter 9.3: Files in Modern Perl.

FTP in perl error?

Is there anything wrong the script bewlow, because I just can't login.....
And I'm sure I'm using the right username and password.
(Cannot login Login incorrect.)
sub UploadToFTPServer()
{
my $filename = shift;
$ftp = Net::FTP->new($FTPSERVER, Debug => 0) ;
if ($ftp) {
eval {
$ftp->login($USERNAME,$PASSWORD) or warn "Cannot login ", $ftp->message;
$ftp->binary();
$ftp->putfile($filename) or warn "Cannot upload ($filename)", $ftp->message;
$ftp->quit();
};
}
else {
warn "Cannot connect to $FTPSERVER: $#";
}
}
Start your script off with this:
use strict;
use warnings;
Then make sure that perl doesn't try to interpolate anything in your un/pw.
my $USERNAME = 'myname#gmail.com'; ## notice the single quotes
my $PASSWORD = 'mypass';
Given your error, it should work with those changes. It would have been easier to catch if the strict and warnings pragmas were used from the start.
Are you sure your testing from the same IP?
Also, try printing the username & password with quotes around them, as gpojd suggested.
Use the module "Net::FTP::Simple"
#send = Net::FTP::Simple->send_files({
username => $user,
password => $pass,
server => $host,
remote_dir => $path,
debug_ftp => 0,
files => [
$file,
],
});
print "The following files were retrieved successfully:\n\t",
join("\n\t", #send), "\n"
if #send;
Try $ftp->put instead of $ftp->putfile. I don't see putfile in the documentation.

Can't use an undefined value as a symbol reference

I'm trying to use an API for a Palo Alto Networks software. The code is supposed to submit username and ipaddress of user network logins to a web interface.
When I try using PANs' API with their sample code for a windows machine the following exception is thrown:
Can't use an undefined value as a symbol reference at
C:/Perl/lib/PAN/API.pm line 179 (#1)
PAN::API::UID::login('PAN::API::UID=HASH(0x7fd113828598)', 'SCU-DSM22/pmmertens', 172.16.6.117) called at API_events.pl line 12
This is the code-example that comes with the API documentation:
#!/usr/bin/perl -w
use strict;
use PAN::API;
my $useridagent = '10.0.0.99'; #I changed this to our PAN server address
my $useridapi = PAN::API::UID->new($useridagent);
my $user = $ENV{USERDOMAIN}.'/'.$ENV{USERNAME};
my $ipaddress = unpack('W4',gethostbyname($ENV{COMPUTERNAME}));
$useridapi->login($user,$ipaddress);
I've ensure that all variables are retrieved correctly. Substituting literal values did not help either. Googling this error turned up references about hard and soft references but I don't see any infractions of these rules in the code below.
This is the codeblock from PAN/Api.pm. Line 179 is where the print starts.
sub submit () {
my $self = shift;
use IO::Socket::INET;
use IO::Socket::SSL;
my $socket = IO::Socket::INET->new(PeerAddr => $self->{server},
PeerPort => $self->{port},
Proto => 'tcp');
my $socketssl = IO::Socket::SSL->start_SSL( $socket,
SSL_version =>'TLSv1');
print $socketssl $self->xml;
$socketssl->close;
$socketssl->stop_SSL;
}
Both the IO::Socket::INET and IO::Socket::SSL lines should have error checking. Something like:
my $socket = IO::Socket::INET->new(....)
or die "Failed to create socket: $!"
And:
my $socketssl = IO::Socket::SSL->start_SSL(...)
or die "Failed to start SSL: ".IO::Socket::SSL::errstr();
Although instead of die I might go with Carp::confess.