Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Get SharePoint to Mail with an SMTP Server Requiring Authentication

0.00/5 (No votes)
11 Jun 2009CPOL1 min read 48.5K   247  
In this article, I discuss my solution to get SharePoint mail to work with an authenticated SMTP server by creating a simple SMTP relay.

Introduction

This is a small Windows service that processes SMTP traffic from SharePoint, constructs an e-mail, and sends it off to a remote SMTP server that requires authentication.

Background

I've been struggling to get WSS 3.0 to send e-mail to an authenticated SMTP server. I have tried the SMTP server that is part of IIS with little success. So, I came up with this quick solution after finding code to process SMTP commands. I figured this might be a common problem.

Using the code

Just install SMTPRelaySetup.msi on your SharePoint server and edit the config file.

XML
<configuration>
  <appsettings>
    <add value="192.168.1.1" key="AllowedIPAddress" />
    <add value="Sharepoint Mail" key="MailFromName" />
    <add value="mail@sharepoint.com" key="MailFromAddress" />
    <add value="mail.sharepoint.com" key="RelayServer" />
    <add value="mail@sharepoint.com" key="RelayServerUser" />
    <add value="p@ssw0rd" key="RelayServerPassword" />
  </appsettings>
</configuration>

The solution contains four projects. There's a WSSMailRelay library project containing most of the functionality, with two projects referencing this library. The WSSMailRelayConsole project is a console application used for testing purposes. The WSSMailRelayService project is the actual Windows service. Finally, WSSMailRelaySetup is the setup project that builds the MSI installer.

I hate debugging Windows services, so whenever I am developing one, I always put most of my code into a separate library. I then reference it from a console application and use that to exclusively debug. The same library is also referenced in the Windows service.

Points of interest

I used Ivar Lumi's SMTP server to process SMTP commands. You can check it out here. Anyways, all I did was create handlers for all the various events that his SMTP server generates and start-up the server.

The most interesting part is when it handles the StoreMessage event. All I did was create a standard MailMessage from all the data that was passed into the event argument e.

C#
void smtpServer_StoreMessage(object sender, LumiSoft.Net.SMTP.Server.NewMail_EventArgs e)
{
    Console.WriteLine("Mail From: " + e.MailFrom);
    foreach (string email in e.MailTo)
    {
        Console.WriteLine("Mail To: " + email);
    }

    StreamReader sr = new StreamReader(e.MessageStream);
    string rawBody = sr.ReadToEnd();
    Console.WriteLine("Message: " + rawBody);
    Console.WriteLine("");

    MailMessage message = new MailMessage();
    message.From = new MailAddress(e.MailFrom);
    foreach (string email in e.MailTo)
    {
        message.To.Add(email);
    }

    message.Headers.Clear();
    foreach (string line in rawBody.Split(
                    new string[] { "\r\n" }, StringSplitOptions.None))
    {
        if (line == string.Empty)
            break;

        if (line.Contains(":"))
        {
            string[] headerPair = line.Split(':');
            switch (headerPair[0].Trim())
            {
                case "Subject":
                    message.Subject = headerPair[1];
                    break;
                case "Reply-To":
                    message.ReplyTo = new MailAddress(headerPair[1]);
                    break;
                case "From":
                    message.From = new MailAddress(
                       ConfigurationManager.AppSettings["MailFromAddress"], 
                       ConfigurationManager.AppSettings["MailFromName"]);
                    break;
                case "Content-Type":
                    if (headerPair[1].Contains("text/html"))
                        message.IsBodyHtml = true;
                    else
                        message.IsBodyHtml = false;
                    break;
                default:
                    message.Headers.Add(headerPair[0].Trim(), headerPair[1].Trim());
                    break;
            }

        }
    }

    message.Body = rawBody.Split(new string[] { "\r\n\r\n" }, 
                                 StringSplitOptions.None)[1];

    SmtpClient emailClient = new 
        SmtpClient(ConfigurationManager.AppSettings["RelayServer"]);
    System.Net.NetworkCredential SMTPUserInfo = new 
      System.Net.NetworkCredential(ConfigurationManager.AppSettings["RelayServerUser"],
        ConfigurationManager.AppSettings["RelayServerPassword"]);
    emailClient.UseDefaultCredentials = false;
    emailClient.Credentials = SMTPUserInfo;
    emailClient.Send(message);
}

History

  • June 11, 2009 - Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)