
Welcome to CPJNSMTPConnection. a collection of MFC classes to
support the SMTP protocol. SMTP for those not familiar with all the internet protocols is
the protocol used to send internet email.
Also included with the SMTP classes in the download is a
class called "CPJNMD5Hash" which provides for calculation of MD5
hashes and HMACs using the MS Crypto API as well as a class called "CNTLMClientAuth" which
provides a reusable client side implementation for NTLM authentication.
Important!: Please note that I
have been informed that CPJNSMTPConnection is being used to develop and
send unsolicited bulk mail. This was not the intention of the code and the
author explicitly forbids use of the code for any software of this kind without
my explicit written consent.
Please note that as of v2.70, the code is now for Visual C++ 2005 or later. I
will not be supporting VC 6 anymore for this code, so please don't email me
requesting this<gg>. Remember VC 6 is now a ten year old compiler. It's
now time to upgrade to VC
2005 or VC 2008!
References
- For information about SMTP (Simple
Mail
Transfer Protocol) you should
read RFC 821.
- For information about ESMTP (Extended Simple Mail Transfer
Protocol) which obsoletes the original SMTP RFC, you should read
RFC 2821.
- RFC 2045 which defines
how MIME attachments are to be handled in a standard SMTP message.
- RFC 822 and
RFC 2822 define the ways
standard headers are used by SMTP.
- RFC
2110 and RFC 2557 which covers MHTML
(aka HTML Email).
- Base64 encoding which is used in various places in SMTP is described in
RFC 1113 and
RFC 1421. If was
eventually referred to as Base64 in
RFC 2045
- The details about SMTP authentication are spread across a number of RFCs
including RFC 1731,
RFC 1869,
RFC 2195,
RFC 2095,
RFC 2245,
RFC 2554,
RFC 2595,
RFC 4616 and
RFC 4954.
- The CRAM-MD5 authentication scheme uses a HMAC (Hashed Message
Authentication Code) which is described in
RFC 2104, while MD5 itself
is described in RFC 1321.
- RFC 3461,
RFC 3464 ,
RFC 3798 and
RFC 3885 describe DSN's
(Delivery Status Notifications).
- The page
http://www.activexperts.com/support/activemail/auth/ includes a good
description of the AUTH LOGIN, AUTH PLAIN and AUTH CRAM-MD5 authentication
schemes which is implemented by CPJNSMTPConnection.
Features
- Simple and clean C++ interface.
- The interface provided is synchronous which
provides an easier programming model than using asynchronous sockets.
- The code does not rely on the MFC socket
classes. These classes have a number of shortcomings, one of which causes problems when
they are used in NT services.
- The code can be used in a console
application without any problems (Again this is not the case for the MFC socket classes).
- A configurable timeout for the connection
can be set through the class API.
- The classes are fully Unicode compliant and
include Unicode built options in the workspace file.
- As of v1.1, the classes now fully supports
file attachments.
- Full support is included for CC (Carbon Copy) & BCC (Blind Carbon
Copy).
- Support for regular email
address formats and multiple email address parsing.
- Full support for MIME and
MHTML (aka HTML Email).
- Full support for MIME Charsets.
- Comprehensive sample program
included which exercises most of the classes functionality.
- As of v2.61, the classes now
fully support sending email over SSL. This means that for instance you can
use the Gmail SMTP server "smtp.gmail.com" on port 465. Also note
that all of the other features such as authentication are fully supported
over SSL. For example to use Gmail you will require some form of
authentication such as AUTH PLAIN because it does not operate as an open
relay (which would facilitate spam).
- Supports numerous authentication protocols including "AUTH CRAM-MD5",
"AUTH LOGIN", "AUTH PLAIN" and "AUTH NTLM". An
"Auto Detection" form of authentication is also supported. In this mode, the
authentication protocols supported by the server are detected and the most
appropriate protocol is used.
- As of v2.65, the classes include comprehensive support for DSN's
(Delivery Status Notifications) as specified in RFC 3461.
The enclosed
zip file contains the CPJNSMTPConnection source code
and a simple test program to exercise all of the functions the classes provide.
Copyright
- You are allowed to include the source code in
any product (commercial, shareware, freeware or otherwise) when your product
is released in binary form.
- You are allowed to modify the source code in
any way you want except you cannot modify the copyright details at the top
of each module.
- If you want to distribute source code with
your application, then you are only allowed to distribute versions released
by the author. This is to maintain a single distribution point for the
source code.
- Important!!: Please note that I
have been informed that CPJNSMTPConnection is being used to develop
and send unsolicited bulk mail. This was not the intention of the code and
the author explicitly forbids use of the code for any software of this kind
without my explicit written consent.
Updates
V1.0 (26 May 1998)
V1.1 (17 June 1998)
- Fixed the case where a single dot occurs on its own in the body of a
message
- Classes now supports an optional "Reply-To" Header Field
- Classes now fully supports file attachments
- Some rework on the contents of the help file
V1.11 (18 June 1998)
- Fixed a memory overwrite problem which was occurring with the buffer
used for encoding base64 attachments.
V1.12 (27 June 1998)
- The case where a line begins with a "." but contains other
text is now also catered for. See RFC821, Section 4.5.2 for further details.
- m_sBody in CSMTPMessage has now been made protected. Client
applications now should call AddBody instead. This ensures that FixSingleDot is only
called once even if the same message is sent a number of times.
- Fixed a number of problems with how the MIME boundaries were defined
and sent.
- Got rid of an unreferenced formal parameter compiler warning when
doing a release build.
- Thanks to Chris Davidson for the all the suggestions and bug
fixes.
V1.2 (11 August 1998)
- VC 5 project file is now provided
- Attachment array which the message class contains now uses references
instead of pointers.
- Now uses Sleep(0) to yield our time slice instead of Sleep(100), this
is the preferred way of writing polling style code in Win32 without severely impacting
performance.
- All Trace statements now display the value as returned from
GetLastError
- A number of extra asserts have been added
- A AddMultipleRecipients function has been added which supports added
a number of recipients at one time from a single string. Thanks go to Bob Yang for
suggested the function and providing code.
- Extra trace statements have been added to help in debugging
V1.21 (12 September 1998)
- Removed a couple of unreferenced variable compiler warnings
discovered when the class was compiled on Visual C++ 6.0.
- Fixed a major bug which was causing an ASSERT when the
CSMTPAttachment destructor was being called in the InitInstance of the sample app. This
was inadvertently introduced for the 1.2 release. The fix is to revert fix 2) as done for
v1.2. This new fix will also help to reduce the number of attachment images kept in memory
at one time.
- Fixed a few errors in the help file.
8 November 1998
Philip K Chung has taken
the CPJNSMTPConnection class and developed a version which has the following features:
- no more MFC
- all collection classes and string classes from STL
- attempted to make it thread safe by making it essentially
free-threaded (i.e. it should be able to handle multiple threads entering its code at the
same time
- broke it out into separate modules and added a precompiled header to
speed up compiling
- turned the whole thing into a DLL with a SINGLE entry point, i.e. see
the public header file
- changed the directory structure around. public header file is under
.../common/include and resultant DLL gets copied over to .../common/bin
- added support for CC and BCC
The code can be downloaded here.
I would ask you to forward any queries relating to this code to Philip as I am only
hosting the code as a favor to him as he does not maintain a web site of his own.
V1.3 (18 January 1998)
- Full support has now been added for CC (Carbon Copy) & BCC (Blind
Carbon Copy).
V1.31 (22 February 1999)
- Added a Get and SetTitle method which allows a files attachment title
to be different that the original filename.
- Updated sample app to include a more descriptive subject line.
- Default timeout for the code when a debug build is built has now been
set to 60 seconds.
- Improved the reading of responses back from the server by
implementing a growable receive buffer.
- Updated instructions on how the relevant RFC documents can be
retrieved.
V1.32 (25 March 1999)
- Now sleeps for 250 ms instead of yielding the time slice. This helps
reduce CPU usage when waiting for data to arrive in the socket.
V1.33 (14 May 1999)
- Updated documentation to refer to RFC 822.
- Fixed a bug with the way the code generates time zone
fields in the Date headers. Thanks to Randy
A. Scott for reporting this bug.
V1.34 (10 September 1999)
- Improved CSMTPMessage::GetHeader to include mime field even when no attachments
are included.
V1.35 (5 October 1999)
- Fixed 2 level 4 warnings when compiled using VC 6.
V1.36 (16 February 2000)
- Fixed another compiler problem when compiled with VC 6.
V1.37 (19 March 2000)
- Fixed a problem in GetHeader on Non-English Windows
machines
- Now ships with a VC 5 workspace. I accidentally shipped
a VC 6 version in one of the previous versions of the code.
- Fixed a number of UNICODE problems
- Updated the sample app to deliberately assert before
connecting to the author's SMTP server.
V1.38 (26 March 2000)
- Updated the sample app provided with the code to be a
mini mail client. This should now also give a better idea of what the code
can be used for.
V1.39 (28 March 2000)
- Set the release mode timeout to be 10 seconds. 2 seconds was causing problems for slow dial
up networking connections.
V1.40 (7 May 2000)
- Addition of some ASSERT's in CSMTPSocket::Connect.
V1.41 (20 June 2000)
- Removed the base64 encoder from this file
- Added the base64 encoder/decoder implementation in a separate file. This was done because base64 decoding was not part of the previous implementation
- Added support for ESMTP connection. The class now attempts to authenticate the user on the ESMTP server using the username and
passwords supplied. For this connect now takes the username and passwords as parameters. These can be null in which case ESMTP authentication is not attempted
- This class can now handle AUTH LOGIN and AUTH LOGIN PLAIN authentication
schemes
- Added the files md5.* containing the MD5 digest generation code
after modifications so that it compiles with VC++ 6
- Added the CRAM-MD5 login procedure.
- Please note that all the support for SMTP
authentication was added by Puneet Pawaia to which I am gratefully
appreciated for all the hard work put in.
V2.0 (21 June 2000)
- Now includes a number of files missing from the zip
file.
- Updated the version number to v2 to reflect the major
changes which occurred in v1.41
V2.01 (10 July 2000)
- Fixed a problem with sending attachments > 1K in
size.
- Changed the parameters to CPJNSMTPConnection::Connect
V2.02 (30 July 2000)
- Fixed a bug in AuthLogin which was transmitting the
username and password with an extra "=" which was causing the
login to failure. Thanks to Victor Vogelpoel for finding this.
V2.03 (5 September 2000)
- Added a CSMTP_NORSA preprocessor macro to allow the
CPJNSMTPConnection
code to be compiled without the dependence on the RSA code.
V2.04 (28 December 2000)
- Removed an unused variable from ConnectESMTP.
- Allowed the hostname as sent in the HELO command to be
specified at run time in addition to using the hostname of the client
machine
- Fixed a problem where high ASCII characters were not
being properly encoded in the quoted-printable version of the body sent.
- Added support for user definable charset's for the
message body.
- Mime boundaries are now always sent irrespective of
whether attachments are included or not. This is required as the body is
using quoted-printable.
- Fixed a bug in sendLines which was causing small
message bodies to be sent incorrectly
- Now fully supports custom headers in the SMTP message
- Fixed a copy and paste bug where the default port for
the SMTP socket class was 110.
- You can now specify the address on which the socket is
bound. This enables the programmer to decide on which NIC data should be
sent from. This is especially useful on a machine with multiple IP
addresses.
- Addition of functions in the SMTP connection class to
auto dial and auto disconnect to the Internet if you so desire.
- Sample app has been improved to allow Auto Dial and
binding to IP addresses to be configured.
- Thanks go to Yaroslav Liapkov, Josef Hampl, Duncan
Strand, Fritz Roland "Nick" Bjorklund, Lev Elbert and Perry Rapp
for finding these problems and/or suggesting the improvements.
V2.1 (14 May 2001)
- Charset now defaults to ISO 8859-1 instead of us-ascii
- Removed a number of unreferenced variables from the sample app.
- Headers are now encoded if they contain non ascii characters.
- Fixed a bug in getLine, Thanks to Lev Evert for spotting this one.
- Made the charset value a member of the message class instead of the connection class
- Sample app now fully supports specifying the charset of the message
- Added a AddMultipleAttachments method to CSMTPMessage
- Attachments can now be copied to each other via new methods in CSMTPAttachment
- Message class now contains copies of the attachments instead of pointers to them
- Sample app now allows multiple attachments to be added
- Removed an unnecessary assert in QuotedPrintableEncode
- Added a Mime flag to the CSMTPMessage class which allows you to decide whether or not a message
should be sent as MIME. Note that if you have attachments, then mime is assumed.
- CSMTPAttachment class has now become CSMTPBodyPart in anticipation of full support for MIME and MHTML email support
- Updated copyright message in source code and documentation
- Fixed a bug in GetHeader related to _tsetlocale usage. Thanks to Sean McKinnon for spotting this problem.
- Fixed a bug in SendLines when sending small attachments. Thanks to Deng Tao for spotting this problem.
- Removed the need for SendLines function entirely.
- Now fully supports HTML email (aka MHTML)
V2.11 (17 June 2001)
- Fixed a bug in CSMTPMessage::HeaderEncode where spaces were not being interpreted correctly. Thanks to Jim Alberico for spotting this.
- Fixed 2 issues with ReadResponse both having to do with multi-line responses. Thanks to Chris Hanson for this update.
V2.12 (25 June 2001)
- Code now links in Winsock and RPCRT40 automatically.
This avoids client code having to specify it in their linker settings.
Thanks to Malte and Phillip for spotting this issue.
- Updated sample code in documentation. Thanks to Phillip
for spotting this.
- Improved the code in CSMTPBodyPart::SetText to ensure
lines are correctly wrapped. Thanks to Thomas Moser for this fix.
V2.13 (1 July 2001)
- Modified QuotedPrintableEncode to prevent the code to
enter in an infinite loop due to a long word i.e. bigger than SMTP_MAXLINE,
in this case, the word is broken. Thanks to Manuel Gustavo Saraiva for this
fix.
- Provided a new protected variable in CSMTPBodyPart
called m_bQuotedPrintable to bypass the QuotedPrintableEncode function in
cases that we don't want that kind of correction. Again thanks to Manuel
Gustavo Saraiva for this fix.
V2.14 (15 July 2001)
- Improved the error handling in the function
CSMTPMessage::AddMultipleAttachments. In addition the return value has been
changed from BOOL to int.
V2.15 (13 August 2001)
- Fixed a bug in QuotedPrintableEncode which was wrapping encoding characters across multiple lines. Thanks to Roy He for spotting this.
- Provided a "SendMessage" method which sends a email directly from disk. This allows you to construct your own emails and the use the class just to do the sending. This function also has the advantage that it efficiently uses memory and reports progress.
- Provided support for progress notification and cancelling via the "OnSendProgress" virtual method.
V2.16 (29 September 2001)
- Fixed a bug in ReadResponse which occurred when you
disconnected via Dial-Up Networking while a connection was active. This was
originally spotted in my POP3 class.
- Fixed a problem in CSMTPBodyPart::GetHeader which was
always including the "quoted-printable" even when
m_bQuotedPrintable for that body part was FALSE. Thanks to "jason"
for spotting this.
Eric Fontana has taken
the CPJNSMTPConnection class and developed a COM version which has the following features:
- In proc dll COM interface
- Supports IDispatch so can be called from ASP, VBScript,
JScript etc
The code can be downloaded here.
I would ask you to forward any queries relating to this code to Eric as I am only
hosting the code as a favor to him.
V2.17 (12 October 2001)
- Fixed a problem where GetBody was reporting the size as 1 bigger than it should have been. Thanks to "c f" for spotting this problem.
- Fixed a bug in the TRACE statements when a socket connection cannot be made.
- The sample app now displays a filter of "All Files" when selecting
attachments to send.
- Fixed a problem sending 0 byte attachments. Thanks to Deng Tao
for spotting this problem.
3 December 2001
- Included item in copyright about the use of class in
bulk mailers.
V2.18 (11 January 2002)
- Now includes a method to send a message directly from memory. Thanks to Tom Allebrandi for this suggestion.
- Change function name "IsReadible" to be "IsReadable". I was never very good at English!.
- Fixed a bug in CSMTPBodyPart::QuotedPrintableEncode.
If a line was exactly 76 characters long plus \r\n
it produced an invalid soft line break of
"\r=\r\n\n". Thanks to Gerald Egert for spotting this problem.
13 January 2002
- Minor update to the sample app to fix a bug in
browsing for attachments, Core classes not changed.
V2.19 (29 July 2002)
- Fixed an access violation in CSMTPBodyPart::QuotedPrintableEncode. Thanks to Fergus Gallagher for spotting this problem.
- Fixed a problem where in very rare cases, the QuotedPrintableEncode function produces a single dot in a line, when inserting the "=" to avoid the mail server's maxline limit. I inserted a call to FixSingleDot after calling the QuotedPrintableEncode function in GetBody. Thanks to Andreas Kappler for spotting this
problem.
- Fixed an issue in CSMTPBodyPart::GetHeader which ensures
all mail clients can correctly handle
body parts and attachments which have a filename with spaces in it. Thanks to Andreas
Kappler for
spotting this problem.
- QP encoding is now only used when you specify MIME. This fixes a bug as reported by David Terracino.
- Removed now unused "API Reference" link in HTML file
supporting
the code.
V2.20 (10 August 2002)
- Fixed a number of uncaught file exceptions in CSMTPBodyPart::GetBody, CSMTPMessage::SaveToDisk and
CPJNSMTPConnection::SendMessage. Thanks to John Allan Miller for reporting this problem.
- The CPJNSMTPConnection::SendMessage version of the method which sends a file directly from disk, now fails if the file is empty.
- Improved the sample app by displaying a wait cursor while a message from file is being sent.
- Improved the sample app by warning the user if mail settings are missing and then bringing up the configuration dialog.
V2.21 (20 September 2002)
- Fixed a problem where the code "Coder.EncodedMessage" was not being converted from an ASCII string to a UNICODE string in calls to CString::Format. This was occurring when sending the username and password for "AUTH LOGIN" support in addition to sending the "username digest" for "AUTH CRAM-MD5" support. Thanks to Serhiy Pavlov for reporting this problem.
- Removed a number of calls to CString::Format and instead replaced with string literal CString constructors instead.
V2.22 (3 October 2002)
- Quoted printable encoding didn't work properly in UNICODE. (invalid conversion from TCHAR to BYTE). Thanks to Serhiy Pavlov for reporting this problem.
- Subject encoding didn't work properly in UNICODE. (invalid conversion from TCHAR to BYTE). Thanks to Serhiy Pavlov for reporting this problem.
- It didn't insert "charset" tag into root header for plain text messages (now it includes "charset" into plain text messages too). Thanks to Serhiy Pavlov for reporting this problem.
V2.23 (4 October 2002)
- Fixed an issue where the header / body separator was not being sent correctly for mails with attachments or when
the message is MIME encoded. Thanks to Serhiy Pavlov for reporting this problem.
- Fixed a bug in QuotedPrintableEncode and HeaderEncode which was causing the errors. Thanks to Antonio Maiorano for reporting this problem.
- Fixed an issue with an additional line separator being sent between the header and body of emails. This was only
evident in mail clients if a non mime email without attachments was sent.
V2.24 (11 December 2002)
- Review all TRACE statements for correctness
- Provided a virtual OnError method which gets called
with error information.
V2.25 (7 February 2003)
- Addition of a "BOOL bGracefully" argument to Disconnect
so that when an application cancels the sending of a message, you can
pass FALSE and close the socket without properly terminating the SMTP
conversation. Thanks to "nabocorp" for this nice addition.
- Did a spell check on the documentation <g>.
9 February 2003
- Updated the sample app to display a simple progress
dialog when you send a message from disk (not using the "Send Direct") option.
This provides a sample of how you can implement a cancellable send of a
message with progress support. Thanks to "nabocorp" for suggesting this
addition to the sample.
V2.26 (19
March 2003)
- Addition of copy constructors and operator= to
CSMTPMessage class. Thanks to Alexey Vasilyev for this suggestion.
V2.27 (13
April 2003)
- Fixed a bug in the handling of EHLO responses. Thanks
to "Senior" for the bug report and the fix.
V2.28 (17
April 2003)
- Enhanced the CSMTPAddress constructor to parse out the
email address and friendly name rather than assume it is an email address.
- Reworked the syntax of the
CSMTPMessage::ParseMultipleRecipients method. Also now internally this
function uses the new CSMTPAddress constructor.
V2.29 (19
April 2003)
- Fixed a bug in the CSMTPAddress constructor where I was
mixing up the friendly name in the "<>" separators, when it should have been
the email address.
V2.30 (4
May 2003)
- Fixed an issue where the class doesn't convert the mail
body and subject to the wanted encoding but rather changes the encoding of the
email in the email header. Since the issue of supporting several languages is
a complicated one I've decided that we could settle for sending all
CPJNSMTPConnection emails in UTF-8. I've added some conversion functions to the
class that - at this point - always converts the body and subject of the email
to UTF-8. A big thanks to Itamar Kerbel for this nice addition.
- Moved code and sample app to VC 6.
V2.31 (5
May 2003)
- Reworked the way UTF8 encoding is now done. What you
should do if you want to use UTF-8 encoding is set the charset "UTF-8"
and use either QP or base 64 encoding.
- Reworked the automatic encoding of the subject line to
use the settings as taken from the root SMTP body part
- Only the correct headers according to the MIME RFC are
now encoded.
- QP encoding is the encoding mechanism now always used
for headers.
- Headers are now only encoded if required to be encoded.
V2.32 (12
May 2003)
- Fixed a bug where the X-Mailer header was being sent
incorrectly. Thanks to Paolo Vernazza for reporting this problem.
- Addition of X-Mailer header is now optional. In
addition sample app now does not send the X-Mailer header.
- The sample app now does not send the Reply-To header.
18 August 2003
- Christian
Andersen has taken
the CPJNSMTPConnection class and developed a version runs on Windows CE. The code can be downloaded
here.
I would ask you to forward any queries relating to this code to Christian as I am only
hosting the code as a favor to him.
V2.33 (18 August
2003)
- Modified the return value from the ConnectToInternet
method. Instead of it being a boolean, it is now an enum. This allows client
code to differentiate between two conditions that it couldn't previously,
namely when an internet connection already existed or if a new connection
(presumably a dial-up connection was made). This allows client code to then
disconnect if a new connection was required. Thanks to Pete Arends for this
nice addition.
19 August
2003
- Updated the sample app to avoid a memory leak. It turns
out that it was to do with the ordering of <string> in the pre compiled
header. I was never too fond of STL and this has confirmed my prejudices.
Thanks to Damian Willis for reporting this problem.
V2.34 (15 October
2003)
- Reworked the CPJNSMTPConnection::ReadResponse method to
use the timeout provided by IsReadable rather than calling sleep. Thanks to
Clarke Brunt for reporting this issue.
V2.35 (3 November
2003)
- Simplified the code in CPJNSMTPConnection::ReadResponse.
Thanks to Clarke Brunt for reporting this issue.
V2.36 (3 December
2003)
- Made code which checks the Login responses which
contain "Username" and "Password" case insensitive. Thanks to Zhang xiao Pan for
reporting this problem.
V2.37 (11 December
2003)
- Fixed an unreferrenced variable in
CPJNSMTPConnection::OnError as reported by VC.Net 2003
- DEBUG_NEW macro is now only used on VC 6 and not on VC
7 or VC 7.1. This avoids a problem on these compilers where a conflict exists
between it and the STL header files. Thanks to Alex Evans for reporting this
problem.
V2.38 (31 January
2004)
- Fixed a bug in CSMTPBodyPart::GetBody where the size of
the body part was incorrectly calculating the size if the encoded size was an
exact multiple of 76. Thanks to Kurt Emanuelson and Enea Mansutti for
reporting this problem.
V2.39 (7 February
2004)
- Fixed a bug in CSMTPBodyPart::SetText where the code
would enter an endless loop in the Replace function. It has now been replaced
with CString::Replace. This now means that the class will not now compile on
VC 5. Thanks to Johannes Philipp Grohs for reporting this problem.
- Fixed a number of warnings when the code is compiled
with VC.Net 2003. Thanks to Edward Livingston for reporting this issue.
V2.40 (18 February
2004)
- You can now optionally set the priority of an email
thro the variable CSMTPMessage::m_Priority. Thanks to Edward Livingston for
suggesting this addition.
V2.41 (4 March
2004)
- To avoid conflicts with the ATL Server class of the
same name, namely "CSMTPConnection", the class is now called "CPJNSMTPConnection".
To provide for easy upgrading of code, "CSMTPConnection" is now defined to be
"CPJSMTPConnection" if the code detects that the ATL Server SMTP class is not
included. Thanks to Ken Jones for reporting this issue.
V2.42 (13 March
2004)
- Fixed a problem where the
CSMTPBodyPart::m_dwMaxAttachmentSize value was not being copied in the
CSMTPBodyPart::operator= method. Thanks to Gerald Egert for reporting this
problem and the fix.
V2.43 (5 June
2004)
- Fixed a bug in CSMTPConnection::ReadResponse, where the
wrong parameters were being null terminated. Thanks to "caowen" for this
update.
- Updated the CSMTPConnection::ReadResponse function to
handle multiline responses in all cases. Thanks to Thomas Liebethal for
reporting this issue.
V2.44 (7 June
2004)
- Fixed a potential buffer overflow issue in
CSMTPConnection::ReadResponse when certain multi line responses are received
V2.45 (30 September
2004)
- Fixed a parsing issue in CPJNSMTPConnection::ReadResponse when multi line responses are read in as multiple packets. Thanks to Mark Smith for reporting this problem.
- Reworked the code which supports the various authentication mechanisms to support the correct terms. What was called "AUTH LOGIN PLAIN" support now more correctly uses the term "AUTH PLAIN". The names of the functions and enums have now also been reworked.
- Did a review of the sample app code provided with the class so that the name of the modules, projects, exe etc is now "PJNSMTPApp". Also reworked the name of some helper classes as well as the module name which supports the main class.
- Reworked CPJNSMTPConnection::AuthLoginPlain (now called AuthPlain) to correctly handle the case where an invalid response is received when expecting the username: response. Thanks to Mark Smith for reporting this problem.
V2.46 (23 December
2004)
- "Name" field in Content-Type headers is now quoted just like the filename field. Thanks to Mark Smith for reporting this issue in conjunction with the mail client Eudora.
V2.47 (24 January
2005)
- All classes now uses exceptions to indicate errors. This means the whole area of handling errors in the code a whole lot simpler. For example the OnError mechanism is gone along with all the string literals in the code. The actual code itself is a whole lot simpler also. You should carefully review your code as a lot of the return values from methods (especially CPJNSMTPConnection) are now void and will throw CSMTPException's. Thanks to Mark Smith for prompting this update.
- General tidy up of the code following the testing of the new exception based code.
19 February 2005
- Updated the usage section of the documentation to
describe what is required to integrate the code into your applications.
Thanks to Matthew Tompkins for prompting this update.
V2.48 (7 March
2005)
- Addition of PJNSMTP_EXT_CLASS define to the classes to allow the classes to be easily incorporated into extension DLLs. Thanks to Arnaud Faucher for suggesting this addition.
- Now support NTLM authentication. Thanks to Arnaud Faucher for this nice addition. NTLM Authentication is provided by a new reusable class called "CNTLMClientAuth" in PJNNTLMAuth.cpp/h".
- Fixed a bug in the sample app in the persistence of the Authentication setting. Thanks to Arnaud Faucher for reporting this issue.
V2.49 (26 March
2005)
- Fixed compile problems with the code when the Force Conformance In For Loop Scope compile setting is used in Visual Studio .NET 2003. Thanks to Alexey Kuznetsov for reporting this problem.
- Fixed compile problems when the code is compiled using the Detect 64-bit Portability Issues setting in Visual Studio .NET 2003.
V2.50 (18 April
2005)
- Addition of a simple IsConnected() function inline with the author's CPop3Connection class. Thanks to Alexey Kuznetsov for prompting this addition.
- Addition of a MXLookup function which provides for convenient DNS lookups of MX records (the IP addresses of SMTP mail servers for a specific host domain). Internally this new function uses the new
DNS functions which are provided with Windows 2000 or later. To ensure that the code continues to work correctly on earlier versions of Windows, the function pointers for the required functions are constructed at runtime using GetProcAddress.
You can use this function to discover the IP address of the mail servers
responsible for a specific domain. This allows you to deliver email directly
to a domain rather than through a third party mail server. Thanks to Hans Dietrich for suggesting this nice addition.
V2.51 (23 April
2005)
- The code now uses a MS Crypto API implementation of the MD5 HMAC algorithm instead of custom code based on the RSA MD5 code. This means that there is no need for the RSA MD5.cpp, MD5.h and glob-md5.h to be included in client applications. In addition the build configurations for excluding the RSA MD5 code has been removed from the sample app. The new classes to perform the MD5 hashing are contained in PJNMD5.h and are generic enough to be included in client applications in their own right.
V2.52 (1 May
2005)
- Now uses the author's CWSocket sockets wrapper class.
- Added support for connecting via Socks4, Socks5 and HTTP proxies
- The last parameter to Connect has now been removed and is configured via an accessor / mutator pair Get/SetBoundAddress.
- CSMTPException class is now called CPJNSMTPException.
- Class now uses the Base64 class as provided with CWSocket. This means that the modules Base64Coder.cpp/h are no longer distributed or required and should be removed from any projects which use the updated SMTP classes.
- Fixed a bug in SaveToDisk method whereby existing files were not being truncated prior to saving the email message.
- All calls to allocate heap memory now generate a CPJNSMTPException if the allocation fails.
- Addition of a MXLookupAvailable() function so that client code can know a priori if DNS MX lookups are supported.
- Sample app now allows you to use the MXLookup method to determine the
mail server to use based on the first email address you provide in the To field.
V2.53 (3 May
2005)
- Updated the usage section to describe the need to have
the Platform SDK installed and configured.
- Fixed a number of warnings when the code is compiled in Visual Studio .NET 2003. Thanks to Nigel Delaforce for reporting these issues.
18 May
2005
- Fixed a compiler warning in the CPJNMD5Hash class when compiled using Visual Studio .NET 2003. Thanks to Alexey Kuznetsov
for reporting this issue.
V2.54 (24 July
2005)
- Now includes support for parsing "(...)" comments in addresses. Thanks to Alexey Kuznetsov for this nice addition.
- Fixed an issue where the mail header could contain a "Content-Transfer-Encoding" header. This header should only be applied to headers of MIME body parts rather than the mail header itself. Thanks to Jeroen van der Laarse, Terence Dwyer and Bostjan Erzen for reporting this issue and the required fix.
- Now calling both AddTextBody and AddHTMLBody both set the root body part MIME type to multipart/mixed. Previously the code comments said one thing and did another (set it to "multipart/related"). Thanks to Bostjan Erzen for reporting this issue.
V2.55 (14 August
2005)
- Minor update to include comments next to various locations in the code to inform users what to do if they get compile errors as a result of compiling the code without the Platform SDK being installed. Thanks to Gudjon Adalsteinsson for prompting this update.
- Fixed an issue when the code calls the function
DnsQuery when the code is compiled for UNICODE. This was the result of a documentation error in the Platform SDK which incorrectly says that DnsQuery_W takes a ASCII string when in actual fact it takes a UNICODE string. Thanks to John Oustalet III for reporting this issue.
V2.56 (5 September 2005)
- Fixed an issue in MXLookup method where memory was not being freed correctly in the call to DnsRecordListFree. Thanks to Raimund Mettendorf for reporting this bug.
- Fixed an issue where lines which had a single dot i.e. "." did not get mailed correctly. Thanks to Raimund Mettendorf for reporting this issue.
- Removed the call to FixSingleDot from SetText method as it is done at runtime as the email as being sent. This was causing problems for fixing up the dot issue when MIME encoded messages were being sent.
- Function pointer to CompleteAuthToken is now constructed at runtime. This means that NTLM client authentication will work correctly on Win9x as used by the class CPJNSMTPConnection and any other class instead of bringing up a "Failed to load due to missing export..." message from the Windows loader. If
you want to remove the NTLM support from CPJNSMTPConnection
then you can continue to use the CPJNSMTP_NONTLM preprocessor define. Thanks to "Lior" for reporting this problem.
- Fixed an issue where the FixSingleDot function was
being called when saving a message to disk. This was incorrect and it should
only be done when actually sending an SMTP email.
V2.57 (7 September 2005)
- Fixed another single dot issue, this time where the
body is composed of just a single dot. Thanks to Raimund Mettendorf for
reporting this issue.
- Fixed a typo in the accessor function CPJNSMTPConnection::GetBoundAddress which was incorrectly called CPJNSMTPConnection::SetBoundAddress.
Thanks to Pavel Kolar for reporting this.
V2.58 (29 September 2005)
- Removed linkage to secur32.lib as all SSPI functions are now constructed at runtime using GetProcAddress. Thanks to Emir Kapic for this update.
- MD5 Format method now allows you to specify an uppercase or lower case string for the hash. This is necessary since the CRAM-MD5 authentication mechanism requires a lowercase MD5 hash. Thanks to Jian Peng for reporting this issue.
- 250 or 251 is now considered a successful response to the RCPT command. Thanks to Jian Peng for reporting this issue.
- Fixed potential memory leaks in the implementation of NTLM authentication as the code was throwing exceptions which the authentication code was not expected to handle.
V2.59 (2 October 2005)
- MXLookup functionality of the class can now be excluded via the preprocessor define "CPJNSMTP_NOMXLOOKUP". Thanks to
Thiago Luiz for prompting this update.
- Sample app now does not bother asking for username and password if authentication type is NTLM. Thanks to Emir Kapic
for spotting this issue.
- Documentation has been updated to refer to issues with NTLM Authentication and SSPI. Thanks to Emir Kapic for
prompting this update.
- Fixed an update error done for the previous version which incorrectly supported the additional 251 command for the "MAIL"
command instead of more correctly the "RCPT" command. Thanks to Jian Peng for reporting this issue.
V2.60 (7 October 2005)
- Fixed an issue where file attachments were incorrectly including a charset value in their headers. Thanks to Asle Rokstad for reporting this issue.
V2.61 (16 November 2005)
- Now includes full support for connecting via SSL. For example sending mail thro Gmail using the server "smtp.gmail.com" on port 465. Thanks to Vladimir Sukhoy for providing this very nice addition (using of course the author's very own OpenSSL wrappers!).
9 December 2005
- Updated the usage section of the documentation on how
to correctly exclude the SSL functionality from the class. Thanks to Berni
Slootbeek for prompting this update.
- Updated the usage section of the documentation on the
preferred way of formatting CID tags for MHTML emails. Thanks to Asle
Rokstad for prompting this update.
V2.62 (29 June 2006)
- Updated the documentation to use the same style as the web site.
- Combined the functionality of the _PJNNTLMCLIENTAUTH_DATA class into the
main CNTLMClientAuth class.
- Code now uses new C++ style casts rather than old style C casts where
necessary.
- Integrated ThrowPJNSMTPException function into CPJNSMTPConnection class
and renamed to ThrowPJNSMTPException
- Combined the functionality of the _PJNSMTP_DATA class into the main
CPJNSMTPConnection class.
- Updated the code to clean compile on VC 2005
- Updated copyright details.
- Removed unnecessary checks for failure to allocate via new since in MFC
these will throw CMemoryExceptions!.
- Optimized CPJNSMTPException constructor code
V2.63 (14 July 2006)
- Fixed a bug in CPJNSMTPConnection where when compiled in UNICODE mode,
NTLM authentication would fail. Thanks to Wouter Demuynck for providing the
fix for this bug.
- Reworked the CPJNSMTPConnection::NTLMAuthPhase(*) methods to throw
standard CPJNSMTPException exceptions if there are any problems detected.
This can be done now that the CNTLMClientAuth class is resilient to
exceptions being thrown.
- Updated CNTLMClientAuth to use newer C++ style casts.
- Made the CNTLMClientAuth::NTLMAuthenticate function "exception"
safe, that is derived classes are free to throw exceptions in their
implementations of NTLMAuthPhase1, NTLMAuthPhase2 or NTLMAuthPhase3 and the
CNTLMClientAuth class will properly clean up its resources. This is achieved
by making the CredHandle and SecHandle values member variables of the class.
- Replaced all calls to ZeroMemory with memset.
- Now the public NTLMAuthenticate function allows you to pass a user name
and password pair to do NTLM authentication using a specified account
instead of the credentials of the current user. If you leave these
values as NULL, then you will get the old behaviour which is to use the
current user credentials. Thanks to Wouter Demuynck for this very nice
addition.
17 July 2006
- Updated the code in the sample app to allow > 30000 characters to be
entered into the edit box which contains the body of the email. This is
achieved by placing a call to CEdit::SetLimitText in the OnInitDialog method
of the dialog. Thanks to Thomas Noone for reporting this issue.
V2.64 (13 October 2006)
- Code now initializes the Domain name value in
CNTLMClientAuth::NTLMAuthenticate to an empty string instead of a NULL
string. This avoids NTLM authentication issues when authenticating as a
non-domain user with certain mail servers. Thanks to Wouter Demuynck for
reporting this issue.
- Fixed an issue in Disconnect where if the call to ReadCommandResponse
threw an exception, we would not close down the socket or set m_bConnected
to FALSE. The code has been updated to ensure these are now done. This just
provides a more consistent debugging experience. Thanks to Alexey Kuznetsov
for reporting this issue.
- CPJNSMTPException::GetErrorMessage now uses the user default locale for
formatting error strings.
- Fixed some issues with cleaning up of header and body parts in
CPJNSMTPConnection::SendBodyPart and CPJNSMTPMessage::WriteToDisk. Thanks to
Xiao-li Ling for reporting this issue.
V2.65 (11 November 2006)
- Reverted CPJNSMTPException::GetErrorMessage to use the system default
locale. This is consistent with how MFC does its own error handling.
- Now includes comprehensive support for DSN's (Delivery Status
Notifications) as specified in RFC 3461. Thanks to Riccardo Raccuglia for
prompting this update.
- CPJNSMTPBodyPart::GetBody and CPJNSMTPConnection::SendMessage(const
CString& sMessageOnFile... now does not open the disk file for exclusive
read access, meaning that other apps can read from the file. Thanks to
Wouter Demuynck for reporting this issue.
- Fixed an issue in CPJNSMTPConnection::SendMessage(const CString&
sMessageOnFile... where under certain circumstances we could end up deleting
the local "pSendBuf" buffer twice. Thanks to Izidor Rozman for reporting
this issue.
V2.66 (30 March 2007)
- Fixed a bug in CPJNSMTPConnection::SetHeloHostname where an unitialized
stack variable could potentially be used. Thanks to Anthony Kowalski for
reporting this bug.
- Updated copyright details.
V2.67 (1 August 2007)
- AuthCramMD5, ConnectESMTP, ConnectSMTP, AuthLogin, and AuthPlain methods
have now been made virtual.
- Now includes support for a Auto Authentication protocol. This will
detect what authentication methods the SMTP server supports and uses the
"most secure" method available. If you do not agree with the order in which
the protocol is chosen, a virtual function called "ChooseAuthenticationMethod"
has been provided.
Thanks to "zhangbo" for providing this very nice addition to the code.
- Removed the definition for the defunct "AuthNTLM" method.
V2.70 (13 November 2007)
- Major update to the code to use VC2005 specific features. This version
of the code and onwards will be supported only on VC 2005 or later. Thanks
to Andrey Babushkin for prompting this update. Please note that there has
been breaking changes to the names and layout of various methods and member
variables. You should carefully analyze the sample app included in the
download as well as your client code for the required updates you will need
to make.
- Sample app included in download is now build for Unicode and links
dynamically to MFC. It also links dynamically to the latest OpenSSL 0.9.8g
dlls.
V2.71 (19 November 2007)
V2.72 (23 December 2007)
- Following feedback from Selwyn Stevens that the AUTH PLAIN mechanism was
failing for him while trying to send mail using the gmail SMTP server, I
decided to go back and re-research the area of SMTP authentication again<g>.
It turns out that the way I was implementing AUTH PLAIN support was not the
same as that specified in the relevant RFCs. The code has now been updated
to be compliant with that specified in the RFC. I've confirmed the fix as
operating correctly by using the gmail SMTP mail server at "smtp.gmail.com"
on the SMTP/SSL port of 465. I've also taken the opportunity to update the
documentation to include a section with links to various RFC's and web pages
for background reference material
V2.73 (24 December 2007)
- CPJNSMTPException::GetErrorMessage now uses the
FORMAT_MESSAGE_IGNORE_INSERTS flag. For more information please see Raymond
Chen's blog at
http://blogs.msdn.com/oldnewthing/archive/2007/11/28/6564257.aspx.
Thanks to Alexey Kuznetsov for reporting this issue.
- All username and password temp strings are now securely destroyed using
SecureZeroMemory.
V2.74 (31 December 2007)
- Updated the sample app to clean compile on VC 2008
- Fixed a x64 compile problems in RemoveCustomHeader &
AddMultipleAttachments.
- Fixed a x64 compile problem in
CPJNSMTPAppConfigurationDlg::CBAddStringAndData
- CPJNSMTPException::GetErrorMessage now uses Checked::tcsncpy_s
- Other Minor coding updates to CPJNSMTPException::GetErrorMessage
V2.75 (2 February 2008)
- Updated copyright details.
- Fixed a bug in CPJNSMTPMessage::FormDateHeader where sometimes an
invalid "Date:" header is created. The bug will manifest itself for anywhere
that is ahead of GMT, where the difference isn't a multiple of one hour.
According to the Windows Time Zone applet, this bug would have occured in:
Tehran, Kabul, Chennai, Kolkata, Mumbai, New Delhi, Sri Jayawardenepura,
Kathmandu, Yangon, Adelaide and Darwin. Thanks to Selwyn Stevens for
reporting this bug and providing the fix.
V2.76 (1 March 2008)
- CPJNSMTP Priority enum values, specifically NO_PRIORITY have been
renamed to avoid clashing with a #define of the same name in the Windows SDK
header file WinSpool.h. The enum values for DSN_RETURN_TYPE have also been
renamed to maintain consistency. Thanks to Zoran Buntic for reporting this
issue.
- Fixed compile problems related to the recent changes in the Base64
class. Thanks to Mat Berchtold for reporting this issue.
- Since the code is now for VC 2005 or later only, the code now uses the
Base64 encoding support from the ATL atlenc.h header file. Thanks to Mat
Berchtold for reporting this optimization. This means that client projects
no longer need to include Base64.cpp/h in their projects.
V2.77 (31 May 2008)
- Code now compiles cleanly using Code Analysis (/analyze)
- Removed the use of the function QuotedPrintableEncode and replaced with
ATL::QPEncode
- Removed the use of the function QEncode and replaced with ATL::QEncode
- Reworked ReadResponse to use CStringA in line with the implementation in
the POP3 class of the author.
V2.78 (20 July 2008)
- Fixed a bug in ReadResponse where the code is determining if it has
received the terminator. Thanks to Tony Cool for reporting this bug.
V2.79 (27 July 2008)
- Updated code to compile correctly using _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
define
- CPJNSMTPMessage::GetHeader now correctly ensures all long headers are
properly folded. In addition this function has been reworked to create the
header internally as an ASCII string rather than as a TCHAR style CString.
V2.80 (16 August 2008)
- Updated the AUTH_AUTO login support to fall back to no authentication if
no authentication scheme is supported by the SMTP server. Thanks to Mat
Berchtold for this update.