Unable to connect to outlook.office365.com for processing emails with Perl Module Mail::IMAPClient - perl

I have searched for days but finally run out of options, one of my clients move its emails accounts to "outlook.office365.com", now all my perl scripts fails because they have a different set of configurations on their platform, so i had to rewrite all of my perl scripts to make everything work again, i was aible to send emails with the module "Email::Sender::Transport::SMTP::TLS" but i didnt had the same luck using my old modules to read and proccess emails such as "Mail::POP3Client".
This is the code a try:
use Mail::IMAPClient;
use Email::MIME;
my $username = 'user';
my $password = 'pass';
my $server = 'outlook.office365.com';
print "Anon connect to IMAP\n";
my $imap = Mail::IMAPClient->new(
Server => $server,
Username => $username,
Password => $password,
Port => 993,
Ssl => 1,
Authmechanism => "PLAIN",
Debug => 1,
)or die "Cannot connect to $mailhost as $username: $#";
print "upgrading connection to TLS \n";
$imap->starttls
(
SSL_verify_mode => 0,
) or die "starttls failed: $#\n";
$imap->User($username);
$imap->Password($password);
print "Logging In\n";
$imap->login() or die "imap login failed: $#\n";
This is a solution that i have found on stackoverflow but it doesnt work for me, i checked my firewall configuration and everything is ok.
This is the output:
Anon connect to IMAP
Started at Fri Dec 16 13:54:25 2016
Using Mail::IMAPClient version 3.38 on perl 5.022001
Connecting with IO::Socket::SSL PeerAddr outlook.office365.com PeerPort 993 Proto tcp Timeout 600 Debug 1
ERROR: Unable to connect to outlook.office365.com: at C:/Perl64/site/lib/Mail/IMAPClient.pm line 370.
Mail::IMAPClient::connect(Mail::IMAPClient=HASH(0xcac170)) called at C:/Perl64/site/lib/Mail/IMAPClient.pm line 314
Mail::IMAPClient::new("Mail::IMAPClient", "Server", "outlook.office365.com", "Username", "user", "Password", "pass", "Port", 993, ...) called at dont.pl line 10
Cannot connect to as user: Unable to connect to outlook.office365.com: at dont.pl line 10.
To check my SSL connection:
openssl s_client -connect outlook.office365.com:993
Results:
* OK The Microsoft Exchange IMAP4 service is ready.
So any ideas?, what is wrong with this code?

EDIT: thanks to Max, finally a solution: removing startls allows to reach the login step.
use Mail::IMAPClient;
use Email::MIME;
my $username = 'user';
my $password = 'pass';
my $server = 'outlook.office365.com';
print "Anon connect to IMAP\n";
my $imap = Mail::IMAPClient->new(
Server => $server,
Port => 993,
Ssl => 1,
Authmechanism => "PLAIN",
Debug => 1,
)or die "Cannot connect to $mailhost as $username: $#";
$imap->User($username);
$imap->Password($password);
print "Logging In\n";
$imap->login() or die "imap login failed: $#\n";
On my machine, it outputs this:
Anon connect to IMAP
Started at Fri Dec 16 16:59:31 2016
Using Mail::IMAPClient version 3.38 on perl 5.022001
Read: * OK The Microsoft Exchange IMAP4 service is ready. [RABCADYAUABSADAAMgAwADEAQwBBADAAMAAyADcALgBlAHUAcgBwAHIAZAAwADIALgBwAHIAbwBkAC4AbwB1AHQAbABvAG8AawAuAGMAbwBtAA==]
upgrading connection to TLS
Sending: 1 CAPABILITY
Sent 14 bytes
Read: * CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
1 OK CAPABILITY completed.
Logging In
Sending: 2 AUTHENTICATE PLAIN
Sent 22 bytes
Read: +
Sending: [Redact: Count=2 Showcredentials=OFF]
Sent 18 bytes
Read: 2 NO AUTHENTICATE failed.
ERROR: 2 NO AUTHENTICATE failed. at /usr/local/share/perl/5.22.1/Mail/IMAPClient.pm line 3261.
Mail::IMAPClient::authenticate(Mail::IMAPClient=HASH(0x14f6a30), "PLAIN", undef) called at /usr/local/share/perl/5.22.1/Mail/IMAPClient.pm line 562
Mail::IMAPClient::login(Mail::IMAPClient=HASH(0x14f6a30)) called at imapt.pl line 30
imap login failed: 2 NO AUTHENTICATE failed.
Which is normal, as I don't have a valid account.

