Click here to Skip to main content
Full site     10M members (42.1K online)    

SMTP Client with SSL/TLS

Introduction

I needed to send emails in a product written in C++, so I searched the Internet and found a great article: SMTP Client written by Jakub Piwowarczyk. However, many of my clients use SMTP servers that require secure connection (TLS or SSL), and the SMTP Client does not support it. So I had to add SSL/TLS support to the CSmtp class from SMTP Client before I could use it in my product. As I was new to SSL/OpenSSL, it did take me quite some time to learn how to use it properly, and to make the code work with several popular SMTP servers. I have also seen people searching the internet looking for a C++ implementation of SMTP/SSL/TLS, but just could not find one. So I decided to share the one I wrote, in the hope that it will save people who are not familiar with SSL some time.

Note that this article does not cover the details of SMTP. Please go to the original article SMTP Client if you need to know more about SMTP.

Background

There are 2 kinds of secure connections for SMTP, one is SSL and the other is TLS. Some SMTP servers support only one kind and some support both. Generally speaking, the port for SSL is 465, and the port for TLS is 587, but this is not always the case. In addition to the ports being different, SMTP/SSL is different than SMTP/TLS in that, SMTP/SSL negotiates an encrypted connection directly after the underlying TCP connection has been established, while SMTP/TLS requires that the client send a STARTLS command to the server before they negotiate an encrypted connection.

The steps involved in SMTP/SSL are as follows:

  1. The client connects to the server using TCP.
  2. The client negotiates an encrypted connection with the server.
  3. The server sends a welcome message using the encrypted connection to the client.
  4. The client sends a EHLO command using the encrypted connection to the server.
  5. The server responds to the EHLO command using the encrypted connection.

The steps involved in SMTP/TLS are as follows:

  1. The client connects to the server using TCP.
  2. The server sends a welcome message using the un-encrypted connection to the client.
  3. The client sends a EHLO command using the un-encrypted connection to the server.
  4. The server responds to the EHLO command using the un-encrypted connection.
  5. The client sends a STARTTLS command using the un-encrypted connection to the server.
  6. The server responds to the STARTTLS command using the un-encrypted connection.
  7. The client negotiates an encrypted connection with the server.
  8. The client sends a EHLO command using the encrypted connection to the server.
  9. The server responds to the EHLO command using the encrypted connection.

Using the Code

I have used openssl (http://www.openssl.org) in the sample code. The directory "openssl-0.9.8l" in the sample code contains all the necessary header files and the two pre-built static openssl libraries. If you would also like to use this version of openssl in your code, be sure to copy the entire "openssl-0.9.8l" directory to the root directory of your project and add "openssl-0.9.8l\inc32" to "Additional Include Directories", and also add "openssl-0.9.8l\out32" to "Additional Library Directories".

If you would like to build your own openssl, please refer to http://www.openssl.org for detailed instructions.

#define test_gmail_tls
    CSmtp mail;
#if defined(test_gmail_tls)
    mail.SetSMTPServer("smtp.gmail.com",587);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_gmail_ssl)
    mail.SetSMTPServer("smtp.gmail.com",465);
    mail.SetSecurityType(USE_SSL);
#elif defined(test_hotmail_TLS)
    mail.SetSMTPServer("smtp.live.com",25);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_aol_tls)
    mail.SetSMTPServer("smtp.aol.com",587);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_yahoo_ssl)
    mail.SetSMTPServer("plus.smtp.mail.yahoo.com",465);
    mail.SetSecurityType(USE_SSL);
#endif
    mail.SetLogin("***");
    mail.SetPassword("***");
    mail.SetSenderName("User");
    // ......
    mail.Send();

If you use a non-privileged user account to test Yahoo, the mail will fail to send. And the error message returned by the Yahoo SMTP server is "530 Access denied: Free users cannot access this server".

Notes

References

History

Thanks to everyone for the effective crowdsourcing!  Please keep up the improvements to our library!

  • Added fix contributed GKarRacer for the improper checking of the MsgBody.size() before working with a line of the message body.
  • Moved memory allocation and checking if all attachments can be opened to before the MAIL command is issued so that if there is an issue with one of them, sending the email can be gracefully aborted without the email being sent without the attachments.
  • Changed all the sprintf commands to snprintf to add greater security.  #define'd snprintf to sprintf_s for MS Visual C.  Also changed most strcpy calls to snprintf since the MS Visual C version of that function strcpy_s has the arguments re-ordered so it wouldn't be possible to use it without affecting portability.
  • Added fix contributed by jcyangzh about a possible infinite loop in the SayQuit function.
  • Added fixes contributed by sbrytskyy required to make the AUTH PLAIN login work properly.
 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search 
