Indy SMTP Malformed address started appearing

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Indy SMTP Malformed address started appearing

Postby pigman » Wed Feb 10, 2016 5:29 pm

Indy 10.6

For two years, my Indy SMTP emailer code worked great. But now, suddenly, it has malformed addresses. My domain host says the SMTP server hasn't been modified (I don't believe them) but as of yesterday, adding more than one email address leads to the error:

Email error: <pigman@pigman.com,piggirl@pigman.com>: malformed address:
,piggirl@pigman.com> may not follow <pigman@pigman.com

Debugging leads me to find that calling these two lines with more than one email address, leads to the error above.
TIdEMailAddressItem *NewItem=IdMessage->Recipients->Add();
NewItem->Address=ptr1; // ptr1 points to next name in csv list. (i.e. pigman@pigman.com etc)

If I was to take a guess, I'd say that my host's SMTP server expects the recipient emails to be, or not be, wrapped with <> brackets when multiple recipients are specified.

Here are other relevant parts of the function:

smtpMail->IOHandler = IdSSLIOHandlerSocketOpenSSL1;
IdUserPassProvider1->Username = (String)SMTP_Username;
IdUserPassProvider1->Password = (String)SMTP_Password;
sprintf(temp,"%s:%d",SMTP_Server,SMTP_Port);
IdSSLIOHandlerSocketOpenSSL1->Destination = temp; //"smtp.foobar.com:587";
IdSSLIOHandlerSocketOpenSSL1->Host = (String)SMTP_Server; //"smtp.foobar.com";
IdSSLIOHandlerSocketOpenSSL1->MaxLineAction = maException;
IdSSLIOHandlerSocketOpenSSL1->Port = SMTP_Port;
IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvTLSv1;
IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Mode = sslmUnassigned;
IdSSLIOHandlerSocketOpenSSL1->SSLOptions->VerifyDepth = 0;
if(SMTP_Port == 587)
smtpMail->UseTLS = utUseExplicitTLS;
else
smtpMail->UseTLS = utUseImplicitTLS;

smtpMail->Connect();
smtpMail->Send(IdMessage);
smtpMail->Disconnect();

I would appreciate any suggestions. My domain host says when they email multiple recipients, it works (of course) and when I use Thunderbird, it works, but something about the Indy components does things differently?

Thank you for your help.
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby rlebeau » Thu Feb 11, 2016 12:21 am

pigman wrote:Debugging leads me to find that calling these two lines with more than one email address, leads to the error above.
TIdEMailAddressItem *NewItem=IdMessage->Recipients->Add();
NewItem->Address=ptr1; // ptr1 points to next name in csv list. (i.e. pigman@pigman.com etc)


Did you verify that you are actually parsing your CSV data correctly, that ptr1 really does contain 1 and only 1 email address and nothing else? You are *supposed* to call Recipients->Add() for each individual recipient.

If your CSV recipient data contains multiple email addresses separated by commas, you could alternatively just assign the whole list to the Recipients->EMailAddresses property and let Indy parse them for you.

pigman wrote:If I was to take a guess, I'd say that my host's SMTP server expects the recipient emails to be, or not be, wrapped with <> brackets when multiple recipients are specified.


Yes, it expects it (per the SMTP protocol), and Indy handles that for you when it is formatting the "RCPT TO" command for each recipient.

pigman wrote: IdSSLIOHandlerSocketOpenSSL1->Destination = temp; //"smtp.foobar.com:587";
IdSSLIOHandlerSocketOpenSSL1->Host = (String)SMTP_Server; //"smtp.foobar.com";
IdSSLIOHandlerSocketOpenSSL1->Port = SMTP_Port;


DO NOT set those properties manually. Connect() handles that for you.

pigman wrote: if(SMTP_Port == 587)
smtpMail->UseTLS = utUseExplicitTLS;
else
smtpMail->UseTLS = utUseImplicitTLS;


And if the user chooses port 25? utUseImplicitTLS does not work on port 25, it needs port 465 instead. And also, not all SMTP servers use standard ports. This is typically why email clients provide a configuration option to specify whether SSL/TLS is to be used, separate from the port number configuration.

pigman wrote: smtpMail->Connect();
smtpMail->Send(IdMessage);
smtpMail->Disconnect();


