C++ smtp發送郵件類(ssl/tls)-轉自codeproject。

來源:互聯網
上載者:User

原文地址:http://www.codeproject.com/Articles/98355/SMTP-Client-with-SSL-TLS

 

代碼:http://www.codeproject.com/KB/IP/smtp_ssl/CSmtp_v2_1_ssl.zip

Introduction

I needed to send emails in a product written in C++, so I searched the Internet and found a great article: SMTP Clientwritten 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 Clientbefore 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
  • The code does not verify the server's identity, that is, it does not check the server's certificate. This is usually not a big problem if we make sure we feed the program with correct server addresses. However, it is still worth mentioning that there is the chance that we are talking to an impersonator if we don't check the certificate.
  • You are not allowed to use the code in this article for spamming.
References
  • SMTP Client by Jakub Piwowarczyk
  • http://www.openssl.org
  • An Introduction to OpenSSL Programming by Eric Rescorla
History
  • Rev 2.1, 2012/11/06

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

    • Added fixes contributed by Alan P Brown for the invalid references to the SMTP_SECURITY_TYPEenumeration.
    • Added modifications contributed by Oleg Dolgov that allow it to compile in Debian Linux.
    • Added feature inspired by Leon Huang and John Tang that allows you to change the character set from the still default US-ASCII to whatever you like by calling the new member function SetCharSet().
    • Added feature inspired by Gospa that allows you to request a read receipt by calling the new member function SetReadReceipt().
    • Added modification inspired by Spike that distinguishes between Linux and Windows path delimiters in the attachment paths.
    • Added modifications inspired by Spike that uses a more simple and portable method of setting thestd::string variables.
    • Added feature contributed by Jerko that allows you to set the local host name by calling the newSetLocalHostName() member function.  If you do not call this function, it works the same as it did before.
    • Added modifications contributed by Korisk that allows it to more cleanly compile in Linux.
    • Added fixes contributed by Angenua Grupoi that fixes the behavior when the m_sNameFrom variable is not populated.
  • Rev 2.0, 2011/06/23
    • Added the m_bAuthenticate member variable to be able to disable authentication even though it may be supported by the server. It defaults to true so if it is not set, the library will act as it would have before the addition.
    • Added the ability to pass the security type, m_type, the new m_Authenticate flag, the login and password into the ConnectRemoteServer function. If these new arguments are not included in the call, the function will work as it did before.
    • Added the ability to pass the new m_Authenticate flag into the SetSMTPServer function. If not provided, the function will act as it would before the addition.
    • Added fixes contributed by Martin Kjallman
    • Added fixes contributed by Karpov Andrey
    • Added fixes contributed by Jakub Piwowarczyk
  • Rev 1.9, 2010/08/19
    • Added PLAIN, CRAM-MD5 and DIGESTMD5 authorization.
    • Added a DisconnectRemoteServer() function and reconfigured the Send() function such that if you have already called the ConnectRemoveServer() function, it will use the existing connection and leave the connection open. This allows you to call ConnectRemoteServer(), then send multiple messages on the same connection. If this approach is used, you have to call DisconnectRemoteServer() to close the connection. If you call Send() without calling ConnectRemoteServer(), it will close the connection after sending. This change should be fully backward compatible.
  • Rev 1.8, 2010/08/09
    • Updates according to Hector Santos's comment
  • 2010/08/03
    • Modified Introduction
  • 2010/08/02
    • Added note
  • 2010/08/01
    • Initial post
License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.