[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

.net smtp listener

Posted on 2011-03-08
12
Medium Priority
?
649 Views
Last Modified: 2012-05-11
Is there a way for using .net to create a console app. or service to listen for SMTP messages over a certain port?

I need to create a middle tier object that will capture and process smtp messages. That is to say i want smtp messages sent and picked up by this listener and then broken down to its basic components and persisted to a sql server DB.

If there is a off the shelf solution even better. I was not able to find one as I scurried the web.

Note: smtp sender will be a web app on the network, as well as exchange. The listener will be assigned some port so all smpt traffic on this port will be designated for my particular application.
0
Comment
Question by:realcoding
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 3
12 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35071666
Have you looked into the System.Net.Sockets.TcpListener class?
0
 

Author Comment

by:realcoding
ID: 35072994
kaufmed:

i have not worked with this class yet. can you explain how this would help me?
0
 
LVL 33

Assisted Solution

by:Todd Gerbert
Todd Gerbert earned 800 total points
ID: 35073847
I doubt you'll want to code a complete SMTP server from scratch.  This forum discussion lists a couple options for off-the-shelf components: http://stackoverflow.com/questions/249047/smtp-and-imap-server-library-for-net
0
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 1200 total points
ID: 35095384
So I put this together out of sheer curiosity, although I do agree with tgerbert that you may find an ready-built solution more easy to apply. My hope is that if you wanted to do the code yourself, then this will give you a start. This example is *extremely* basic. There is only one iteration on the "server;" in reality, I would expect this to be in a loop waiting for new connections. There is no serious error checking, and I may not be following the SMTP protocol strictly (I did intend to). There is no verification of the recipient as I'm not sure how you'd want to verify that.

Server
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication42
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(IPAddress.Loopback, 8000);
            TcpClient client;
            NetworkStream ns;
            
            listener.Start();

            Console.WriteLine("Awaiting connection...");
            client = listener.AcceptTcpClient();
            Console.WriteLine("Connection accepted!");

            ns = client.GetStream();

            using (StreamWriter writer = new StreamWriter(ns))
            {
                writer.WriteLine("220 localhost SMTP server ready.");
                writer.Flush();

                using (StreamReader reader = new StreamReader(ns))
                {
                    string response = reader.ReadLine();

                    if (!response.StartsWith("HELO") && !response.StartsWith("EHLO"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    string remote = response.Replace("HELO", string.Empty).Replace("EHLO", string.Empty).Trim();

                    writer.WriteLine("250 localhost Hello " + remote);
                    writer.Flush();

                    response = reader.ReadLine();

                    if (!response.StartsWith("MAIL FROM:"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    remote = response.Replace("RCPT TO:", string.Empty).Trim();
                    writer.WriteLine("250 " + remote + " I like that guy too!");
                    writer.Flush();

                    response = reader.ReadLine();

                    if (!response.StartsWith("RCPT TO:"))
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    remote = response.Replace("MAIL FROM:", string.Empty).Trim();
                    writer.WriteLine("250 " + remote + " I like that guy!");
                    writer.Flush();

                    response = reader.ReadLine();

                    if (response.Trim() != "DATA")
                    {
                        writer.WriteLine("500 UNKNOWN COMMAND");
                        writer.Flush();
                        ns.Close();
                        return;
                    }

                    writer.WriteLine("354 Enter message. When finished, enter \".\" on a line by itself");
                    writer.Flush();

                    int counter = 0;
                    StringBuilder message = new StringBuilder();

                    while ((response = reader.ReadLine().Trim()) != ".")
                    {
                        message.AppendLine(response);
                        counter++;

                        if (counter == 1000000)
                        {
                            ns.Close();
                            return;  // Seriously? 1 million lines in a message?
                        }
                    }

                    writer.WriteLine("250 OK");
                    writer.Flush();
                    ns.Close();
                    // Insert "message" into DB
                    Console.WriteLine("Received message:");
                    Console.WriteLine(message.ToString());
                }
            }

            Console.ReadKey();
        }
    }
}

Open in new window



Client
using System.Net;
using System.Net.Mail;

namespace ConsoleApplication43
{
    class Program
    {
        static void Main(string[] args)
        {
            MailMessage message = new MailMessage("ma@example.com", "pa@example.com");
            SmtpClient client = new SmtpClient(IPAddress.Loopback.ToString(), 8000);

            message.Body = "Don't forget to pick up some milk from the market.";

            client.Send(message);
        }
    }
}

Open in new window


Here are the references I used in creating the example above:

    https://helpdesk.islandnet.com/pep/smtp.php
    http://www.networksorcery.com/enp/protocol/smtp.htm




untitled.PNG
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35095417
P.S.

I arbitrarily used 8000 because our virus scanner at work is set up to block 25 by default. You can change it accordingly  : )
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35095669
Here's the actual standard from the IETF, note section 4.5.1 lists the minimum required to comply with the standard.  You would probably need to meet those minimums to effectively work with commercial SMTP servers like Exchange.  There are also other details you need to be aware of (like maximum length for a "MAIL FROM:<>" command, and encoding of periods in message data).

http://tools.ietf.org/html/rfc821
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35095765
@tgerbert

I started off looking at that, but after a few minutes I said, "Man, that's a lot to read!"

; )
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35095787
Yeah, but most of it's not necessarily applicable - the list of minimum required commands is pretty short.
0
 

Author Comment

by:realcoding
ID: 35097702
thanks all, i have got some serious reading to do. also ill try your POC app as well. thanks all for the great help !
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35117314
NP. Glad to help  = )
0
 

Author Comment

by:realcoding
ID: 35142003
@kaufmed,

I have the consul apps made but my environment is preventing mail from going out and telling me the server actively refused the connection. do i need to config something aside from running the apps?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35156628
>>  server actively refused the connection.

That usually means the server doesn't have that port open (i.e. the service isn't running). There could also be firewall or antivirus restrictions, I imagine. Can you confirm none of these is the case?
0

Featured Post

Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Are you an Exchange administrator employed with an organization? And, have you encountered a corrupt Exchange database due to which you are not able to open its EDB file. This article will explain all the steps to repair corrupt Exchange database.
This month, Experts Exchange sat down with resident SQL expert, Jim Horn, for an in-depth look into the makings of a successful career in SQL.
To show how to generate a certificate request in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.:  First we need to log into the Exchange Admin Center. Navigate to the Servers >> Certificates…
The basic steps you have just learned will be implemented in this video. The basic steps are shown to configure an Exchange DAG in a live working Exchange Server Environment and manage the same (Exchange Server 2010 Software is used in a Windows Ser…

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question