Send() should be inside a try/catch block. You need to call Disconnect() regardless of whether Send() succeeds or fails (unless you are catching an exception in higher code that destroys the TIdSMTP object, in which case the destructor will call Disconnect()).

pigman wrote:I would appreciate any suggestions. My domain host says when they email multiple recipients, it works (of course) and when I use Thunderbird, it works, but something about the Indy components does things differently?


Did you try looking at the actual SMTP commands that TIdSMTP is sending? You can attach one of Indy's TIdLog... components, such as TIdLogFile or TIdLogEvent, to the TIdSMTP::Intercept property.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Indy SMTP Malformed address started appearing

Postby pigman » Fri Feb 12, 2016 12:29 pm

Thank you for replying, Remy. As I mentioned, this code (below) worked for two years
and then suddenly had error messages but only if multiple recipients were added.
I cobbled the code together from many Internets searches and it's not great but
has worked fine until now. Thank you again!



> Did you verify that you are actually parsing your CSV data correctly ...
Yes, using debugger and internal event logs.


>You are *supposed* to call Recipients->Add() for each individual recipient.

Yes, see real code below.

>If your CSV recipient data contains multiple email addresses separated by commas,
>you could alternatively just assign the whole list to the Recipients->EMailAddresses
>property and let Indy parse them for you.

I wasn't yet able to get this to compile because I didn't understand where to insert it.


>And if the user chooses port 25? utUseImplicitTLS does not work on port 25,
> ...
>Send() should be inside a try/catch block. You need to call Disconnect()
>regardless of whether Send()

All understood. I left it out of previous pasted code but included it all now.

>You can attach one of Indy's TIdLog... components, such as TIdLogFile...
Certainly.

Stat Connected.

Recv 2/12/2016 1:14:13 PM: 334 <EOL>
Sent 2/12/2016 1:14:13 PM: EOL>
Recv 2/12/2016 1:14:13 PM: 235 Authentication succeeded<EOL>
Sent 2/12/2016 1:14:13 PM: MAIL FROM:<johnb@xxxxx.com,jb2003@yyy.com><EOL>
Recv 2/12/2016 1:14:13 PM: 501 <johnb@xxxxx.com,jb2003@yyy.com>: malformed address: ,jb2003@yyy.com> may not follow <johnb@xxxxx.com<EOL>
Sent 2/12/2016 1:14:20 PM: QUIT<EOL>
Recv 2/12/2016 1:14:20 PM: 221 bounty.dns-nac-zone.com closing connection<EOL>
Stat Disconnected.





