|
Could the problem be that you compiled OpenSSL in VS2013 and are trying to compile the library in VS2015?
|
|
|
|
|
The "application/x-msdownload" mime type should only be used for .exe and .dll attachments!
I replaced the following lines:-
strcat(SendBuf, "Content-Type: application/x-msdownload; name=\"");
strcat(SendBuf, EncodedFileName.c_str());
strcat(SendBuf, "\"\r\n");
with the following:
const char *LastFourCharsOfFileName = FileName.c_str() + strlen(FileName.c_str()) - 4;
if(strlen(FileName.c_str()) < 4) {
// Very short filename which can't have a three letter extension, so do nothing
} else if(!strcmp(LastFourCharsOfFileName, ".pdf")) {
strcat(SendBuf, "Content-Type: application/pdf\r\n"); // See http://pdf.mime-application.com/ and http://stackoverflow.com/questions/312230/proper-mime-media-type-for-pdf-files
} else if(!strcmp(LastFourCharsOfFileName, ".exe") || !strcmp(LastFourCharsOfFileName, ".dll")) {
strcat(SendBuf, "Content-Type: application/x-msdownload; name=\""); // See http://x-msdownload.mime-application.com/
strcat(SendBuf, EncodedFileName.c_str());
strcat(SendBuf, "\"\r\n");
}
That makes it work correctly for PDF, EXE and DLL attachments. Don't know about other ones?
Eric
Eric
|
|
|
|
|
Eric,
Per RFC 1341:
An "application" Content-Type value, which can be used to transmit application data or binary data, and hence, among other uses, to implement an electronic mail file transfer service.
As I understand it, it is intended to signify any type of binary data. Do you have a source that sites a different set of requirements?
|
|
|
|
|
After making the date change suggested by Eric Schwerzel and adding a function to allow for setting the m_bHTML boolean, it's working well.
Thanks for sharing!
John
|
|
|
|
|
error:Server returned error after sending EHLO
why?
|
|
|
|
|
Most likely its the combination of port and security settings you are using.
|
|
|
|
|
Great code!
It's not clear for me why if I put a message like:
mail.AddMsgLine("How are you today?123456789/-+èé+*çò°à@#§ù-_<>ì^|()[]{}");
I recieve in the email:
How are you today?123456789/-+鴇+*趛啤@#杜-_<>餧|()[]{}
There is some convertion to do to get the correct string without strange symbols??
Thanks
|
|
|
|
|
I'm not sure. Please post back if you find a solution.
Thanks,
David
|
|
|
|
|
There is a bug with how the date is formatted which I've been told is getting the emails sent being marked as Spam. If the email is sent at one second and one minute past one, the date generated is:
Date: 1 Jan 2016 1:1:1
when it should be
Date: 01 Jan 2016 01:01:01
The date, hours, minutes and seconds need to be two digits each (see http://email.about.com/od/Email-Standards-Tips/qt/How-To-Understand-Date-And-Time-In-Email-Headers.htm), so you need to replace:
snprintf(header, BUFFER_SIZE, "Date: %d %s %d %d:%d:%d\r\n", timeinfo->tm_mday,
with:
snprintf(header, BUFFER_SIZE, "Date: %02d %s %04d %02d:%02d:%02d\r\n", timeinfo->tm_mday,
If you also want the day of the week and correct timezone to be displayed (recommended to make the spam filters happier) then you can have the following for the first part of FormatHeader (the #### are where all the changes are):-
void CSmtp::FormatHeader(char* header)
{
char month[][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
char dayofweek[][4] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; // ####
TIME_ZONE_INFORMATION TimeZoneInformation; // ####
int success, timezonebias, houroffset, minuteoffset; // ####
size_t i;
std::string to;
std::string cc;
std::string bcc;
time_t rawtime;
struct tm* timeinfo;
// date/time check
if(time(&rawtime) > 0)
timeinfo = localtime(&rawtime);
else
throw ECSmtp(ECSmtp::TIME_ERROR);
// check for at least one recipient
if(Recipients.size())
{
for (i=0;i<Recipients.size();i++)
{
if(i > 0)
to.append(",");
to += Recipients[i].Name;
to.append("<");
to += Recipients[i].Mail;
to.append(">");
}
}
else
throw ECSmtp(ECSmtp::UNDEF_RECIPIENTS);
if(CCRecipients.size())
{
for (i=0;i<CCRecipients.size();i++)
{
if(i > 0)
cc. append(",");
cc += CCRecipients[i].Name;
cc.append("<");
cc += CCRecipients[i].Mail;
cc.append(">");
}
}
// Determine the Time Zone string. See http://email.about.com/od/Email-Standards-Tips/qt/How-To-Understand-Date-And-Time-In-Email-Headers.htm ####
success = GetTimeZoneInformation(&TimeZoneInformation); // This is a Windows function call - don't know how to make this portable?
timezonebias = TimeZoneInformation.Bias; // Normal timezone
if(timeinfo->tm_isdst) timezonebias += TimeZoneInformation.DaylightBias; // Timezone adjusted for daylight saving
timezonebias = -timezonebias; // In the email headers it is the negative of the Windows value
houroffset = timezonebias / 60; // Truncate towards zero
minuteoffset = timezonebias % 60; // Modulus (remainder of minutes)
if(minuteoffset < 0) minuteoffset = -minuteoffset; // Only use the negative sign once (don't allow negative minutes)
// Date: <SP> <day of week>, <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <timezone> <CRLF> // ####
snprintf(header, BUFFER_SIZE, "Date: %s, %02d %s %04d %02d:%02d:%02d %+02d%02d\r\n", dayofweek[timeinfo->tm_wday], timeinfo->tm_mday, // ####
month[timeinfo->tm_mon], timeinfo->tm_year+1900, timeinfo->tm_hour,
timeinfo->tm_min, timeinfo->tm_sec, houroffset, minuteoffset); // ####
// From: <SP> <sender> <SP> "<" <sender-email> ">" <CRLF>
if(!m_sMailFrom.size()) throw ECSmtp(ECSmtp::UNDEF_MAIL_FROM);
... etc
Eric Schwerzel
|
|
|
|
|
Great addition Eric. One quick note - when I was testing, it seemed that the array of day names is shifted by 1. Since tm_wday is days since Sunday, 0 in the array should be Sun. After I flipped it around, everything worked great!
Thanks!
Cameron
|
|
|
|
|
Great comments. I'll incorporate that into the next release. What about doing something like this to get the timezone offset:
struct tm tmGMT,
tmLocal;
time_t now;
int offset;
time(&now);
if(gmtime_s(&tmGMT, &now)!=0) return 0;
if(localtime_s(&tmLocal, &now)!=0) return 0;
offset = (tmLocal.tm_year - tmGMT.tm_year)*365*24*60*60;
offset += (tmLocal.tm_yday - tmGMT.tm_yday)*24*60*60;
offset += (tmLocal.tm_hour - tmGMT.tm_hour)*60*60;
offset += (tmLocal.tm_min - tmGMT.tm_min)*60;
offset += (tmLocal.tm_sec - tmGMT.tm_sec);
|
|
|
|
|
the source of eml can see the sender computer ip.
Received: from xxxxxx (unknown [xxx.xxx.xxx.xxx])
can it change to:
Received: from xxxxxx (unknown [127.0.0.1])
or can it hide the sender computer ip?
|
|
|
|
|
This is probably be appended to the headers by your SMTP server.
|
|
|
|
|
Works with Gmail but no results with Outlook.it / .com
I have used this parameter
mail.SetSMTPServer("smtp-mail.outlook.com",25); mail.SetSecurityType(USE_TLS);
and I have created an app password like said in this post: C# SMTP Configuration for Outlook.Com SMTP Host[^]
Why doesn't work?
|
|
|
|
|
hotmail -> live
mail.SetSMTPServer("smtp.live.com",587);
mail.SetSecurityType(USE_TLS);
regards,procyon!
|
|
|
|
|
Generally servers don't support TLS on port 25. You probably just need to change it to:
mail.SetSMTPServer("smtp-mail.outlook.com",587);
mail.SetSecurityType(USE_TLS);
|
|
|
|
|
hi,
Ussing SMTP SSL, How I can detect the 534-5.7.14 gmail error (log in via your web browser)?
Thanks
|
|
|
|
|
You would have to add it to the Command_Entry command_list[] array. If you end up getting it to work as you want it to, please post back the updates.
|
|
|
|
|
David, The introduction on this post sounds exactly like what I have been going through wrt getting ssl email, except for on an Arduino platform. I have been looking into this for quite some time, and have not found any examples. Could you please shed some thoughts or guidance on how to port this example to work on an Arduino Due board? All i need is the email with tls/ssl support. I am not sure how to use the ethernet.h library in Arduino to work with this example.
really appreciate your help on this.
Abraham (acherian@buffalo.edu)
|
|
|
|
|
Sorry, I don't have any experience with Arduino programming. If you get it to work, please post back so others can benefit from it.
Thanks,
David
|
|
|
|
|
Your code was a great workaround for us because our old email module developped with CDOSYS could not be ported to x64.
Your code is fully functional in an x64 architecture.
I tested it successfully with gmail and Yahoo but I have some problems with a very simple email server running Microsoft Exchange with no security (It is is not setup to use SSL on the SMTP relay and uses anonymous authentication).
When I try this, with:
mail.SetSMTPServer("smtp.company.com",25);
mail.SetSecurityType(NO_SECURITY);
I get an error on the line "if(res && FD_ISSET(hSocket,&fdexcept))" of CSmtp::ConnectRemoteServer as somebody already reported in another thread.
Am I using CSmtp incorrectly or is there something special to setup on the server?
|
|
|
|
|
Which parameter you use for Yahoo? Mine doesn't work...
I used
mail.SetSMTPServer("smtp.mail.yahoo.com",465);
mail.SetSecurityType(USE_TLS);
|
|
|
|
|
You probably need mail.SetSecurityType(USE_SSL);
|
|
|
|
|
Thanks for the feedback. If you find a solution, please post back so I can add it to the distribution.
|
|
|
|
|
Hello there,
excellent code, I use him as an inspiration in my e-mail program.
My program has a GUI for creating the e-mail. The path of the e-mail creation (e-mail header, alternatively and HTML text, file attachments, images in the HTML code) is different from the one of you.
The e-mails are also sent correctly, no matter how many e-mails I send, that program is working properly.
However, I use exactly your way to connect to the server and send e-mails via SSL.
When establishing a connection to the server via SSL, I get 2 memory leaks when I close my application. Every time 20 and 16 bytes in size. For disconnecting from the server I also use exactly your way.
I was able to narrow the error, it happens in the function InitOpenSSL () under
SSL_library_init ();
SSL_load_error_strings ();
m_ctx = SSL_CTX_new (SSLv23_client_method ());
If I comment out all function in my program, so that only connect to the server to function InitOpenSSL() and I finish my program. I get 2 memory leaks.
If now I command out the function InitOpenSSL () and my program exit, the 2 memory leaks are gone.
Do you have any idea which caused?
|
|
|
|
|