We will be conducting planned maintenance to ordering system next week:
Tuesday, May 7, 2019 from From 5:00 AM CDT/12:00 PM CEST, lasting approximately 6 hours.
During the planned maintenance, the system will continue to take orders. However customers may see temporary delays in fulfillment and order confirmation emails.
Once the maintenance is finished, we expect all functionality to resume; orders will be processed, and order confirmation emails will be sent to customers.
It is no longer possible to re-enable Basic Auth or use App passwords.
// C#
using (Imap client = new Imap())
{
client.ConnectSSL("outlook.office365.com");
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken");
...
}
using (Pop3 client = new Pop3())
{
client.ConnectSSL("outlook.office365.com");
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken");
...
}
using (Smtp client = new Smtp ())
{
client.Connect("outlook.office365.com");
client.StartTLS();
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken");
...
}
' VB.NET
Using client As New Imap()
client.ConnectSSL("outlook.office365.com")
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken")
...
End Using
Using client As New Pop3()
client.ConnectSSL("outlook.office365.com")
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken")
...
End Using
Using client As New Smtp()
client.Connect("outlook.office365.com")
client.StartTLS()
client.UseBestLogin("user@domain.onmicrosoft.com", "accesstoken")
...
End Using
Office 365 pre-upgrade
For latest Office 365 pre-upgrade, use the following settings:
On the main screen go to “Options” / “See All Options…”:
Now click the “Settings for POP, IMAP, and SMTP access…” link:
You can find POP, SMTP and IMAP server addresses and settings on the popup window:
Office365 uses default ports for IMAP, POP3 and SMTP protocols. That means that you don’t need to remember port numbers, as Mail.dll .NET email component is going to use correct port numbers by default.
Sending email is built into .NET, so there’s no need for 3rd party library, however Mail.dll is much easier to use than SmtpClient, and much more powerful. Receiving is a bit more complicated. It does require a 3rd party library.
There are two standard protocols for receiving emails IMAP (Internet Message Access Protocol) and POP3 (Post Office Protocol). Without getting in to much details IMAP is better and offers more features when receiving emails (you can find a detailed IMAP vs POP3 comparison here).
We’ll use Imap class to work with this protocol.
Installation
You can install Mail.dll client from nuget via Package Manager:
First thing you need to do is to connect to your IMAP email server. Most servers today require SSL or TLS. We’ll use ConnectSSL(string host) to connect and establish secure channel. This method makes sure correct SSL/TLS versions are used and server certificate is valid:
// C#
using (Imap imap = new Imap ())
{
imap.ConnectSSL("imap.example.com");
imap.UseBestLogin("user@example.com", "password");
' VB
Using imap As New Imap()
imap.ConnectSSL("imap.example.com")
imap.UseBestLogin("user@example.com", "password")
Next step is to select a folder which we want to access and download unique ids (UIDs) of email messages. In this example we’ll search and receive unseen emails from INBOX folder.
' VB
imap.SelectInbox()
Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
Receive emails
Finally we need to receive and process those emails. On the server emails are stored in MIME format. GetMessageByUID method receives emails as a raw byte array and MailBuilder class can be used to parse it:
// C#
foreach (long uid in uids)
{
var eml = imap.GetMessageByUID(uid)
IMail email = new MailBuilder().CreateFromEml(eml);
Console.WriteLine(email.Subject);
Console.WriteLine(email.Text);
}
' VB
For Each uid As Long In uids
{
Dim eml = imap.GetMessageByUID(uid)
Dim email As IMail = builder.CreateFromEml(eml)
Console.WriteLine(email.Subject)
Console.WriteLine(email.Text)
}
Here are the full samples that receive emails in both C# and VB .NET:
// C#
using Limilabs.Mail;
using Limilabs.Client.IMAP;
class Program
{
static void Main(string[] args)
{
using(Imap imap = new Imap())
{
imap.ConnectSSL("imap.example.com");
imap.UseBestLogin("user", "password");
imap.SelectInbox();
List<long> uids = imap.Search(Flag.Unseen);
foreach (long uid in uids)
{
var eml = imap.GetMessageByUID(uid);
IMail email = new MailBuilder()
.CreateFromEml(eml);
Console.WriteLine(email.Subject);
Console.WriteLine(email.Text);
}
imap.Close();
}
}
};
' VB.NET
Imports Limilabs.Mail
Imports Limilabs.Client.IMAP
Public Module Module1
Public Sub Main(ByVal args As String())
Using imap As New Imap()
imap.ConnectSSL("imap.example.com")
imap.UseBestLogin("user", "password")
imap.SelectInbox()
Dim uids As List(Of Long) = imap.Search(Flag.Unseen)
For Each uid As Long In uids
Dim eml = imap.GetMessageByUID(uid)
Dim email As IMail = New MailBuilder() _
.CreateFromEml(eml)
Console.WriteLine(email.Subject)
Console.WriteLine(email.Text)
Next
imap.Close()
End Using
End Sub
End Module
Here’s the latest version that supports Visual Studio 2017 and Visual Studio 2015.
Extension is convention based. It matches ClassName file with ClassNameTest or ClassNameTests and vice-versa, so you can easily navigate to the test file and back.
The Mailsploit vulnerability stems from how email servers/clients interpret email addresses containing encoded words. Incorrectly handling those, could allow an attacker to spoof email identities.
Recent specs (RFC-2822 and RFC-5322) don’t allow using encoded-words for email addresses (addr-spec):
Here are the unit test that show how Mail.dll behaves when such malicious emails are parsed. Please note that encoded-words are not decoded when part of email address.
[Test]
public void Test1()
{
string eml = @"From: =?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@example.com
Body";
IMail mail = new MailBuilder().CreateFromEmlASCII(eml);
Assert.AreEqual(
"=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@example.com",
mail.Headers["From"]);
Assert.AreEqual(
"=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=@example.com",
mail.From[0].Address); // Correct
Assert.AreEqual(
null,
mail.From[0].Name); // Correct
}
[Test]
public void Test2()
{
string eml = @"From: =?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=
Body";
IMail mail = new MailBuilder().CreateFromEmlASCII(eml);
Assert.AreEqual(
"=?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?=",
mail.Headers["From"]);
Assert.AreEqual(
null,
mail.From[0].Address); // Correct
Assert.AreEqual(
"potus@whitehouse.gov",
mail.From[0].Name); // Correct - this is correct behavior,
// sender can put anything in the name field.
}
Mail.dll allows anything in the name part of the address headers:
[Test]
public void Test4()
{
string eml = @"From: =?utf-8?Q?=42=45=47=49=4E=20=2F"
+ @"=20=20=2F=20=00=20=50=41=53=53=45=44"
+ @"=20=4E=55=4C=4C=20=42=59=54=45=20=2F=20=0D=0A"
+ @"=20=50=41=53=53=45=44=20=43=52"
+ @"=4C=46=20=2F=20=45=4E=44?= <test@example.com>
Body";
IMail mail = new MailBuilder().CreateFromEmlASCII(eml);
Assert.AreEqual(
"test@example.com",
mail.From[0].Address);
Assert.AreEqual(
"BEGIN / / \0 PASSED NULL BYTE / \r\n PASSED CRLF / END",
mail.From[0].Name);
// Note the \r\n (new line) and \0 (null) characters
}
Specification allow using encoded-words in the name (RFC2047 – 5. Use of encoded-words in message headers. (3) )
Encoded words are used to encode non-ASCII characters, for example national characters like umlauts (ä, ö, ü).
RFC2047 imposes no restrictions what characters can be encoded, which means that zero byte (\0) and new lines (\r\n) are valid characters.
Client applications must ensure that such special charters don’t ‘push’ the actual email address (“”test@example.com”) outside of control, in such way, that it becomes not visible.
It is crucial for them to display the email address (test@example.com) no matter what is in the name field.