Retrieving blocked attachments from Google with Delphi

So, I was looking at an old email, and there was an attachment.

Unfortunately, Google's Gmail had blocked the attachment, thinking it had a virus attached to it (It was just a zip file containing some Delphi source files, there weren't any binaries in it)

 

So, I clicked on the "Show original"  from the context menu, then clicked on the "Download original" link to save the entire message into a text file.

From the text file, the attachment appeared like so:

------=_Part_9053_26313827.1141183321391
Content-Type: application/zip; name="Inors.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Inors.zip"
X-Attachment-Id: f_ek9315vx

UEsDBAoAAAAAACVuYTQAAAAAAAAAAAAAAAAaAAAAU2hhcmVkIEZpbGVzL0NvbW1vbiBGaWxlcy9Q
SwMEFAAAAAgA5ZgrNNsyWjZWFQAAjWEAACYAAABTaGFyZWQgRmlsZXMvQ29tbW9uIEZpbGVzL0F3
.... many lines
c3N2ZXIuc2NjUEsBAhQACgAAAAAA+21hNAAAAAAAAAAAAAAAACIAAAAAAAAAAAAQAAAAQvwuAElu
b3JzX09yaW9uX0JDYXN0U2VydmVyX1JNU0NsaWVudC9QSwUGAAAAALkBuQFkpwAAgvwuAAAA
------=_Part_9053_26313827.1141183321391--

And so, I cut and pasted the MIME data, starting from the line beginning with "UEsD", till the last line, beginning with "b3Jz" into a text file, named Base64.txt

I then came up with the following code to decode it:

uses
  IdCoder, IdCoderMIME, System.Classes, System.SysUtils;

{$R *.res}
var
  LCoder: TIdDecoderMIME;
  SrcStream, DstStream: TFileStream;

var
  LCoder: TIdDecoderMIME;
  SrcStream, DstStream: TFileStream;
begin
  LCoder := TIdDecoderMIME.Create(nil);
  DstStream := TFileStream.Create('c:\temp\INORS.zip', fmCreate);
  SrcStream := TFileStream.Create('c:\temp\base64.txt', fmOpenRead);
  try
    LCoder.DecodeBegin(DstStream);
    LCoder.Decode(SrcStream);
    LCoder.DecodeEnd;
  finally
    SrcStream.Free;
    DstStream.Free;
    LCoder.Free;
  end;
end.

and only to discover to my chagrin that the Indy MIME decoder wasn't able to decode it. It appears that it doesn't deal with CRLF in the MIME stream.

Eventually, I used the RTL's TBase64Encoding class to decode it. The following is the code that does the job. It appears this class is specifically designed to handle data from MIME attachments. It has a limitation of handling up to 76 characters per line, not including CRLF/LF.

uses
  System.Classes, System.SysUtils, System.NetEncoding;

{$R *.res}
var
  SrcStream, DstStream: TFileStream;
begin
  DstStream := TFileStream.Create('c:\temp\INORS.zip', fmCreate);
  SrcStream := TFileStream.Create('c:\temp\base64.txt', fmOpenRead);
  try
    TBase64Encoding.Base64.Decode(SrcStream, DstStream);
  finally
    SrcStream.Free;
    DstStream.Free;
  end;
end.
Published Mon, 1 Jan 2018 @ 11:30 PM by chuacw
Related articles: ,