Related

i have an error in website Eprints, cannot send test email in perl

Connect failed :IO::Socket::INET: connect: timeout
at /usr/share/perl5/Net/SMTP/TLS.pm line 109.
here my code at 109
sub new {
my $pkg = shift;
my $host= shift;
my %args= #_;
$args{Host} = $host;
$args{Hello}= "localhost" if not $args{Hello};
# make the non-SSL socket that will later be
# transformed
$args{sock} = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => $args{Port} || 25,
Proto => 'tcp',
Timeout => $args{Timeout} || 5)
or croak "Connect failed :$#\n";
Your outgoing connections to port 25 may be blocked (firewalled) to prevent outgoing spam.
Do you get smtp greeting message when you telnet smtp port on the host from command line?
telnet hostname.domainname 25
Does the smtp server handle MSP (587) port? [port for message submission via smtp protocol]

How to connect outlook IMAP server go through proxy server uisng perl

I want to connect IMAP server but i am not able to connect directly imap server that's why i used proxy but still i am not able to connect and read emails.
Following is my code,
#!/usr/intel/bin/perl
use strict;
use warnings;
# fill in your details here
my $username = 'username#companyname.com';
my $password = 'password';
my $mailhost = 'outlook.office365.com';#imap-mail.outlook.com
my $mailport = 993;
my $proxyhost = '121.244.253.5';
my $proxyport = 8080;
print "Proxy...\n";
use IO::Socket::Socks::Wrapper(
{
ProxyAddr => $proxyhost,
ProxyPort => $proxyport,
SocksDebug => 0,
Timeout => 100000000
}
);
# required modules
use Net::IMAP::Simple;
use Email::Simple;
use IO::Socket::SSL;
print "Connecting...\n";
$IO::Socket::SSL::DEBUG=2;
# Connect
my $imap = Net::IMAP::Simple->new(
$mailhost,
port => $mailport,
use_ssl => 1
) || die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr \n";
print "Logging In...\n";
# Log in
if ( !$imap->login( $username, $password ) ) {
print STDERR "Login failed: " . $imap->errstr . "\n";
exit(64);
}
print "Selecting Folder...\n";
# Look in the the INBOX
my $nm = $imap->select('Archive');
print "How Many Messages Are There...\n";
# How many messages are there?
my ($unseen, $recent, $num_messages) = $imap->status();
print "unseen: $unseen, recent: $recent, total: $num_messages\n\n";
print "Quickly Look for unseen messages...\n";
## Iterate through unseen messages
for ( my $i = 1 ; $i <= $nm ; $i++ ) {
if ( $imap->seen($i) ) {
next;
} else {
my $es = Email::Simple->new( join '', #{ $imap->top($i) } );
printf( "[%03d] %s\n\t%s\n", $i, $es->header('From'), $es->header(+'Subject') );
}
}
print "Disconnect...\n";
# Disconnect
$imap->quit;
print "Exit...\n";
exit;
Following is my Response :-
Proxy...
Connecting...
DEBUG: .../IO/Socket/SSL.pm:332: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:334: socket connected
DEBUG: .../IO/Socket/SSL.pm:347: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:377: set socket to non-blocking to enforce timeout=100000000
I don't know why its not going further. Please share your opinion and correct me.
Please help me here...
Correct syntax is :
my $proxyhost = '65.130.4.202';
my $proxyport = 24451;
use Net::IMAP::Simple;
print "Proxy...\n";
use IO::Socket::Socks::Wrapper(
Net::IMAP::Simple => {
ProxyAddr => $proxyhost,
ProxyPort => $proxyport,
SocksDebug => 3,
Timeout => 100000000
}
);
use IO::Socket::SSL;
print "Connecting...\n";
$IO::Socket::SSL::DEBUG=2;
# Connect
my $imap = Net::IMAP::Simple->new(
'imap.gmail.com',
port => 993,
use_ssl => 1
) || die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr \n";
print "Logging In...\n";
# Log in
if ( !$imap->login( 'pappucant#gmail.com', 'pappu123' ) ) {
print STDERR "Login failed: " . $imap->errstr . "\n";
exit(64);
}
Working fine for me, didn't work with the proxy server mentioned in the code.
Output:
Proxy...
Connecting...
DEBUG: .../IO/Socket/SSL.pm:625: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:627: socket connected
DEBUG: .../IO/Socket/SSL.pm:649: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:682: using SNI with hostname imap.gmail.com
DEBUG: .../IO/Socket/SSL.pm:738: set socket to non-blocking to enforce timeout=90
DEBUG: .../IO/Socket/SSL.pm:764: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:774: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:794: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:764: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:774: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:794: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:764: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:774: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:794: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:809: ssl handshake done
Logging In...
Login failed: [AUTHENTICATIONFAILED] Invalid credentials (Failure)

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
};