Code: Select all
//---------------------------------------------------------------------------
int __fastcall TfrmVclMisc::SendSMTP(char *ToAddress, char *CCAddress, char *Subject, char *Text1, char *ExtraText, char *Filename, int Attachments)
{
//IdLogFile1->Active = true;
    char *ptr1, *ptr2, str[512], temp[512];
    char SMTP_Server[255], SMTP_Password[255], SMTP_Username[255];
    int SMTP_Authenticate, SMTP_Port;

    int addrIndex;
    Screen->Cursor = crHourGlass;


    FILE *fp;
    if(NULL != (fp=fopen("header.htm","w"))){ // in order to attach reports (below), we seem to need a html stub (Indy)
        fprintf(fp,"<html><body>\n");
        fprintf(fp,"<h2> </h2>\n"); //was  Report attached
        fprintf(fp,"<p>%s</p>\n",Text1);
        fprintf(fp,"</body></html>\n");
        fclose(fp);
    }

    formMain->DisplayStatus(0, "Sending Email...");
    if(Attachments == 0){
        lstboxAttachments->Clear();
        if(strlen(Filename) > 0)
            lstboxAttachments->Items->Add(Filename);
    }

    SMTP_Authenticate = frmMySQL->ReadIniInt("SMTPAuthenticate",IACN, -1);
    SMTP_Port = atoi(frmMySQL->ReadIniAnsiString("SMTPPort",IACN, -1).c_str()); // used a lot so read into variable.
    strcpy(SMTP_Server,frmMySQL->ReadIniAnsiString("SMTPServer",IACN, -1).c_str());
    strcpy(SMTP_Username,frmMySQL->ReadIniAnsiString("SMTPServerUserName",IACN, -1).c_str());
    strcpy(SMTP_Password,frmMySQL->ReadIniAnsiString("SMTPServerUserPwd",IACN, -1).c_str());
    RemediateSQLRead(SMTP_Password);
    Mangle(SMTP_Password);

    if(XM.ViewMessages == 1){  // use native servers so override above settings.
        SMTP_Authenticate = 1;
        SMTP_Port = 465;
        strcpy(SMTP_Server,"mail.xxxxx.com");
        strcpy(SMTP_Username,"xxxxxxx@xxxxx.com");
        strcpy(SMTP_Password,"xxxxxxx");
    }

    smtpMail->Host=(String)SMTP_Server;
    smtpMail->Username=(String)SMTP_Username;
    smtpMail->Password=(String)SMTP_Password;
    smtpMail->Port=SMTP_Port;

    TIdMessageBuilderHtml *IdMessageB = new TIdMessageBuilderHtml (  );
    TIdMessage *IdMessage = new TIdMessage ( this );
    IdMessage->Clear();
    IdMessage->From->Address=frmMySQL->ReadIniAnsiString("SMTPFromAddress",IACN, -1);
    IdMessage->From->Name=frmMySQL->ReadIniAnsiString("SMTPFromName",IACN, -1);
    IdMessage->Subject=Subject;
    IdMessage->UseNowForDate=true;
    IdMessage->CharSet="big5";  // or try "utf-8" for unicode text in body.
    IdMessage->UseNowForDate=true;
    IdMessage->Body->Text = "body text";

    IdMessageB->PlainText->Text = "";
    if(strlen(Text1) > 0 || strlen(ExtraText) > 0){
        ptr1=Text1;
        while(NULL != (ptr2 = strchr(ptr1,'\r'))){ // break up Text1 if it has /n chars
            *ptr2=NULL;
            LeftJustifyString(ptr1);
            IdMessageB->PlainText->Add(ptr1);
            ptr1=ptr2+1;
        }
        LeftJustifyString(ptr1);
        IdMessageB->PlainText->Add(ptr1);
        IdMessageB->PlainText->Add("");
        IdMessageB->PlainText->Add(ExtraText);
    }

    if(lstboxAttachments->Items->Count > 0){
        for (int i=0; i < lstboxAttachments->Items->Count; i++){
            strcpy(str,lstboxAttachments->Items->Strings[i].c_str());
            if(strstr(str,".htm")){
                if(frmMySQL->ReadIniInt("ReportEmailBody",IACN, -1) == 1)
                    IdMessageB->Html->LoadFromFile("report.htm");   // put report inline in email
                else
                    IdMessageB->Html->LoadFromFile("header.htm");   // just send header that says "report is attached"

                if(frmMySQL->ReadIniInt("ReportEmailAttach",IACN, -1) == 1)
                    IdMessageB->HtmlFiles->Add(str);                // also attach report so users can save attachment.
            }else{
                IdMessageB->Html->LoadFromFile("header.htm");   // put report inline in email
                IdMessageB->Attachments->Add(str);
            }
        }
    }


    strcpy(temp,ToAddress); // First, send TO addresses.
    if(strlen(temp) > 0){
        ptr1=temp;
        while(NULL != (ptr2 = strchr(ptr1,','))){ // Loop thru CSV recipients
            *ptr2=NULL;
            LeftJustifyString(ptr1);
            if(strchr(ptr1,'@')){ // only allow "valid" email addresses.
                TIdEMailAddressItem *NewItem=IdMessage->Recipients->Add();
                NewItem->Address=ptr1;
                if(GL.TraceEmail == 1)
                    VLogEvent("Appending %s as 'To' recipient.",ptr1);
            }
            ptr1=ptr2+1;
        }
        LeftJustifyString(ptr1);
        TIdEMailAddressItem *NewItem=IdMessage->Recipients->Add();
        NewItem->Address=ptr1;
        if(GL.TraceEmail == 1)
            VLogEvent("Appending %s as 'To' recipient.",ptr1);
    }

    strcpy(temp,CCAddress); // Now, for the CC addresses...
    if(strlen(temp) > 0){
        ptr1=temp;
        while(NULL != (ptr2 = strchr(ptr1,','))){ // Loop thru CSV recipients, like above loop
            *ptr2=NULL;
            LeftJustifyString(ptr1);
            if(strchr(ptr1,'@')){ // only allow "valid" email addresses.
                TIdEMailAddressItem *NewItem=IdMessage->CCList->Add();
                NewItem->Address=ptr1;
                if(GL.TraceEmail == 1)
                    VLogEvent("Appending %s as 'CC' recipient.",ptr1);
            }
            ptr1=ptr2+1;
        }
        LeftJustifyString(ptr1);
        TIdEMailAddressItem *NewItem=IdMessage->CCList->Add();
        if(GL.TraceEmail == 1)
            VLogEvent("Appending %s as 'CC' recipient.",ptr1);
        NewItem->Address=ptr1;
    }

    if(SMTP_Authenticate == 0){ // No Password Authentication
        if(SMTP_Port == 25){
            smtpMail->AuthType = satDefault;
            smtpMail->UseTLS = utUseExplicitTLS;
            smtpMail->IOHandler = IdSSLIOHandlerSocketOpenSSL1;
            IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvTLSv1;
        }else{  // bare frame to ensure following else if from interrupting logic.
        }
    }else if(SMTP_Port == 465 || SMTP_Port == 587){ // using gmail?   "smtp.gmail.com:587"
        smtpMail->IOHandler = IdSSLIOHandlerSocketOpenSSL1;
        IdUserPassProvider1->Username = String(SMTP_Username);
        IdUserPassProvider1->Password = (String)SMTP_Password;
        sprintf(temp,"%s:%d",SMTP_Server,SMTP_Port);
        IdSSLIOHandlerSocketOpenSSL1->MaxLineAction = maException;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvTLSv1;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Mode = sslmUnassigned;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->VerifyDepth = 0;
        if(SMTP_Port == 587)
            smtpMail->UseTLS = utUseExplicitTLS;
        else
            smtpMail->UseTLS = utUseImplicitTLS;
        if(GL.TraceEmail == 1)
            VLogEvent("Outbound email for %s is using TLS crypto protocols.", IdUserPassProvider1->Username.c_str());
    }else{ // password authentication, but on nonstandard port
        smtpMail->AuthType = satSASL;
        IdSASLCRAMMD51->UserPassProvider = IdUserPassProvider1;
        IdUserPassProvider1->Username = (String)SMTP_Username;
        IdUserPassProvider1->Password = (String)SMTP_Password;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvSSLv2; //sslvTLSv1;
    }
    int retVal = 0;
    IdMessageB->FillMessage(IdMessage);
    if(!smtpMail->Connected())
    try{
        smtpMail->Connect();
        smtpMail->Send(IdMessage);
        smtpMail->Disconnect();
    }catch (Exception &exception){
        sprintf(temp,"Email Error:%s",exception.Message.c_str());
        VLogEvent(temp);
        frmVclMisc->PWMessageBox(temp,10);
        retVal = -1;
        smtpMail->Disconnect();
    }

    lstboxAttachments->Clear();
    delete IdMessage;
    delete IdMessageB;
    Screen->Cursor = crDefault;
    return retVal;
}
//---------------------------------------------------------------------------
Last edited by pigman on Fri Feb 12, 2016 6:41 pm, edited 1 time in total.
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby rlebeau » Fri Feb 12, 2016 6:10 pm

