2
votes

I Can't Download/Retrieve Email from Gmail with Delphi + Indy!

For several weeks I can not read e mail from Gmail.

Before the Code below works fine.

Now, I always get this Error Message:

error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

during connecting to Gmail.

On Cryptosense Blog I read

As trailed back in September 2015, Google are turning off SSLv3 and RC4 support from their TLS servers.

Any solutions how to read Emails from Gmail now?

My Code is this:

  1. Start a new Delphi project

  2. You have to download the SSL dlls from this site:

http://indy.fulgan.com/SSL/indy_OpenSSL096m.zip

  1. Unzip the file and put libeay32.dll and ssleay32.dll in your projects path.

  2. Replace the code of Unit1.pas and Unit1.dfm with the code below

  3. Change the Username and Password properties on the POP3 component to match those of your GMAIL account.

  4. Run it

//StartOfCode

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdPOP3,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL;

type
  TForm1 = class(TForm)
    POP3: TIdPOP3;
    Button1: TButton;
    SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  IdMessage, IdText;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  lMsg: TIdMessage;
  liCount: Integer;
  liMessages: Integer;
begin
  POP3.Connect;
  liMessages := POP3.CheckMessages;
  Memo1.Lines.Add('CheckMessages: ' + IntToSTr(liMessages));
  lMsg := TIdMessage.Create;
  try
    POP3.Retrieve(1, lMsg);
    Memo1.Lines.Text := lMsg.MsgId;
    for liCount := 0 to lMsg.MessageParts.Count-1 do
      if lMsg.MessageParts[liCount] is TIdText then
        Memo1.Lines.AddStrings((lMsg.MessageParts[liCount] as TIdText).Body);
  finally
    lMsg.Free;
  end;
end;

end.

//EndOfCode

//StartOfDFM

object Form1: TForm1
  Left = 192
  Top = 114
  Width = 696
  Height = 480
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 216
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Memo1: TMemo
    Left = 24
    Top = 56
    Width = 657
    Height = 185
    Lines.Strings = (
      'Memo1')
    TabOrder = 1
  end
  object POP3: TIdPOP3
    IOHandler = SSLHandler
    AutoLogin = True
    Host = 'pop.gmail.com'
    Username = '[email protected]'
    UseTLS = utUseImplicitTLS
    Password = 'YourPassword'
    Port = 995
    SASLMechanisms = <>
    Left = 40
    Top = 16
  end
  object SSLHandler: TIdSSLIOHandlerSocketOpenSSL
    Destination = 'pop.gmail.com:995'
    Host = 'pop.gmail.com'
    MaxLineAction = maException
    Port = 995
    DefaultPort = 0
    SSLOptions.Method = sslvSSLv3
    SSLOptions.Mode = sslmUnassigned
    SSLOptions.VerifyMode = []
    SSLOptions.VerifyDepth = 0
    Left = 80
    Top = 16
  end
end

//EndOfDFM

2
It seems you know what the problem is. Stop using SSLv3 and switch to TLS. Also... POP with Gmail? Why? I thought we left the single client model back in the 90s...J...
@J: >>POP with Gmail? What you use? Please share your code.Ingo
Naturally. POP vs IMAP has nothing to do with the encryption problem.J...
Do you use latest OpenSSL and latest Indy version?smooty86
Evidently you should now use SSLOptions.Method = sslvTLSv1 instead of SSLOptions.Method = sslvSSLv3; also gmail now uses AES128-SHA encryption instead of RC4-SHA, but probably it does not require changes in SSLOptions settings.kludg

2 Answers

3
votes

The following test code works fine for me to login to Gmail via POP3:

procedure Test;
var
  IdPOP3: TIdPOP3;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
  IdPOP3 := TIdPOP3.Create(nil);
  try
    IdPOP3.Host := 'pop.gmail.com';
    IdPOP3.Port := 995;
    IdPOP3.Username := MyGmailUsername;
    IdPOP3.Password := MyGmailAppPassword;
    IdPOP3.ConnectTimeout := 60000;

    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdPOP3);
    IdSSL.SSLOptions.Method := sslvTLSv1;
    IdSSL.SSLOptions.Mode := sslmClient;
    IdPOP3.IOHandler := IdSSL;
    IdPOP3.UseTLS := utUseImplicitTLS;

    IdPOP3.Connect;
    try
      // use IdPOP3 as needed...
    finally
      IdPOP3.Disconnect;
    end;
  finally
    IdPOP3.Free;
  end;
end;

UPDATE

Note: Indy does not yet natively support OAuth authentication (but there are 3rd party implementations floating around), so if you want to use your real password (and not use 3rd party authentication) then you would need to tweak your Google account security settings to allow less secure apps to access your account. However, if you have 2-Step Verification enabled in your account (and you should), you DO NOT need to allow access to "less secure apps", you can instead generate an application-specific password and use that in place of your real password.

0
votes

Simply change the SSLOptions.Method from sslvSSLv3 to sslvTLSv1.