home

POP before SMTP for asp.net 2.0 and c sharp


or what to do if your new web hosting company use weird anti-spam mechanisms and you're in a rush

1 the problem

It's standard to avoid open SMTP relays in order to make life harder for anonymous idiots sending spam through an ISP's servers. So everyone closes those SMTP ports, usually 25. That's a bit serious if you're a valid customer though, and you actually want to send your non-spam email. There are several approaches to letting you do that, including:

extracted from the host's user manual...

POP before SMTP

The reason you get the error message: “sorry, that domain isn’t in my list of allowed rcpthosts” or “sorry, that domain is not allowed to be relayed through this MTA” when trying to send email is commonly related to an anti-spam protection we have in place on our network. This protection is called “POP-before-SMTP” and is for the benefit of your domain. Due to this protection, it will not be possible for a spammer to use your mail server to relay their unwanted messages.

You can still use the SMTP service that comes with your account. When sending mail you first have to login to your email server, this usually happens when you check for new messages. For a certain period of time after you check for mail, you are authorized to send email through your mail server. As soon as you receive the same error message - simply login again to your mail"

So what's the problem? Ah, well if you use a hosting company like IX web hosting and want to get your web site to send email, you'll hit the POP before SMTP problem sooner or later. The user manual and the company's Indians will tell you (see inset) that you need to "receive before send", which is all well and good if you're sitting at a mail client, but bog all use if you're a web server trying to send a receipt email to a customer who just ordered something.

So that's the problem: some hosting companies block their own mail servers from their own web servers. I can see why they do it, but it's still a problem if you're a legitimate user.

2 how to fix it

2.1 authenticated SMTP

Some ISPs support authenticated SMTP (I know, I worked for them); others like IX don't. So the first thing to try is to simply use the ASP.NET SmtpClient in authenticated mode, passing credentials which are username and password. I didn't get this to work as IX don't support it (I checked by Telnetting to their servers). However to save you another google here's the code I'm told should work:

smtp.Credentials = new NetworkCredential("username", "password");
smtp.Send(mail);

2.2 POP before SMTP

But here's my code to do the POP before SMTP thing if you really have to do that...Rocket science it isn't, but it took me a while to figure out I needed to do this; perhaps you'll get there faster now.

private void PopBeforeSMTP(string server, string userName, string password)
{
TcpClient connexion = new TcpClient(server, 110); // Connect to mail POP3 port.

NetworkStream netStream = connexion.GetStream();

SendCommand(netStream, "USER", userName);
SendCommand(netStream, "PASS", password);
SendCommand(netStream, "QUIT", String.Empty);

netStream.Close();
}

private static void SendCommand(NetworkStream stream, string command, string parameter)
{
string data = String.Format( "{0} {1}\r\n", command, parameter);
byte[] codedData = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray());
stream.Write(codedData, 0, codedData.Length);
}

All you need to do is to decide precisely when to do the pop-before. I read the manual from my hosting company and I did it perhaps half a second before I did the send, which should have worked. It didn't, so I backed off to just doing the send, then catching any "5.7.1" exception, doing the POP, then trying again. That works fine. Exception handling's slightly crude but it does the job.

2.3 just POP

If you have mail sends from your site all of which you control then the above's going to work fine. But what if you've a third party application on there which just expects SMTP or authenticated SMTP... it all gets to be a bit of a pain in the rear end really. So here's another solution... just run a "cron" job which POPs from the web server to the mail server every timeout, so that your web server's continually able to send SMTP from the web server's IP address.

Assuming you're using a hosted solution (which is why you have this problem in the first place...), you can't easily run a "cron" job. But the mechanism described in this code project article (c# version, detailed in the feedback), works fine.

In summary:

  1. add a class to handle scheduled tasks as per the above link
  2. add a global.asax and hook the scheduled task into application start
  3. make the time out value a little shorter than your ISP's time out (officially it's 30 minutes for IXwebhosting, so 25 minutes works fine)
  4. make the scheduled task execute the above POP-before-SMTP code
Retire to pub.