How can I connect to gmail from perl? - perl

I am trying to read messages from a gmail account, and the examples I've seen aren't working.
I started with this:
use Mail::IMAPClient;
use IO::Socket::SSL;
my $user = 'user\#mydomain.com';
my $pwd = 'password';
my $socket = IO::Socket::SSL->new(
PeerAddr => 'imap.gmail.com',
PeerPort => 993,
SSL_verify_mode => SSL_VERIFY_PEER,
)
or die "socket(): $#";
my $client = Mail::IMAPClient->new(
Socket => $socket,
User => $user,
Password => $pwd,
)
or die "new(): $#";
if ( $client->IsAuthenticated() ) {
print "Auth OK\n";
} else {
print "No auth\n";
}
This appears to work, but never authenticates. According to the documentation, Mail::IMAPClient->new should call login if username and password are provided.
I have tried calling client->login with no difference.
There are a few questions with similar content, but the answers state to use a different package (Mail::Webmail::Gmail is one, but it seems obsolete and doesn't work either)
The account is a google apps account, not a regular gmail account. I have enabled imap access for the account.
I also tried using Net::IMAP::Client, both with a google apps account and using my gmail account with an app-specific password, and get nothing but "Invalid credentials".
use Net::IMAP::Client;
my $user = 'user\#gmail.com';
my $pwd = ' app password';
my $imap = Net::IMAP::Client->new(
server => 'imap.gmail.com',
user => $user,
pass => $pwd,
ssl => 1, # (use SSL? default no)
ssl_verify_peer => 0, # (use ca to verify server, default yes)
port => 993 # (but defaults are sane)
) or die "Could not connect to IMAP server: $_";
$imap->login or
die('Login failed: ' . $imap->last_error);
Is there something I'm missing when trying to connect to gmail imap?

In Perl, the string "\#" inside single quotes is literally "\#".
Lose the \.

Related

Freeradius-Perl script using POP3 against Gmail

has anyone successfully authenticate against gmail using pop3 perl scripts in freeradiu 3? I'm following this tutorial(https://kerker.website/freeradiusgmail802-1x%e8%a8%ad%e5%ae%9apop3s/) but perl continues rejecting the user.
This is the script:
use Data::Dumper;
use Mail::POP3Client;
use IO::Socket::SSL;
sub authenticate {
my $pop = Mail::POP3Client->new(
USER => $RAD_REQUEST{'User-Name'},
PASSWORD => $RAD_REQUEST{'User-Password'},
HOST => "pop.gmail.com",
USESSL => 1,
DEBUG => 1,
);
if($pop->Connect()){
return RLM_MODULE_OK;
}else{
return RLM_MODULE_REJECT;
}
$pop->Close;
}
I can't post the output right now but it rejects the user and I haven't been able to debug the script. I just want to know if anyone has recently sucedded in authenticating gmail and how.

LDAP bind operation with Perl

I am trying to connect a LDAP server. Customer sent following 3 info to me:
IP address of LDAP server
username
password
I am using following code:
my $ldap = Net::LDAP->new ($ip_address) or die "$#";
my $mesg = $ldap->bind ( $username,
password => $password,
) or die $#;
my $result = $ldap->search(
base => $base,
filter => $filter
attrs => \#attributes,
);
die $result->error if $result->code;
$result->error value is :
'000004DC: LdapErr: DSID-0C090728, comment: In order to perform this operation a successful bind must be completed on the connection.,
According to message, bind is not successful. But it should die if it was unsuccessful. I changed password, wrote wrong value, it again did not die.
I dumped $mesg which is return value of bind and saw following message:
'80090308: LdapErr: DSID-0C0903C5, comment: AcceptSecurityContext error
But it is same with the correct username and password too. Username is 'itservice'. I am using as follow:
my $mesg = $ldap->bind ( 'itservice',
password => $password,
) or die $#;
I tried as follow but result is same
my $mesg = $ldap->bind ( 'cn=itservice',
password => $password,
) or die $#;
Is there any other format of using username or password?
The LDAP Bind request requires a valid DN for the user and not just a user name.
Usually, applications first do a search on userName to retrieve the user DN and then bind as the user.

connect to localhost failed (Connection refused) no (more) retries

I want to send an email using perl ,but when i execute the command as follows:
#./sendmail.sh "par1" "par2" "par3"
i got the error msg "connect to localhost failed (Connection refused) no (more) retries"
sendmail.sh:
/usr/bin/perl /code/sendmail.pl "$1" "$2" "$3";
sendmail.pl:
#!/usr/bin/perl -w
use Mail::Sendmail;
my $event1 = shift(#ARGV);
my $event2 = shift(#ARGV);
my $time = shift(#ARGV);
#my $info = shift(#ARGV);
my $datetime = `/bin/date "+20%y-%m-%d %H:%M:%S"`;
chomp $datetime;
$msg = "This is Monitor System speak:\n
The system discovers the events at $datetime.
Something may be abnormal, please check it. The detail is below:\n";
$msg = $msg."$event1 and $event2 at $time\n";
$msg = $msg."\n";
$msg = $msg."Any problem, check it from http://map_test.php\n\n\n";
$mail_subject = "Abnormal";
sendmail(
From => 'localhost',
To => 'test#mail.com',
Subject => $mail_subject,
Message => $msg,
);
Any help appreciated.
smtp stands for simple mail transfer protocol.
When you need to send an email your mail client needs to talk to an smtp server which will accept the message. Normally your internet service provider will provide an smtp host. If you look at your mail client it will need to have an smtp server configured to be able to send mail.
Ok so when you install the Mail::Sendmail module, it doesn't know what your smtp server will be. It is up to you to tell it. It provides a default of localhost which would often be true if your server is running a sendmail daemon.
The configuration of Mail::Sendmail is stored in a variable called
%Mail::Sendmail::mailcfg
You can change the value of the sendmail server using this snippet of code:
unshift #{$Mail::Sendmail::mailcfg{'smtp'}} , 'my.smtp.server';
You need to add this line of code to your script to set the smtp server.
It adds this server to an array which also includes localhost.
So if neither of the hosts work it will still print an error message about localhost which is slightly confusing.
If you use Data::Dumper to print the contents of the mailcfg variable it will look something like this:
#!/usr/bin/perl
use Mail::Sendmail;
use Data::Dumper;
unshift #{$Mail::Sendmail::mailcfg{'smtp'}} , 'my.smtp.server';
print Dumper(\%Mail::Sendmail::mailcfg);
Should return:
$VAR1 = {
'retries' => 1,
'smtp' => [
'my.smtp.server',
'localhost'
],
'delay' => 1,
'port' => 25,
'from' => '',
'debug' => 0,
'tz' => '',
'mime' => 1
};

Trying to send authenticated email using Net::SMTP::SSL

I'm attempting to send an authenticated email with the Net::SMTP::SSL module to a comcast email server. I'm using the following code.
#!/usr/bin/perl
use Net::SMTP::SSL;
use MIME::Base64;
$smtp = Net::SMTP::SSL->new
(
"smtp.comcast.net",
Hello => "host.comcast.net",
Port => 465,
Timeout => 30,
Debug => 1,
);
$smtp->datasend("AUTH LOGIN\n");
$smtp->response();
# Mailbox info
$smtp->datasend(encode_base64('username')); # username
$smtp->response();
$smtp->datasend(encode_base64('password')); # password
$smtp->response();
# Email from
$smtp->mail('user\#comcast.net');
# Email to
$smtp->to('user\#host.com');
$smtp->data();
$smtp->datasend("To: user\#host.com\n");
$smtp->datasend("From: user\#comcast.net\n");
$smtp->datasend("Subject: Test");
# Line break to separate headers from body
$smtp->datasend("\n");
$smtp->datasend("Blah\n");
$smtp->dataend();
$smtp->quit();
exit;
I'm basically following the code from here for comcast.
I've ran telnet and can connect to the smtp server on the port and I can issue the AUTH LOGIN and successfully login, but issuing the
$smtp->datasend("AUTH LOGIN\n");
always results in:
Can't call method "datasend" on an undefined value
I've also tried executing the auth method to login and that fails as well.
What am I missing here? I know it's something simple I'm overlooking.
Pretty much all of the Net::SMTP methods optionally set error codes, so I suspect that Net::SMTP::SSL does the same. Try the following for your constructor:
use Net::SMTP::SSL;
use MIME::Base64;
use strict;
use warnings;
my $smtp = Net::SMTP::SSL->new(
"smtp.comcast.net",
Hello => "host.comcast.net",
Port => 465,
Timeout => 30,
Debug => 1,
) or die "Failed to connect to mail server: $!";
Also, the fact that your smtp server is different than your Hello is a little suspect to me.
For email services that use STARTTLS, it's best to use the newer NET::SMTPS module. Try the following code:
my $msg = MIME::Lite ->new (
From => 'from#bellsouth.net',
To => 'to#bellsouth.net',
Subject => 'Test Message',
Data => 'This is a test',
Type => 'text/html'
);
my $USERNAME = 'from#bellsouth.net';
my $PASSWORD = 'abc123';
my $smtps = Net::SMTPS->new("smtp.mail.att.net", Port => 587, doSSL => 'starttls', SSL_version=>'TLSv1');
$smtps->auth ( $USERNAME, $PASSWORD ) or die("Could not authenticate with bellsouth.\n");
$smtps ->mail('from#bellsouth.net');
$smtps->to('to#bellsouth.net');
$smtps->data();
$smtps->datasend( $msg->as_string() );
$smtps->dataend();
$smtps->quit;
Originally from http://www.skipser.com/p/2/p/send-email-using-perl-via-live.com.html
Try this:
Email from
Change
$smtp->mail('user\#comcast.net'); to $smtp->mail('user#comcast.net'); without '\'
Email to
Change
$smtp->to('user\#host.com'); to $smtp->to('user#host.com'); without '\'

Connecting keeps closing?

so i'm having a problem trying to automatically login to a internal website. I'm able to send a post request but in the response I always get the Header Connection: close. I've tried to pass is through the post request but it still seems to respond with Connection: close. I want to be able to navigate through the website so I need the Connection: keep-alive so that i can send more request. Could anyone tell me what I'm doing wrong? here's the code:
#usr/bin/perl
#NetTelnet.pl
use strict; use warnings;
#Sign into cfxint Unix something...
use Net::Telnet;
# Create a new instance of Net::Telnet,
my $telnetCon = new Net::Telnet (Timeout => 10,
Prompt => '/bash\$ $/') or die "Could not make connection.";
my $hostname = 'cfxint';
# Connect to the host of the users choice
$telnetCon->open(Host => $hostname,
Port => 23) or die "Could not connect to $hostname.";
use WWW::Mechanize;
my $mech = WWW::Mechanize->new(cookie_jar => {});
&login_alfresco;
sub login_cxfint {
#get username and password from user
my $CXusername = '';
my $CXpassword = '';
# Recreate the login
# Wait for the login: message and then enter the username
$telnetCon->waitfor(match => '/login:/i');
# this method adds a \n to the end of the username, it mimics hitting the enter key after entering your username
$telnetCon->print($CXusername);
# does the same as the previous command but for the password
$telnetCon->print($CXpassword);
#Wait for the login successful message
$telnetCon->waitfor();
}
sub login_alfresco{
my $ALusername = '';
my $ALpassword = '';
$mech->get('http://documents.ifds.group:8080/alfresco/faces/jsp/login.jsp');
my $res = $mech->res;
my $idfaces = '';
if($res->is_success){
my $ff = $res->content;
if($ff =~ /id="javax.faces.ViewState" value="(.*?)"/){
$idfaces = $1;
}
else {
print "javax.faces /Regex error?\n";
die;
}
}
print $idfaces, "\n";
#Send the get request for Alfresco
$mech->post('http://documents.ifds.group:8080/alfresco/faces/jsp/login.jsp',[
'loginForm:rediretURL' =>,
'loginForm:user-name' => $ALusername,
'loginForm:user-password' => $ALpassword,
'loginForm:submit' => 'Login',
'loginForm_SUBMIT' => '1',
'loginForm:_idcl' => ,
'loginForm:_link_hidden_' => ,
'javax.faces.ViewState' => $idfaces], **'Connection' =>'keep-alive'**);
$res = $mech->res;
open ALF, ">Alfresco.html";
print ALF $mech->response->as_string;
if($res->is_success){
my $ff = $res->content;
if($ff =~ /id="javax.faces.ViewState" value="(.*?)"/){
$idfaces = $1;
}
else {
print "javax.faces /Regex error?\n";
die;
}
}
print $idfaces, "\n";
#Logout
$mech->post('http://documents.ifds.group:8080/alfresco/faces/jsp/extension/browse/browse.jsp', [
'browse:serach:_option' => '0',
'browse:search' => ,
'browse:spaces-pages' => '20',
'browse:content-pages' => '50',
'browse_SUBMIT' => '1',
'id' => ,
'browse:modelist' => '',
'ref'=>'',
'browse:spacesList:sort' => ,
'browse:_idJsp7' => ,
'browse:sidebar-body:navigator' => ,
'browse:contentRichList:sort' => ,
'browse:act' => 'browse:logout',
'outcome' => 'logout',
'browse:panel' => ,
'javax.faces.ViewState' => $idfaces,])
}
You can enable keep-alive by using a connection cache:
use LWP::ConnCache;
...
$mech->conn_cache(LWP::ConnCache->new);
All that header means is that the connection will be closed upon completion of the request, instead of being kept open for possible further requests. This is perfectly normal and should not interfere with sending the request.
EDIT: If you're sending a Connection:Keep-Alive and the server is still responding with Connection:Close, then the server configuration needs to be changed. The default for HTTP/1.1 is persistent connections, so the server must explicitly be configured to send Connection:Close. See Section 8 of RFC2616.