Archive for the ‘Component’ Category

Send email to multiple recipients

Wednesday, December 7th, 2011

The easiest way is to use BCC field (Blind-Carbon-Copy),  and specify Undisclosed recipients group as the message recipient.

// C# version

MailBuilder builder = new MailBuilder();
builder.From.Add(new MailBox("alice@example.com", "Alice"));
builder.To.Add(new MailGroup("Undisclosed recipients"));

builder.Bcc.Add(new MailBox("bob@example.com", "Bob"));
builder.Bcc.Add(new MailBox("tom@example.com", "Tom"));
builder.Bcc.Add(new MailBox("john@example.com", "John"));

builder.Subject = "Put subject here";
builder.Html = "Put <strong>HTML</strong> message here.";

// Plain text is automatically generated, but you can change it:
//builder.Text = "Put plain text message here.";

IMail email = builder.Create();

// Send the message
using (Smtp smtp = new Smtp())
{
    smtp.Connect("server.example.com");   // or ConnectSSL for SSL
    smtp.UseBestLogin("user", "password"); // remove if not needed

    smtp.SendMessage(email);

    smtp.Close();
}
' VB.NET version

Dim builder As New MailBuilder()
builder.From.Add(New MailBox("alice@example.com", "Alice"))
builder.[To].Add(New MailGroup("Undisclosed recipients"))

builder.Bcc.Add(New MailBox("bob@example.com", "Bob"))
builder.Bcc.Add(New MailBox("tom@example.com", "Tom"))
builder.Bcc.Add(New MailBox("john@example.com", "John"))

builder.Subject = "Put subject here"
builder.Htm = "Put <strong>HTML</strong> message here."

' Plain text is automatically generated, but you can change it:
'builder.Text ="Put plain text message here."

Dim email As IMail = builder.Create()

' Send the message
Using smtp As New Smtp()
	smtp.Connect("server.example.com")    ' or ConnectSSL for SSL
	smtp.UseBestLogin("user", "password")  ' remove if not needed

	smtp.SendMessage(email)

	smtp.Close()
End Using

Also take a look at Mail.dll’s templating engine

Import certificate, private or public keys (PEM, CER, PFX)

Tuesday, November 22nd, 2011

Encrypted private key, RSA private key in PEM file:

PEM stands for Privacy Enhanced Mail format.

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadEncryptedPrivateKeyFromFile(
   "EncryptedPrivateKey.pem", // "EncryptedRSAPrivateKey.pem"
   "cypher");

This code handles following formats:

PKCS #8 EncryptedPrivateKeyInfo Encrypted Format:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICojAcBgoqhkiG9w0BD .....

Private Key (Traditional SSLeay RSAPrivateKey format) Encrypted:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,24A667C253F8A1B9

mKz .....

You can remove the passphrase from the private key:
openssl rsa -in EncryptedPrivateKey.pem -out PrivateKey.pem

Unencrypted private key in PEM file:

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadPrivateKeyFromFile(
   "PrivateKey.pem");

This code handles following formats:

PKCS #8 PrivateKeyInfo Unencrypted:

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0B ......

Private Key (Traditional SSLeay RSAPrivateKey format) Unencrypted:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCcHVm .....

Public key in PEM file:

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadPublicKeyFromFile(
   "PublicKey.pem")

This code handles following formats:

Public Key (SubjecPublicKeyInfo):

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEB .....

Certificate/private key in PFX file:

X509Certificate2 certificate  = new X509Certificate2(
   "certificate.pfx",
   "",
   X509KeyStorageFlags.PersistKeySet)

if (certificate.HasPrivateKey)
{
  using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey)
  {
  }
}

Certificate in PEM/CER file

Note: The private key is never stored in a .pem/.cer file.

X509Certificate2 certificate = new X509Certificate2(
   "certificate.cer");

-or-

PemReader pem = new PemReader();
X509Certificate2 certificate = pem.ReadCertificateFromFile(
   "certificate.cer");

This code handles following formats:


-----BEGIN CERTIFICATE-----
MIIFsTCCA5mgAwIBAgIKYQ .....

Mail.dll .NET email spam filter

