- Experts Exchange Approved
By Sean D. Stuber
Up to date through Oracle version 11gR2
Part II: How to Send Email Attachments with Oracle
Oracle's UTL_SMTP package introduced in version 8i through version 11.2.0.1 (as of this writing, the latest version available on OTN for most platforms) offers no built in method to authenticate to a server. When UTL_MAIL was introduced in 10g the functionality hole was still left unaddressed. Frequently this is not a problem within a business because your company's internal SMTP server will often let internal connections send outbound traffic without additional authentication; relying on firewalls or other configuration to prevent external connections from abusing the server. The fact that the request is "internal" is authentic enough for many places and Oracle's packages were apparently designed with this assumption in place.
However, this is not always the case. If your internal server requires authentication or if you must connect directly to your ISP's server or if you must use some other third-party service then you will need to authenticate your identity to the server in order to send mail. Herein, I will show how to extend the functionality of UTL_SMTP to allow for common authentication mechanisms. Alas, UTL_MAIL, due to its over-simplicity is not able to be extended in this way and I suggest converting to UTL_SMTP-based functionality.
Surprisingly, the original SMTP protocol provided no means of authenticating; but with the rise of spam engines and malicious users it quickly became a necessary component and was later added with addendum RFC's. SMTP authentication can be of multiple forms, some more secure than others. Discussing the implementations of all possibilities is beyond the scope of this article and some aren't possible to replicate solely within the UTL_SMTP API; but I will show a few of the more common methods.
Initiating the Communication
Since authentication is an extension to base SMTP functionality, you will initiate communication with the EHLO (extended hello) command rather than the standard HELO command.
When the server reads an EHLO command its response should include the types of authentication supported, if any.
The response might look something like this:
This would indicate the server supports 4 methods of SMTP authentication as well as the more secure SSL/TLS protocol.
First, let's look at the SMTP authentication methods. All of these include Base-64 Encoding, as part of their algorithms.
It is important to note, Base-64 Encoding is NOT ecryption. It's simply a text conversion to a subset of ASCII for purposes of ensuring correct processing regardless of character sets. Encoding is unkeyed and completely reversible. As such it should be considered "plain text" for purposes of security evaluation of the PLAIN and LOGIN methods.
AUTH PLAIN
With this method the client sends the authenticating id, the user id and the password as a single Base-64-encoded, NULL-delimited (ASCII-0) string. For most email servers, the authenticating id and the user id will be the same.
If they differ, the details should be provided by your server as to what the required id's are.
With PLAIN, there is no prompting or challenge, you simply send an authentication command and the server will process it. The syntax is a single line, and might look something like this...
which would look like this after decoding with "|" representing the NULL character - chr(0)
To replicate this functionality in PL/SQL, you simply send these strings with the UTL_SMTP.COMMAND procedure after connecting.
AUTH LOGIN
Another authentication method, LOGIN, will prompt you for username and password responses. The prompts will be Base-64 encoded and the responses are expected to be as well.
SMTP authentication via LOGIN method with a telnet session might look something like this...
Which would like this after decoding
To replicate this functionality in PL/SQL, you simply send these strings with the UTL_SMTP.COMMAND procedure after connecting.
As with AUTH PLAIN you initiate communication with the EHLO command and use UTL_SMTP.COMMAND to send the authentication instructions but rather than putting all the info on one line, the server will prompt you as shown above.
In this example, if the login, user or password messages aren't accepted, an error should be raised from the server which will then be re-raised by UTL_SMTP as an oracle UTL_SMTP exception.
AUTH CRAM-MD5 (or CRAM-SHA1)
The Challenge-Response Authentication Mechanism (CRAM) with MD5 is defined in RFC2195 ( http://www.ietf.org/rfc/rf
Using the Sample challenge, username and password from RFC2195 the CRAM-MD5 algorithm might look something like this...
The server sends challenge: "PDE4OTYuNjk3MTcwOTUyQHBvc
Which is "<1896.697170952@postoffic
The above is a bit hard to follow, and it doesn't take into account requirements for handling passwords over 64 bytes. So, I have provided a function below that will encapsulate the full CRAM algoritm, including support for long passwords as well as the option to switch to CRAM-SHA1. Using this function makes it much easier to generate the proper response to the challenge string.
example use might look something like this
Your SMTP server may support other means as well, such as POP before SMTP which is essentially a timing authentication.
First you must request to receive email via POP3 which has authentication built in to it and then from the same ip address within a short period ("short" being server defined) you can then send SMTP commands and it will allow access. The POP3 protocol can't be implemented through UTL_SMTP, but could be implemented via UTL_TCP. Doing so is outside the scope of this article, but I may address it in a future article if there is sufficient interest. Other authentication includes TLS/SSL which is much more secure and common for public servers such as GMail. Note however, while TLS authentication is requested by SMTP it is not actually part of SMTP itself and cannot be implemented with calls to UTL_SMTP.COMMAND as with the methods above. Other authentication means are also possible but again are outside the scope of this article with implementation and content requirements being determined by the server.
As of Oracle version 11.2.0.2 (available through Oracle Support, not OTN), the OPEN command was extended to allow use of wallets and introduced the STARTTLS procedure which allows us to implement SSL/TLS. If using this it is important to remember to send the EHLO command a second time after initiating TLS as the server may respond with different authentication schemes within the encrypted communication.
Even if you don't have the latest versions available, hopefully the above examples of basic SMTP authentication will help.
As always, questions and comments welcome.
Ciao!
Sean D. Stuber
by: younghv on 2011-06-03 at 05:15:50ID: 27964
Thank you for putting this out here for us.
"Yes" vote above.
I looked in your profile and saw that you have some other Articles which I will now go read.
Have you ever considered posting a link to your other Articles when you write a new one? Doing so will save us the time of digging them up.
Thanks again.