Most email services use SMTP for outgoing email with SSL/TSL for security. But Microsoft's email service is an exception. It uses STARTTLS instead. With most email clients like outlook or thunderbird, configuring email for any of microsoft's email services like live.com, hotmail.com or outlook.com is just child's play. But how to do it if you want to send emails with a programming language like Perl?

outlook.com email sending using perl

The most common scenario when you would want this is either to send bulk automated emails or sending emails from web servers. With gmail, you would use the Net::SMTP::SSL module. But since Microsoft's email server live.com is STARTTLS based, it won't work.

Your best bet here is to use the very new NET::SMTPS module. It adds STARTTLS support over the smtp module which means you can use the same smtp functions to send emails. Going by the documentation, the connection part would look like this -

use Net::SMTPS;
my $ssl = 'starttls';   # 'ssl' / 'starttls' / undef
my $smtp = Net::SMTPS->new("smtp.live.com", Port => 587, doSSL => $ssl);
$smtps->auth ( $USERNAME, $PASSWORD )

But this won't work if you try out. Enabling debug for smtps will show that authentication is failing.

The reason is the underlying SSL module trying to use the default "SSLv23:!SSLv2" as the SSL version. For tls, we need to use "TLSv1". Here's a working example with "TLSv1" used insted of the default -

my $msg = MIME::Lite ->new (  
From => '<FROM_EMAIL>',
To => '<TO_EMAIL>',
Subject => '<SUBJECT>',  
Data => <MESSAGE_BODY>,  
Type => 'text/html'  
);  
my $USERNAME = '<LOGIN_EMAIL>';
my $PASSWORD = '<LOGIN_PASSWORD>'; 

my $smtps = Net::SMTPS->new("smtp.live.com", Port => 587,  doSSL => 'starttls', SSL_version=>'TLSv1');

$smtps->auth ( $USERNAME, $PASSWORD ) or DIE("Could not authenticate with gmail.\n");

$smtps ->mail('<LOGIN_EMAIL>');  
$smtps->to('<TO_EMAIL>');
$smtps->data(); 
$smtps->datasend( $msg->as_string() );  
$smtps->dataend();  
$smtps->quit;

The trick here is to add SSL_version=>'TLSv1' in the "new" call so the default is overriden and TLSv1 gets used.

So please try out and let me know if you face any problem as comments below.