Saturday, October 22nd, 2011

Mail.dll .NET email component includes high accuracy anti-spam filter.

It uses enhanced naive Bayesian classifier, specifically modified to handle email messages. Bayesian spam filters are a very powerful technique for dealing with spam.

In our tests we achieved 99,6% accuracy with very low false positive spam detection rates (9 false positives in 54’972 emails tested – that’s 0.016%).

Training

First in the learning phase, you need to teach the classifier to recognize spam and non-spam (ham) messages. You need to prepare 100-200 spam and ham messages.

I suggest using following folder structure:

“Learn” folder is used for training the filter. Both spam and ham folders should contain around 100-200 messages each (the more the better). The number of messages in spam and ham folders must be equal. You can find a spam archive on the bottom of the article.

Messages must be in eml format with correct line endings (rn or 13 10 hex).

Now we use SpamFilterTeacher class to teach BayesianMailFilter:

// C#
using Lesnikowski.Mail.Tools.Spam;

BayesianMailFilter filter = new BayesianMailFilter();
SpamFilterTeacher teacher = new SpamFilterTeacher(filter);
teacher.TeachSpam(@"c:bayeslearnspam");
teacher.TeachHam(@"c:bayeslearnham");

Testing

“Test” folder is used for testing our filter:

// C#

SpamTestResults r = teacher.Test(
    @"c:bayestestspam",
    @"c:bayestestham");

Console.WriteLine(r);
r.FalsePositives.ForEach(Console.WriteLine);
r.NotMarkedAsSpam.ForEach(Console.WriteLine);

The results should be similar to this:

Accuracy=0.9949, False positives=9, Not marked as spam=271, Tests count=54972
c:bayestestham�16874.eml
...

When the filter is trained and the results are satisfactory, you can save it to disk:

// C#

filter.Save("c:\20111022.mbayes");

Using

You can load the filter from disk and check individual messages:

// C#

BayesianMailFilter filter = new BayesianMailFilter();
filter.Load("c:\20111022.mbayes");

// you can use Mail.dll to download mesage from POP3 or IMAP server:
string eml = ... 

IMail email = new MailBuilder().CreateFromEml(eml);

SpamResult result = filter.Examine(email);
Console.WriteLine(result.Probability);
Console.WriteLine(result.IsSpam);

If the filter incorrectly recognizes the message you can train it again:

// C#

filter.LearnSpam(email);
// - or -
filter.LearnHam(email);

filter.Save("c:\20111022.mbayes");

Spam archives

For most recent spam you can check this great archive: http://www.untroubled.org/spam/.
Unfortunately messages don’t have correct extension (*.eml) and line endings are incorrect.

You can download spam archive including 7874 spam messages from Oct 2011 here:
http://www.lesnikowski.com/mail/spam/spam201110.zip

OAuth with Gmail

Friday, October 21st, 2011

OAuth is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

In this post I’ll show how to access Gmail account using 3-legged OAuth authentication method. The key advantage of this method is that it allows an application to access user email without knowing user’s password.

You can read more on OAuth authentication with Google accounts here:
http://code.google.com/apis/accounts/docs/OAuth_ref.html

Gmail IMAP and SMTP using OAuth:
http://code.google.com/apis/gmail/oauth/protocol.html

If your application/website is not registered, you should use following key and secret:
consumer key: “anonymous”
consumer secret: “anonymous”

Remember to add reference to Maill.dll and appropriate namespaces.

// C#

using Lesnikowski.Client.IMAP;
using Lesnikowski.Client.Authentication;
using Lesnikowski.Client.Authentication.Google;

const string userEmailAccount = "pat@gmail.com";
const string consumerKey = "anonymous";
const string consumerSecret = "anonymous";

GmailOAuth oauth = new GmailOAuth(
    consumerKey, consumerSecret);

string url = oauth.GetAuthorizationUrl("http://localhost:64119/");

Process.Start(url);
// You can use Response.Redirect(url) in ASP.NET

string oauthVerifier = HttpUtility.UrlDecode(Console.ReadLine());
// You can use Request["oauth_verifier"].ToString() in ASP.NET