How can I connect to gmail from 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 \.

"Can't call method "auth" on an undefined value at..." after many successful runs

i have a perl app that is supposed to send emails to a massive number of recipients. It seems to work ok, but after about 9K emails it fails with:
Can't call method "auth" on an undefined value at...
In the code I see:
# Open a connection to the SendGrid mail server
my $smtp = Net::SMTP->new('smtp.xyz.net', Port=> 25, Hello=>$DOMAIN);
# Authenticate
my $code = $smtp->auth($USERNAME, $PASSWORD);
The Net::SMTP constructor returns undef if there's a problem (e.g. it's unable to connect to port 25 on smtp.xyz.net). You aren't checking for that, and when you try to call a method on undef, you get the error message you mentioned.
my $smtp = Net::SMTP->new('smtp.xyz.net', Port=> 25, Hello=>$DOMAIN)
or die "Failed to open SMTP connection: $!";
may give you more information. (Although it's not necessarily a socket error, so $! may not contain anything useful.)
The Net::SMTP documentation says that when a method fails it returns undef. So I expect your method call failed.
You might be able to get more information by enabling the Debug => 1 flag in the Net::SMTP constructor.
You will want to detect that your method call failed, and possibly retry it after a short wait.
# Open a connection to the SendGrid mail server
my $smtp = Net::SMTP->new('smtp.xyz.net', Port=> 25, Hello=>$DOMAIN, Debug=>1);
die "Failed to make connection" unless ($smtp);
# Authenticate
my $code = $smtp->auth($USERNAME, $PASSWORD);
You could change it to retry in increasing intervals
something like this:
my $retry = 10; # in seconds;
my $smtp = Net::SMTP->new('smtp.xyz.net', Port=> 25, Hello=>$DOMAIN);
while (not defined $smtp) {
if ($retry > 300) {
die "could not connect to smtp server, giving up";
else {
print "could not connect to smtp, retrying in $retry seconds\n";
}
sleep ($retry);
$smtp = Net::SMTP->new('smtp.xyz.net', Port=> 25, Hello=>$DOMAIN);
$retry *= 2;
}
# Authenticate
my $code = $smtp->auth($USERNAME, $PASSWORD);
This happens mainly if you have the wrong mailbox. Check if smtp.xyz.net is the correct smtp mailbox or it could even be mail.xyz.net. That kind of error occurs if auth is not able to work with the value of 'host' given.