pigman wrote: 2/12/2016 1:14:13 PM: AUTH PLAIN<EOL>
Recv 2/12/2016 1:14:13 PM: 334 <EOL>
Sent 2/12/2016 1:14:13 PM: **********<EOL>
Recv 2/12/2016 1:14:13 PM: 235 Authentication succeeded<EOL>


This is a public forum, please mask out any posted credential data. You just exposed real credentials for a real server (AUTH PLAIN is not secure and easily decoded by hand).

pigman wrote:Sent 2/12/2016 1:14:13 PM: MAIL FROM:<johnb@xxxxx.com,jb2003@yyy.com><EOL>


The TIdMessage.Recipients property has nothing to do with the MAIL FROM command, only the RCPT TO command. Only the TIdMessage.From and TIdMessage.Sender properties are used for the MAIL FROM command. Since you said your debugging lead you to the TIdMessage.Recipients property as the culprit, your debugging led you down the wrong path.

You are not assigning any values to the TIdMessage.Sender property, so only the TIdMessage.From property is used to populate the MAIL FROM command. The TIdEmailAddress.Address property has no getter/setter methods, so the MAIL FROM command ends up being populated with the exact text that is assigned to From.Address. Given the code you have shown, that means the ONLY way TIdSMTP can generate that malformed MAIL FROM command is if frmMySQL->ReadIniAnsiString("SMTPFromAddress") is returning a comma-separated list containing multiple email addresses.

