2014-10-01 44 views
0

我的問題是:爲什麼Gmail爲我的錯誤:德爾福XE2印92年5月10日的GMail SMTP錯誤「的用戶名和密碼不被接受」

用戶名和密碼不被接受。瞭解更多在 http://support.google.com/mail/bin/answer.py?answer=14257 lp8sm18275694wic.17 - gsmtp

我嘗試了一切,大量的選項:SSL,TSL,SASL和什麼都沒有。在某處我發現Google要求在Indy中完成一些OAUTH2 SASL方法。

當然,在Delphi 6和Indy 9上使用適當的eay dlls,可以在端口465上使用ssl。 任何人都有一些想法該怎麼做?

Ø當然,我安裝http://slproweb.com/products/Win32OpenSSL.html我有人問...

這裏是代碼:

procedure send(Recipientemail, AccountName, Pass, EmailSMTP,EmailPortNo :string); 
var 
    lTextPart: TIdText; 
    lImagePart: TIdAttachmentfile; 
    IdSMTP1: TIdSMTP; 
    IdMsg: TIdMessage; 
    SSLHandler:TIdSSLIOHandlerSocketOpenSSL; 
    IdUserPassProv1: TIdUserPassProvider; 

    IdSASLLogin1: TIdSASLLogin; 
    IdSASLCRAMMD5: TIdSASLCRAMMD5; 
    IdSASLCRAMSHA1: TIdSASLCRAMSHA1; 
    IdSASLPlain: TIdSASLPlain; 
    IdSASLLogin: TIdSASLLogin; 
    IdSASLSKey: TIdSASLSKey; 
    IdSASLOTP: TIdSASLOTP; 
    IdSASLAnonymous: TIdSASLAnonymous; 
    IdSASLExternal: TIdSASLExternal; 
begin 

    IdSMTP1:=TIdSMTP.Create(nil); 
    IdMsg:=TIdMessage.Create(nil); 
    IdSMTP1.Host:=EmailSMTP; 
    IdSMTP1.Port:=EmailPortNo; 
    //IdSMTP1.Username:=trim(AccountName);//tried with or without 
    //IdSMTP1.Password:=trim(Pass);//tried with or without 



    TIdSSLContext.Create.Free; 
    SSLHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP1); 
    SSLHandler.SSLOptions.Method := sslvSSLv3; 
    SSLHandler.SSLOptions.Mode := sslmClient; 
    IdSMTP1.IOHandler := SSLHandler; 

    if (IdSMTP1.port = 465) then 
     IdSMTP1.UseTLS := utUseImplicitTLS 
     else 
     IdSMTP1.UseTLS := utUseExplicitTLS; 

    IdSASLLogin1:=TIdSASLLogin.Create(IdSMTP1); 
    IdUserPassProv1:=TIdUserPassProvider.Create(IdSMTP1); 
    IdUserPassProv1.Password:=trim(EmailHasloKonta); 
    IdUserPassProv1.Username:=trim(EmailNazwaKonta); 

    IdSMTP1.AuthType:=satSASL; 

    IdSASLCRAMSHA1 := TIdSASLCRAMSHA1.Create(idSMTP1); 
    IdSASLCRAMSHA1.UserPassProvider := IdUserPassProv1; 
    IdSASLCRAMMD5 := TIdSASLCRAMMD5.Create(idSMTP1); 
    IdSASLCRAMMD5.UserPassProvider := IdUserPassProv1; 
    IdSASLSKey := TIdSASLSKey.Create(idSMTP1); 
    IdSASLSKey.UserPassProvider := IdUserPassProv1; 
    IdSASLOTP := TIdSASLOTP.Create(idSMTP1); 
    IdSASLOTP.UserPassProvider := IdUserPassProv1; 
    IdSASLAnonymous := TIdSASLAnonymous.Create(idSMTP1); 
    IdSASLExternal := TIdSASLExternal.Create(idSMTP1); 
    IdSASLLogin := TIdSASLLogin.Create(idSMTP1); 
    IdSASLLogin1.UserPassProvider:=IdUserPassProv1; 
    IdSASLPlain := TIdSASLPlain.Create(idSMTP1); 
    IdSASLPlain.UserPassProvider := IdUserPassProv1; 

    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMSHA1; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLCRAMMD5; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLSKey; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLOTP; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLAnonymous; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLExternal; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLLogin1; 
    IdSMTP1.SASLMechanisms.Add.SASL := IdSASLPlain; 

    IdMsg.CharSet:=CmbEncod.Text; 
    IdMsg.From.Address:=EmailAdresNadawcy; 
    IdMsg.From.Name:=ToISO_8859_2(true, EmailNadawca); 

    IdMsg.Recipients.Add.Address:=email; 
    if EmailDoWiad<>'' then IdMsg.BccList.Add.Address:=EmailDoWiad; 

    IdMsg.ContentType:='multipart/relative';//; charset='+CmbEncod.Text; 
    IdMsg.Subject:=ifthen(TytulEmaila='',translate('Potwierdzenie rezerwacji'),TytulEmaila); 
    IdMsg.Body.Clear; 
    IdMsg.Body.Text:=''; 

    lTextPart := TIdText.Create(IdMsg.MessageParts); 
    lTextPart.Body.text:='Some body text'; 
    lTextPart.ContentType := 'text/plain'; 

    try 
    IdSMTP1.Connect;  
    //IdSMTP1.Authenticate; //tried with or without 

    try 

     try 
     IdSMTP1.Send(IdMsg); 
     except 
     on e: exception do 
     MessageDlg('Sending error:'#13+ 
        e.message, 
        mtinformation,[mbok],0); 
     end; 
    finally 
     IdSMTP1.Disconnect; 
    end; 
    finally 
    IdSMTP1.Disconnect; 
    IdUserPassProv1.free; 
    IdSASLLogin1.free; 
    IdSASLCRAMMD5.free; 
    IdSASLCRAMSHA1.free; 
    IdSASLPlain.free; 
    IdSASLLogin.free; 
    IdSASLSKey.free; 
    IdSASLOTP.free; 
    IdSASLAnonymous.free; 
    IdSASLExternal.free; 
    lTextPart.Free; 
    lImagePart.Free; 
    SSLHandler.free; 
    IdSMTP1.Free; 
    IdMsg.Free; 
    SSLHandler.Free; 
    end; 
