Hi Chilkat,
I'm having problem DKIM signing my emails using the the DKIM functions in Delphi DLL (from Delphi XE2)
I have a general function SendMailUsingChilkat(), that sets up a Mailman and Email object.
If useDkim it true, it setups the DKIM object and signes and send the email.
The first time there is no problem and the mail is sent (and even verify using CkDkim_VerifyDkimSignature).
The second time it the second time it crashes, when calling CkDkim_Create()
best regards
Torben
Here the code:
procedure SendMailUsingChilkat(Mess: widestring;
subject: widestring;
mailaddress : widestring;
smtpserver : widestring;
fromAddress : widestring = 'dummy@dummy.com';
fromName : widestring = '';
bccAddress : widestring = '';
asHtml : boolean = false;
Attachments : TStrings = nil;
replyToAddress : widestring = '';
logProc : TLogProc = nil;
useDkim : boolean = true;
benchmark : boolean = false);
var
mailman : HCkMailMan;
success : boolean;
html : widestring;
email : HCkEMail;
dkim: HCkDkim;
Recp : TStringList;
i : integer;
contentType : pWideChar;
str : WideString;
mimeData: HCkByteData;
dkimSignedMime: HCkByteData;
strTo: widestring;
starttime : DWORD;
begin
if Assigned(logProc) and benchmark then
starttime := GetTickCount;
Recp := TStringList.Create;
mailman := CkMailMan_Create();
try
success := CkMailMan_UnlockComponent(mailman,CHILKAT_MAIL_UNLOCK_KEY);
if (success <> true) then
raise exception.create('Failed unlocking mailman component. Message: ' + CkMailman__LastErrorText(mailman));
CkMailMan_putSmtpHost(mailman,PWideChar(smtpserver));
//not needed CkMailMan_putSmtpUsername(mailman,'myLogin');
//not needed CkMailMan_putSmtpPassword(mailman,'myPassword');
//not needed CkMailMan_putSmtpPort(mailman,587);
email := CkEmail_Create();
CkEmail_putSubject(email,PWideChar(subject));
if asHtml then
begin
Mess := ubvStringReplace(Mess,#13#10,'',[rfReplaceAll]);
CkEmail_SetHtmlBody(email,PWideChar(Mess));
CkEmail_putCharset(email,'UTF-8');
end
else
begin
CkEmail_putBody(email,PWideChar(Mess));
end;
CkEmail_putFrom(email,PWideChar(FromAddress));
if FromName <> '' then
CkEmail_putFromName(email,PWideChar(FromName));
Recp.Text := ubvStringReplace(mailaddress, ';', #13, [rfReplaceAll]);
for i:=0 to Recp.Count-1 do
begin
CkEmail_AddTo(email,PWideChar(Recp[i]),PWideChar(Recp[i]));
end;
if bccAddress <> '' then
begin
Recp.Text := ubvStringReplace(bccAddress, ';', #13, [rfReplaceAll]);
for i:=0 to Recp.Count-1 do
begin
CkEmail_AddBcc(email,PWideChar(Recp[i]),PWideChar(Recp[i]));
end;
end;
if replyToAddress <> '' then
begin
CkEmail_putReplyTo(email,PWideChar(replyToAddress));
end;
if Assigned(Attachments) then
begin
for i:=0 to Attachments.Count-1 do
begin
str := Attachments[i];
CkEmail__AddFileAttachment(email,PWideChar(str));
if not CkEmail_getLastMethodSuccess(email) then
raise exception.Create('Failed to attach file ' + Attachments[i] + ' to email: ' + CkEmail__LastErrorText(email));
end;
end;
if useDkim then
begin
try
//render email to mimeData
mimeData := CkByteData_Create();
success := CkMailMan_RenderToMimeBytes(mailman,email,mimeData);
if (success <> true) then
raise exception.create('Failed render email to mimebytes. Message: ' + CkMailman__LastErrorText(mailman));
//setup dkim object
dkim := CkDkim_Create(); // <--- It always crashes here the second time
success := CkDkim_UnlockComponent(dkim,CHILKAT_S_MIME_UNLOCK_KEY);
if (success <> true) then
raise exception.create('Failed unlocking dkim component. Message: ' + CkDkim__lastErrorText(dkim));
CkDkim_putDkimDomain(dkim,MAIL_DKIM_DOMAIN);
CkDkim_putDkimSelector(dkim,MAIL_DKIM_SELECTOR);
success := CkDkim_LoadDkimPkFile(dkim,MAIL_RSA_PEM_FILE,MAIL_RSA_PEM_FILE_PASSWORD);
if (success <> true) then
raise exception.create('Failed to load rsa file ' + MAIL_RSA_PEM_FILE + '. Message: ' + CkDkim__lastErrorText(dkim));
//add the DKIM-Signature header to mime and returns the new mime with DKIM-Signature added.
dkimSignedMime := CkByteData_Create();
success := CkDkim_AddDkimSignature(dkim,mimeData,dkimSignedMime);
if (success <> true) then
raise exception.create('Failed to add dkim signature. Message: ' + CkDkim__lastErrorText(dkim));
//verify signature
if CkDkim_VerifyDkimSignature(dkim,0,dkimSignedMime) then
begin
if Assigned(logproc) then
LogProc('Signature in mimeBytes was succesfully verfied');
end
else
raise exception.create('Failed to verify dkim signature. Message: ' + CkDkim__lastErrorText(dkim));
//send signed mimebytes (email)
strTo := ubvStringReplace(mailaddress, ';',',', [rfReplaceAll]);
success := CkMailMan_SendMimeBytes(mailman,PWideChar(FromAddress),PWideChar(strTo),dkimSignedMime);
if (success <> true) then
raise exception.create('Failed to send mimebytes / email. Message: ' + CkMailman__LastErrorText(mailman));
finally
CkByteData_Dispose(mimeData);
CkByteData_Dispose(dkimSignedMime);
CkDkim_Dispose(dkim);
end;
end
else
begin
//normal send (without dkim)
success := CkMailman_SendEmail(mailman,email);
if (success <> true) then
raise exception.Create('Sending mail failed with message: ' + CkMailman__LastErrorText(mailman));
//debug CkEmail_SaveXml(email,PWideChar(ExtractFilePath(ParamStr(0))+'last_mail.xml'));
end;
success := CkMailman_CloseSmtpConnection(mailman);
if (success <> true) then
raise exception.Create('Connection to SMTP server not closed cleanly.');
finally
FreeAndNil(Recp);
CkMailMan_Dispose(mailman);
CkEmail_DropAttachments(email);
CkEmail_Dispose(email);
if Assigned(logProc) and benchmark then
logProc('Total duration of SendMailUsingChilkat(): ' + IntToStr(GetTickCount - starttime) + ' millisec.');
end;
end;