Application Security Testing: An Integral Part of DevOps
by John Peterson
I'm not sure how much interest there is in this, but it's one of those things I always meant to do and never did... until now.
I always figured you could send messages via a seperate SMTP server via CDO, but I had never tried it. The only thing I had ever looked into was the "Smart Host" setting at the local SMTP server level which will forward all mail to another SMTP server via the local SMTP service. There's not much info floating around about this, but it does work as it's supposed to and has been useful on occasion.
The problem with that solution is that you still need to have the local SMTP server installed, configured, and running. It's not a biggie, but if you configure it wrong or a bug is found you could find yourself with an open relay and be used to spam everyone on the internet! Using one outgoing SMTP server for your entire web farm/department/corporation/whatever makes administering and ensuring it's secure much easier.I set out to find out how to use CDO (as opposed to a 3rd party component) and still specify an external SMTP server to handle the emailing. I didn't do an exhastive search, but after checking a half-dozen of my favorite ASP sites, a half-dozen of my ASP books, and searching the web via Altavista and Google, I couldn't find anyone covering this. I'm not saying no one has ever written about this, but I couldn't find it. (If you find anything outside the MSDN docs relating to this topic let me know and I'll link to it.)
Having no luck in the ASP community, I rolled up my sleeves, dove into the documentation, booted up another test server to relay through, and started writing and trying some code. Come to find out it's pretty easy once you figure out all the constants.
Here's the process I went through to arrive at the code listed below. I'm including it so that if you need to find any information that I haven't included you'll at least know where to start looking.
There are tons of great ASP-related websites out there, but for something like this (a simple question that should have a simple answer and that you can assume hundreds of people have asked at one time or another) I tend to look to for a FAQ (Frequently Asked Questions) list. There are two good ASP FAQ sites that I know of... http://www.aspfaq.com/ and http://www.aspfaqs.com/. Both are normally good about covering this type of thing, but I couldn't find any info about this topic (at least as of the date of this article - when I was looking). That being said, if you have a question that might be covered in a FAQ, I highly recommend you check them out before posting your question to a newsgroup or discussion list. You'll get an answer much faster, it'll probably be of higher quaility, and you'll help keep the noise down on the newsgroups and lists so that people can get more complex questions answered quicker. Basically everyone wins!
Books and Search Engines
I then checked the books on my shelf. Over the years I've accumulated quite a library of ASP-related books, but apparently none about CDO. Personally I find books have their place, but technology-related books become outdated so fast that it's hard to keep up and since CDO isn't really part of ASP and is a so called "related technology", none of them cover much more then the basic send an email script.
Okay so scratch the books... to the web! Well I got tons of results ranging from hosting companies to development shops. Mixed in were plenty of good resources for sending an email via ASP, but we already knew how to do that! I spent some time trying to refine my search using some booleans, but never really got anything useful.
Finally I gave in and decided that I had to go to Microsoft for the info I wanted. In a perfect (or even slightly sane) world, you'd think that the source for the software you're trying to use would be the first place you should look. Well anyone who's been developing with Microsoft products for a while knows that this just isn't the case... especially for ASP. It's getting a lot better with ASP.NET, but still...
For an interesting and pertinent example of what I'm talking about: next time you get a chance, take a look at the ASP.NET QuickStart that ships with the .NET Framework. In the top navigation bar they have a link titled "How Do I..." that leads to a great page full of sample scripts. This page has hundreds of samples on topics from how to generate and compare a hash value for use in cryptograpy to how to call a function exported from an unmanaged DLL so that .NET can interoperate with legacy apps. Now I'm not saying these aren't worthy topics, but nowhere on this page is there any mention of how to send an email!
And even if you do happen to stumble upon what you're looking for, you better print out a hard copy... there's a good chance it'll be moved or removed the next time you go to look at it.
It's really nice that VBScript and VB are so similar sometimes. I knew VB had a way of looking up constants. I fired off VB, created a new project, added a reference to CDO for Windows 2000, and ran the Object Browser and copied the constants I needed into my script file. Not the neatest way to do it, but it got the job done and did it without knowing that the UUID for the CDO for Windows 2000 Type Library is CD000000-8B95-11D1-82DB-00C04FB1625D.
The type library should also get you the constants for any errors CDO throws your way, but I tend to find it just as easy to look them up in the VB Object Browser... either way will get you a better explanation then some random error number.
Anyway... without any further ado...
You can probably do this via CDONTS, but I assume most of us are on Win 2000 by now so the code below uses CDO for 2000. I'll try and get a CDONTS version up soon... I'm having some trouble finding an NT 4 server to test it on.
<% Const cdoSendUsingMethod = _ "http://schemas.microsoft.com/cdo/configuration/sendusing" Const cdoSendUsingPort = 2 Const cdoSMTPServer = _ "http://schemas.microsoft.com/cdo/configuration/smtpserver" Const cdoSMTPServerPort = _ "http://schemas.microsoft.com/cdo/configuration/smtpserverport" Const cdoSMTPConnectionTimeout = _ "http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout" Const cdoSMTPAuthenticate = _ "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate" Const cdoBasic = 1 Const cdoSendUserName = _ "http://schemas.microsoft.com/cdo/configuration/sendusername" Const cdoSendPassword = _ "http://schemas.microsoft.com/cdo/configuration/sendpassword" Dim objConfig ' As CDO.Configuration Dim objMessage ' As CDO.Message Dim Fields ' As ADODB.Fields ' Get a handle on the config object and it's fields Set objConfig = Server.CreateObject("CDO.Configuration") Set Fields = objConfig.Fields ' Set config fields we care about With Fields .Item(cdoSendUsingMethod) = cdoSendUsingPort .Item(cdoSMTPServer) = "smtp_server_name" .Item(cdoSMTPServerPort) = 25 .Item(cdoSMTPConnectionTimeout) = 10 .Item(cdoSMTPAuthenticate) = cdoBasic .Item(cdoSendUserName) = "username" .Item(cdoSendPassword) = "password" .Update End With Set objMessage = Server.CreateObject("CDO.Message") Set objMessage.Configuration = objConfig With objMessage .To = "Display Name <email_address>" .From = "Display Name <email_address>" .Subject = "SMTP Relay Test" .TextBody = "SMTP Relay Test Sent @ " & Now() .Send End With Set Fields = Nothing Set objMessage = Nothing Set objConfig = Nothing %>
To use it you'll need to edit the smtp server name, the username and password if you're authenticating, and the to and from email addresses.
Bad News For NT4 Users:
I did some more research and found some info that makes it look like doing this via CDO for NTS isn't going to happen. Microsoft has a page in the CDO for NTS documentation that compares CDO for NTS and CDO 1.2.1 (the two CDO libraries available on NT4). It appears that while the CDO for NTS library doesn't support "remote server access", CDO 1.2.1 doesn't support "SMTP access". As a result, accessing a remote server via SMTP would seem to be impossible if you want to use either CDO library on NT4.
However, all is not lost. As I mentioned earlier, it is still possible to send email via CDO and use an external SMTP server by using the "Smart Host" setting at the local SMTP server level. This does mean the local SMTP service will need to be running, but it does allow you to set SMTP permissions and settings in one place. As far as I can tell, it's either "Smart Host" or a 3rd party or custom component if you're still on NT4. Sorry guys.
Two of our readers each independently informed me that Microsoft has a KnowledgeBase article which addresses this topic:
Thanks go out to both Marsha Glassner and Cameron Frasnelly for finding the article and letting us know about it.