end; 

回答

4

使用最新版本的Indy(10.6.1),我可以成功連接和認證TIdSMTP到使用Indy的SASL組件的Gmail(使用端口號爲465的UseTLS=utUseImplicitTLS)和TLS(端口號爲587的UseTLS=utUseExplicitTLS)使用與您所顯示的類似的代碼。儘管流行的觀點,OAUTH2是而不是還需要。

事實上,你得到一個人類可讀的認證錯誤意味着SSL/TLS部分工作正常,所以這是一個嚴格的SASL問題。

如果您的Gmail帳戶使用兩步驗證,請確保您在您的Gmail帳戶設置中創建了應用程序密碼,但無法使用您的主Gmail密碼。閱讀Gmail的文檔瞭解更多信息:

Application-specific password required

Sign in using App Passwords

雖這麼說,唯一的變化,我建議您對您所顯示的代碼是:

  1. 設置UseTLS屬性可能會更改Port屬性值,所以您應該先設置UseTLS,然後再將Port設置爲所需的值算賬:

    if (EmailPortNo = 465) then 
        IdSMTP1.UseTLS := utUseImplicitTLS 
    else 
        IdSMTP1.UseTLS := utUseExplicitTLS; 
    IdSMTP1.Port := EmailPortNo; 
    
  2. 你不需要創建和銷燬TIdSSLContext對象,因此擺脫了這一點。手動創建TIdSSLContext的唯一原因是它可以調用IdSSLOpenSSL.LoadOpenSSLLibrary()函數,該函數是公開的,因此如果需要可以直接調用它(在這種情況下您並不需要這樣做)。

  3. multipart/relative不是有效的ContentType。你的意思是multipart/related?您的TIdMessage不包含多個部分,因此您不應使用multipart ContentType開頭。

  4. 由於您將TIdSMTP指定爲除TIdMessage之外的所有者,因此您撥打Free()的大部分電話都是多餘的。你不需要手動釋放SASL組件,你可以讓TIdSMTP爲你做。

  5. 您打電話給IdSMTP1.Disconnect()兩次。你不需要那個。

0

這裏是解決方案:

所有嘗試後,似乎我有兩個DLL的版本錯誤libeay.dll和ssleay.dll。