That being said, most of your custom parsing code is over-complicated, risky, and unnecessary. Your code can be greatly simplified to the following:

Code: Select all
//---------------------------------------------------------------------------
int __fastcall TfrmVclMisc::SendSMTP(char *ToAddress, char *CCAddress, char *Subject, char *Text1, char *ExtraText, char *Filename, int Attachments)
{
    //IdLogFile1->Active = true;
    AnsiString SMTP_Server, SMTP_Password, SMTP_Username;
    int SMTP_Authenticate, SMTP_Port;

    Screen->Cursor = crHourGlass;

    formMain->DisplayStatus(0, "Sending Email...");
    if (Attachments == 0)
    {
        lstboxAttachments->Clear();
        if ((Filename) && (*Filename != 0))
            lstboxAttachments->Items->Add(Filename);
    }

    SMTP_Authenticate = frmMySQL->ReadIniInt("SMTPAuthenticate",IACN, -1);
    SMTP_Port = frmMySQL->ReadIniInt("SMTPPort",IACN, -1); // used a lot so read into variable.
    SMTP_Server = frmMySQL->ReadIniAnsiString("SMTPServer",IACN, -1);
    SMTP_Username = frmMySQL->ReadIniAnsiString("SMTPServerUserName",IACN, -1);
    SMTP_Password = frmMySQL->ReadIniAnsiString("SMTPServerUserPwd",IACN, -1);

    RemediateSQLRead(SMTP_Password.c_str());
    Mangle(SMTP_Password.c_str());

    if (XM.ViewMessages == 1) // use native servers so override above settings.
    {
        SMTP_Authenticate = 1;
        SMTP_Port = 465;
        SMTP_Server = "mail.xxxxx.com";
        SMTP_Username = "xxxxxxx@xxxxx.com";
        SMTP_Password = "xxxxxxx";
    }

    TIdMessageBuilderHtml *IdMessageB = new TIdMessageBuilderHtml (  );

    IdMessageB->PlainTextCharSet = "utf-8";
    IdMessageB->PlainText->Text = Text1;
    if ((ExtraText) && (*ExtraText != 0))
    {
        IdMessageB->PlainText->Add("");
        IdMessageB->PlainText->Add(ExtraText);
    }

    if (frmMySQL->ReadIniInt("ReportEmailBody",IACN, -1) == 1)
        IdMessageB->Html->LoadFromFile("report.htm");   // put report inline in email
    else
    {
        // just send header that says "report is attached"
        IdMessageB->Html->Add("<html><body>");
        IdMessageB->Html->Add("<h2> </h2>"); //was  Report attached
        IdMessageB->Html->Add("<p>" + String(Text1) + "</p>");
        IdMessageB->Html->Add("</body></html>");
    }

    for (int i = 0; i < lstboxAttachments->Items->Count; ++i)
    {
        str = lstboxAttachments->Items->Strings[i];
        if (str.Pos(".htm") != 0)
        {
            if (frmMySQL->ReadIniInt("ReportEmailAttach",IACN, -1) == 1)
                IdMessageB->Attachments->Add(str);                // also attach report so users can save attachment.
        }
        else
        {
            IdMessageB->Attachments->Add(str);
        }
    }

    TIdMessage *IdMessage = IdMessageB->NewMessage( );
    IdMessage->From->Address = frmMySQL->ReadIniAnsiString("SMTPFromAddress",IACN, -1);
    IdMessage->From->Name = frmMySQL->ReadIniAnsiString("SMTPFromName",IACN, -1);
    IdMessage->Subject = Subject;
    IdMessage->UseNowForDate = true;

    IdMessage->Recipients->EMailAddresses = ToAddress; // First, send TO addresses.
    if (GL.TraceEmail == 1)
    {
        for (int i = 0; i < IdMessage->Recipients->Count; ++i) {
            VLogEvent("Appended %s as 'To' recipient.", AnsiString(IdMessage->Recipients->Items[i]->Address).c_str());
        }
    }

    IdMessage->CCList->EMailAddresses = CCAddress; // Now, for the CC addresses...
    if (GL.TraceEmail == 1)
    {
        for (int i = 0; i < IdMessage->CCList->Count; ++i) {
            VLogEvent("Appended %s as 'CC' recipient.", AnsiString(IdMessage->CCList->Items[i]->Address).c_str());
        }
    }

    smtpMail->Host = SMTP_Server;
    smtpMail->Port = SMTP_Port;

    if (SMTP_Authenticate == 0) // No Password Authentication
    {
        smtpMail->AuthType = satNone;
    }
    else
    {
        // make sure SASL components are assigned to smtpMain->SASLMechanisms
        // and IdUserPassProvider1 is assigned to them...

        smtpMain->AuthType = satSASL;
        IdUserPassProvider1->Username = SMTP_Username;
        IdUserPassProvider1->Password = SMTP_Password;
    }

    if ((SMTP_Port == 25) || (SMTP_Port == 587))
    {
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvTLSv1;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Mode = sslmClient;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->VerifyDepth = 0;

        smtpMail->IOHandler = IdSSLIOHandlerSocketOpenSSL1;
        smtpMail->UseTLS = utUseExplicitTLS;

        if (GL.TraceEmail == 1)
            VLogEvent("Outbound email may use TLS crypto protocols.");
    }
    else if (SMTP_Port == 465)
    {
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Method = sslvTLSv1;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->Mode = sslmClient;
        IdSSLIOHandlerSocketOpenSSL1->SSLOptions->VerifyDepth = 0;

        smtpMail->IOHandler = IdSSLIOHandlerSocketOpenSSL1;
        smtpMail->UseTLS = utUseImplicitTLS;

        if (GL.TraceEmail == 1)
            VLogEvent("Outbound email is using TLS crypto protocols.");
    }
    else
    {
        // nonstandard port
        smtpMail->IOHandler = NULL;
 
        if (GL.TraceEmail == 1)
            VLogEvent("Outbound email is not using TLS crypto protocols.");
     }

    int retVal = 0;
    try
    {
        smtpMail->Connect();
        try {
            smtpMail->Send(IdMessage);
        }
        __finally {
            smtpMail->Disconnect();
       }
    }
    catch (const Exception &exception)
    {
        AnsiString temp = "Email Error:" + exception.Message;
        VLogEvent(temp.c_str());
        frmVclMisc->PWMessageBox(temp.c_str(), 10);
        retVal = -1;
    }

    lstboxAttachments->Clear();
    delete IdMessage;
    delete IdMessageB;
    Screen->Cursor = crDefault;
    return retVal;
}
//---------------------------------------------------------------------------
Last edited by rlebeau on Sat Feb 13, 2016 1:43 am, edited 1 time in total.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Indy SMTP Malformed address started appearing

