Friday, May 8, 2009

Sending Emails from .Net using Google's SMTP servers

The .Net framework has a few classes to handle mail.
The System.Net.Mail namespace will let you send an email message via the SMTP server configured in your web.config file or app.config file.
This works very well for many providers - but if you are using Gmail or google apps things get a little sticky since the only way to connect to the SMTP servers is using SSL which is not supported by system.net.mail.
I found a workaround this problem using an open source component called stunnel - stunnel allows you to create SSL tunnels to communicate with specific addresses and ports.
The way this would work is this:
1. we will tell our program to send email using SMTP to a non standard port (say 8025 instead of 25).
2. We will tell STunnel to listen on this port and forward all the traffic through an SSL tunnel to Google's SMTP server.

So here are the step by step directions:
1. Download the Stunnel installer from Stunnel.Org - http://www.stunnel.org/ - install this on your server
2. go to the the install directory for stunnel and change the stunnel.conf file to look like:

cert = stunnel.pem
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
;debug = 7

output = stunnel.log
; Use it for client mode
client = yes
[GmailSMTP]
accept = XXX.XXX.XXX.XXX:8025
connect = smtp.gmail.com:465

You will need to replace XXX.XXX.XXX.XXX with the IP address for the server you are running on - do not use localhost or 127.0.0.1 - they failed for me.
3. From the start menu do - stunnel service install and then stunnel servic start (you can change the start mode for the service to automatic also).
4. You can test your work - so far - open a command prompt window and type the following:
Telnet XXX.XXX.XXX.XXX:8025 (where XXX.XXX.XXX.XXX is the address above).
If everything works well you should see something like:
220 mx.google.com ESMTP q18sm6397127pog.5
Close the window.
5. In your application edit the System.Net configuration section of web.config or app.config as follows:
<system.net>
<mailsettings>
<smtp from="name@domain.com" >
<network host="XXX.XXX.XXX.XXX"
port="8025"
password="YOUR PASSWORD" userName="name@domain.com">
</smtp>
</mailsettings>
</system.net>

That should do it.

The inspiration for this was an article I read here:
http://quack.me/2007/02/gmail_via_pop3_on_exchange.php

3 comments:

matware said...

I've successfully sent using gmail with the following config section.

<system.net>
<settings/>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="smtp.gmail.com" userName="yourusername@gmail.com" port="587" password="yourpassword"></network>
</smtp>
</mailSettings>
</system.net>

And set
SmtpClient.EnableSSL = true


Although your article did make me wonder if there was an easier way :-)

Matthew @ Pelsys

Sagi E. Shkedy said...

matware,
This definately works: (SmtpClient.EnableSSL = true)
However if you need to switch to another SMTP server you will have to remove it and recompile the code. The STunnel way circumvents that and can be scaled for many applicaitons on the same server.

Meneer Habbiebabbie said...

To prevent having to recompile when changing smtp serversettings (the ssl part) I added a key in the AppSettings section of the web.config that tabkes a boolean.

The STunnel trick would never work on a shared server.