2014-10-01 3 views
0

Мой вопрос: почему Gmail дает мне эту ошибку:ошибка Delphi XE2 Indy 10.5.92 GMail SMTP «Имя пользователя и пароль не принимаются»

Имя пользователя и пароль не принимаются. Узнать больше на http://support.google.com/mail/bin/answer.py?answer=14257 lp8sm18275694wic.17 - gsmtp

Я пробовал все, весь набор параметров: SSL, TSL, SASL и еще ничего. Где-то я обнаружил, что google требует некоторого метода OAUTH2 SASL, который должен быть сделан в Indy.

Конечно, на Delphi 6 и Indy 9 с надлежащими eay dll на порту 465 с ssl отлично работает. У кого-нибудь есть идея, что с этим делать?

O Конечно, я установил 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

Используя версию последней Инди (10.6.1), можно успешно подключиться и аутентификации TIdSMTP к Gmail с использованием компонентов SASL от Indy с SSL (UseTLS=utUseImplicitTLS на порту 465) и TLS (UseTLS=utUseExplicitTLS на порту 587), используя аналогичный код, который вы указали. Несмотря на распространенное мнение, 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. Большинство ваших звонков на Free() являются избыточными, поскольку вы назначили TIdSMTP в качестве Владельца всего, кроме TIdMessage.Вам не нужно освобождать компоненты SASL вручную, вы можете позволить TIdSMTP сделать это за вас.

  5. Вы звоните IdSMTP1.Disconnect() дважды. Тебе это не нужно.

0

Вот решение:

После всех попыток это, кажется, у меня была неправильная версия двух библиотек DLL libeay.dll и ssleay.dll.

Смежные вопросы