Postby pigman » Fri Feb 12, 2016 7:16 pm

Hi Remy,
Thanks very much spending the effort to clean up my mistakes. I'm humbled. When I run the new code, unfortunately, the same error results. I've included a trace below. I have a Comcast account which does not generate an error.

BTW, here's my domain host's reply regarding my ticket with them:
I have checked and successfully send emails to multiple email account via command line and webmail client without any issue, this seems to be issue with the indent marks in the email address at the email client. Please let us know the email client which you are using so that we can check the issue further.

Indy log:

Stat Connected.
Recv 2/12/2016 7:50:03 PM: 220-bounty.dns-nac-zone.com ESMTP Exim 4.86 #2 Fri, 12 Feb 2016 17:05:44 -0800 <EOL>220-We do not authorize the use of this system to transport unsolicited, <EOL>220 and/or bulk e-mail.<EOL>
Sent 2/12/2016 7:50:03 PM: EHLO m3800b<EOL>
Recv 2/12/2016 7:50:03 PM: 250-bounty.dns-nac-zone.com Hello c-73-0-24-198.hsd1.fl.comcast.net [73.0.24.198]<EOL>250-SIZE 52428800<EOL>250-8BITMIME<EOL>250-PIPELINING<EOL>250-AUTH PLAIN LOGIN<EOL>250 HELP<EOL>
Sent 2/12/2016 7:50:03 PM: AUTH PLAIN<EOL>
Recv 2/12/2016 7:50:03 PM: 334 <EOL>
Sent 2/12/2016 7:50:03 PM: xxxxxxxxxxxxxxxxxxxxx=<EOL>
Recv 2/12/2016 7:50:04 PM: 235 Authentication succeeded<EOL>
Sent 2/12/2016 7:50:04 PM: MAIL FROM:<johnb@xxxxx.com,jb2003@xxx.com><EOL>
Recv 2/12/2016 7:50:04 PM: 501 <johnb@xxxxx.com,jb2003@xxx.com>: malformed address: ,jb2003@xxx.com> may not follow <johnb@xxxxx.com<EOL>
Sent 2/12/2016 7:50:10 PM: QUIT<EOL>
Recv 2/12/2016 7:50:10 PM: 221 bounty.dns-nac-zone.com closing connection<EOL>
Stat Disconnected.

Many thanks!
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby rlebeau » Sat Feb 13, 2016 1:51 am

pigman wrote:When I run the new code, unfortunately, the same error results.


As I said, given the code you have shown, there is only one possibility. The following line is at fault:

Code: Select all
IdMessage->From->Address = frmMySQL->ReadIniAnsiString("SMTPFromAddress",IACN, -1);


The "SMTPFromAddress" value has to be returning the malformed value. There is no other possibility. That is where you need to focus your debugging efforts. Your Ini source data is likely corrupted.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Indy SMTP Malformed address started appearing

Postby pigman » Mon Feb 15, 2016 11:38 pm

Remy, you were, of course, correct. I was going down the road that the malformed address error emanated from the "To" address instead of the "From" address which obviously can't have multiple comma separated addresses. Oddly enough, Comcast's servers never chucked a wobbly about it. Anyway, thank you for all of your patience and unselfish help over the years.
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby pigman » Wed Feb 24, 2016 3:45 pm

For some reason, this part of the code adds Text1 but ExtraText doesn't arrive in the email. The CPPB debugger verifies the if condition is met and that the fields contain the text data.

Code: Select all
 
   TIdMessageBuilderHtml *IdMessageB = new TIdMessageBuilderHtml (  );

    IdMessageB->PlainTextCharSet = "utf-8";
    IdMessageB->PlainText->Text = Text1;
    if ((ExtraText) && (*ExtraText != 0))
    {
        IdMessageB->PlainText->Add("");
        IdMessageB->PlainText->Add(ExtraText);
    }
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby pigman » Wed Feb 24, 2016 3:59 pm

Viewing the email source indicates the function you kindly rewrote might be mixing text/plain with text/html.


Content-Type: multipart/alternative; boundary="xxxxxxxxxxxxxxxx0"
MIME-Version: 1.0
Date: Wed, 24 Feb 2016 13:55:10 -0500

This is a multi-part message in MIME format

--xxxxxxxxxxx0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Text1

Text2

--xxxxxxxxxxxxxxxxxxxxx0
Content-Type: text/html
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

<html><body>
<h2> </h2>
<p>Text1</p>
</body></html>

--xxxxxxxxxxxxxxxxxxxxxx0--
pigman
 
Posts: 6
Joined: Wed Feb 10, 2016 9:03 am

Re: Indy SMTP Malformed address started appearing

Postby rlebeau » Wed Feb 24, 2016 4:06 pm

pigman wrote:Viewing the email source indicates the function you kindly rewrote might be mixing text/plain with text/html.


It is supposed to. The whole purpose of TIdMessageBuilderHtml is to setup the email in such a way that an HTML-enabled viewer will display the HTML, and a non-HTML viewer will display the plain text instead. That is what the "multipart/alternative" media type is all about - alternative representations. It is your responsibility to populate the PlainText and Html properties with equivalent content for each representation. For example, the code is adding the ExtraText only to the PlainText property, but not to the Html property, so you should probably add that:

Code: Select all
IdMessageB->Html->Add("<html><body>");
IdMessageB->Html->Add("<h2> </h2>"); //was  Report attached
IdMessageB->Html->Add("<p>" + String(Text1) + "</p>");
if ((ExtraText) && (*ExtraText != 0))
{
    IdMessageB->Html->Add("<p>" + String(ExtraText) + "</p>"); // <-- here
}
IdMessageB->Html->Add("</body></html>");
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA


Return to Technical

Who is online

Users browsing this forum: Bing [Bot] and 12 guests

cron