Per page   
QuestionCan I used this code in commercial applications
hp156
1 hr 45mins ago 
QuestionUsing Dev-C++ to compile the project
Wolkenpaul
12 May '13 - 0:56 
AnswerRe: Using Dev-C++ to compile the project
David Johns
12 May '13 - 11:00 
GeneralRe: Using Dev-C++ to compile the project
Wolkenpaul
12 May '13 - 21:42 
GeneralRe: Using Dev-C++ to compile the project
David Johns
20hrs 18mins ago 
GeneralRe: Using Dev-C++ to compile the project
Wolkenpaul
15hrs 16mins ago 
QuestionSevere failure with attachments that are too large (greater than 5MB limit)
GKarRacer
11 May '13 - 16:55 
AnswerRe: Severe failure with attachments that are too large (greater than 5MB limit)
David Johns
12 May '13 - 10:53 
GeneralRe: Severe failure with attachments that are too large (greater than 5MB limit)
GKarRacer
12 May '13 - 16:32 
GeneralRe: Severe failure with attachments that are too large (greater than 5MB limit)
GKarRacer
12 May '13 - 17:21 
Questionretreiving file size for attachments
GKarRacer
11 May '13 - 15:11 
AnswerRe: retreiving file size for attachments
GKarRacer
11 May '13 - 15:15 
GeneralRe: retreiving file size for attachments
David Johns
12 May '13 - 10:36 
Questionhow to set a smtp proxy?
ASERERTA@#@s
8 May '13 - 8:01 
AnswerRe: how to set a smtp proxy?
David Johns
12 May '13 - 10:52 
GeneralMy vote of 5
ASERERTA@#@s
8 May '13 - 7:54 
QuestionIncorrect range check
GKarRacer
2 May '13 - 10:03 
AnswerRe: Incorrect range check
David Johns
6 May '13 - 1:37 
SuggestionWorks on Linux. CSmtp.cpp needed #include <unistd.h> for gethostname()
jim fred
28 Apr '13 - 15:27 
GeneralRe: Works on Linux. CSmtp.cpp needed #include <unistd.h> for gethostname()
David Johns
29 Apr '13 - 15:51 
Questionsend with live.com, outlook.com or hotmail.com
ludohavil
25 Apr '13 - 7:39 
AnswerRe: send with live.com, outlook.com or hotmail.com
David Johns
25 Apr '13 - 13:45 
GeneralRe: send with live.com, outlook.com or hotmail.com
ludohavil
26 Apr '13 - 7:54 
GeneralRe: send with live.com, outlook.com or hotmail.com
David Johns
29 Apr '13 - 16:02 
GeneralRe: send with live.com, outlook.com or hotmail.com
ludohavil
1 May '13 - 5:04 
GeneralRe: send with live.com, outlook.com or hotmail.com
David Johns
5 May '13 - 1:28 
Questionvalidate email address
umeca74
17 Apr '13 - 1:31 
AnswerRe: validate email address
David Johns
17 Apr '13 - 2:13 
QuestionWonderful article
RavindraHuilgol
8 Apr '13 - 18:11 
BugThrow Exception in Destructor
altair.fang
20 Mar '13 - 16:28 
QuestionHow to get a DLL?
gmrm
19 Mar '13 - 5:42 
AnswerRe: How to get a DLL?
Member 8728402
21 Mar '13 - 6:05 
GeneralRe: How to get a DLL?
gmrm
21 Mar '13 - 23:59 
GeneralMy vote of 5
Abinash Bishoyi
21 Feb '13 - 21:38 
QuestionMail save
pippo pioppo
18 Feb '13 - 2:54 
AnswerRe: Mail save
David Johns
18 Feb '13 - 3:19 
GeneralRe: Mail save
pippo pioppo
18 Feb '13 - 4:31 
GeneralRe: Mail save
David Johns
19 Feb '13 - 1:03 
QuestionTLS/SSL Memory Leak?
mojaverider223
12 Feb '13 - 5:34 
AnswerRe: TLS/SSL Memory Leak?
David Johns
12 Feb '13 - 12:41 
GeneralRe: TLS/SSL Memory Leak?
mojaverider223
13 Feb '13 - 3:46 
GeneralRe: TLS/SSL Memory Leak?
David Johns
13 Feb '13 - 14:18 
Questionproblem with smtp.live.com
ludohavil
8 Jan '13 - 10:30 
AnswerRe: problem with smtp.live.com
malaka1
8 Feb '13 - 13:02 
GeneralRe: problem with smtp.live.com
ludohavil
13 Feb '13 - 11:24 
Bugfixed CRAM-MD5
ludohavil
8 Jan '13 - 10:27 
GeneralRe: fixed CRAM-MD5
David Johns
13 Feb '13 - 14:54 
GeneralRe: fixed CRAM-MD5
ludohavil
14 Feb '13 - 5:28 
BugFixed AUTH PLAIN
ludohavil
8 Jan '13 - 10:26 
GeneralRe: Fixed AUTH PLAIN
David Johns
13 Feb '13 - 14:56 

Last Updated 6 May 2013 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2013