oauth.GetAccessToken(oauthVerifier);

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.gmail.com");
    string oauthImapKey = oauth.GetXOAuthKeyForImap();
    client.LoginOAUTH(oauthImapKey);

    // Now you can access user's emails
    //...

    client.Close();
    oauth.RevokeToken(oauthImapKey);
}

1.
GmailOAuth.GetAuthorizationUrl method returns url you should redirect your user to so he can authorize access.
As you can see Mail.dll is asking for access to user’s email information and Gmail access:

2.
If you don’t specify callback parameter, user will have to manually copy&paste the token to your application:

In case of a web project, you can specify a web address on your website. oauth_verifier will be included as the redirection url parameter.

After the redirection, your website/application needs to read oauth_verifier query parameter:

3.
GmailOAuth.GetAccessToken method authorizes the token.

4.
GmailOAuth.GetXOAuthKeyForImap method uses Google API to get the email address of the user, and generates XOAuth key for IMAP protocol (you can use GetXOAuthKeyForSmtp for SMTP).

5.
GmailOAuth.RevokeToken method revokes XOAuth key, so no further access can be made with it.

…and finally VB.NET version of the code:

' VB.NET

Imports Lesnikowski.Client.IMAP
Imports Lesnikowski.Client.Authentication
Imports Lesnikowski.Client.Authentication.Google

Const userEmailAccount As String = "pat@gmail.com"
Const consumerKey As String = "anonymous"
Const consumerSecret As String = "anonymous"

Dim oauth As New GmailOAuth(consumerKey, consumerSecret)

Dim url As String = oauth.GetAuthorizationUrl("http://localhost:64119/")

Process.Start(url)
' You can use Response.Redirect(url) in ASP.NET

Dim oauthVerifier As String = HttpUtility.UrlDecode(Console.ReadLine())
' You can use Request["oauth_verifier"].ToString() in ASP.NET

oauth.GetAccessToken(oauthVerifier)

Using client As New Imap()
	client.ConnectSSL("imap.gmail.com")
	Dim oauthImapKey As String = oauth.GetXOAuthKeyForImap()
	client.LoginOAUTH(oauthImapKey)

	' Now you can access user's emails
	'...

	client.Close()
	oauth.RevokeToken(oauthImapKey)
End Using

2-legged OAuth with Gmail

Friday, October 21st, 2011

OAuth is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

In this post I’ll show how to access Gmail account using 2-legged OAuth authentication method. The basic idea is that domain administrator can use this method to access user email without knowing user’s password.

You can read more on OAuth authentication with Google accounts here:
http://code.google.com/apis/accounts/docs/OAuth_ref.html

Gmail IMAP and SMTP using OAuth:
http://code.google.com/apis/gmail/oauth/protocol.html

Remember to add reference to Maill.dll and appropriate namespaces.

// C#

using Lesnikowski.Client.IMAP;
using Lesnikowski.Client.Authentication;
using Lesnikowski.Client.Authentication.Google;

const string consumerKey = "example.com";
const string consumerSecret = "secret";
const string email = "pat@example.com";

Gmail2LeggedOAuth oauth = new Gmail2LeggedOAuth(
    consumerKey, consumerSecret);

using (Imap client = new Imap())
{
    client.ConnectSSL(TestConstants.GmailImapServer);

    string oauthImapKey = oauth.GetXOAuthKeyForImap(email);

    client.LoginOAUTH(oauthImapKey);

    //...

    client.Close();
}
' VB.NET

Imports Lesnikowski.Client.IMAP
Imports Lesnikowski.Client.Authentication
Imports Lesnikowski.Client.Authentication.Google

Const  consumerKey As String = "example.com"
Const  consumerSecret As String = "secret"
Const  email As String = "pat@example.com"

Dim oauth As New Gmail2LeggedOAuth(consumerKey, consumerSecret)

Using client As New Imap()
	client.ConnectSSL(TestConstants.GmailImapServer)

	Dim oauthImapKey As String = oauth.GetXOAuthKeyForImap(email)

	client.LoginOAUTH(oauthImapKey)

	'...

	client.Close()
End Using

Here are the google apps configuration screens: