Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New API example crashes [CORE5376] #5649

Open
firebird-automations opened this issue Oct 14, 2016 · 7 comments
Open

New API example crashes [CORE5376] #5649

firebird-automations opened this issue Oct 14, 2016 · 7 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @aafemt

Example 01.create.pas crashes on run because master.getUtilInterface returns nil.

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

assignee: Alexander Peshkov [ alexpeshkoff ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Not reproduced on fpc:

#⁠ fpc -Fu../../src/include/gen/ -Mdelphi 01.create.pas
Free Pascal Compiler version 2.6.4 [2014/11/16] for x86_64
Copyright (c) 1993-2014 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling 01.create.pas
Compiling /usr/home/firebird/B3_0_Release/src/include/gen/Firebird.pas
Linking 01.create
13224 lines compiled, 1.4 sec
localhost interfaces #⁠ ./01.create
Database fbtests.fdb created
Re-attached database fbtests.fdb
Table dates_table created
Record inserted into dates_table
localhost interfaces #⁠

Afraid I hurried a bit trying to help with win-specific issue

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

assignee: Alexander Peshkov [ alexpeshkoff ] =>

@firebird-automations
Copy link
Collaborator Author

Commented by: @aafemt

Yes, with FPC 3.0.0 it works. The issue should be related to Delphi.

@firebird-automations
Copy link
Collaborator Author

Commented by: Boris Vinkler (borisvin)

I wrote the code below in Delphi XE 3 (the code is written from the example "01.create.pas").
When I want to open an allready encrypted database by passing the encryption key via my application then the application freezes at line "att := prov.attachDatabase(st, 'fbtests.fdb', dpb.getBufferLength(st), dpb.getBuffer(st));" (the function "Callback" is triggered).

Could anyone please help me to manage how to pass the encryption key from delphi application to the Firebird server?

Program create;
{$APPTYPE CONSOLE}

uses
Sysutils,Firebird,Windows;

var
st : IStatus;
master : IMaster;
util : IUtil;
dpb : IXpbBuilder;
prov : IProvider;
att : IAttachment;
tra : ITransaction;

procedure PrintError\(s : IStatus\);
var
	maxMessage : Integer;
	outMessage : PAnsiChar;
begin
	maxMessage := 256;
	outMessage := PAnsiChar\(StrAlloc\(maxMessage\)\);
	util\.formatStatus\(outMessage, maxMessage, s\);
	writeln\(outMessage\);
	StrDispose\(outMessage\);
end;

type
IKeyCallback = class(ICryptKeyCallbackImpl)
function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; override;
end;

function IKeyCallback.callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal;
var Key: PAnsiChar;
KeyLength:Integer;
begin
KeyLength := 1;
If (bufferLength > 0) and (buffer <> nil) then
begin
WriteLn('Sending key');
Key := '1234567890abcdef';
KeyLength := Length(Key);
WriteLn('got key request: '+Key+':'+IntToStr(KeyLength));
Move(Key, buffer^, KeyLength);
end;
Result := KeyLength;
end;

var param1:String;

begin
if ParamCount>0 then
begin
param1 := ParamStr(1);
end;
if param1<>'open' then
param1 := 'create';

WriteLn\('starting\.\.\.\('\+param1\+'\)'\);
master := fb\_get\_master\_interface;
if master = nil then
 begin
  WriteLn\('master is nil'\);
  Exit;
 end;
Write\('getting util interface\.\.\.'\);
util := master\.getUtilInterface;
WriteLn\('done\.'\);

Write\('getting status and dispatcher\.\.\.'\);
st := master\.getStatus;
prov := master\.getDispatcher;
WriteLn\('done\.'\);
if \(util = nil\) or \(st = nil\) or \(prov = nil\) then
begin
	WriteLn\('null pointers'\);
	Exit;
end;

try
	prov\.setDbCryptCallback\(st, IKeyCallback\.create\);
	Write\('Generating DPB\.\.\.'\);
	// create DPB
	dpb := util\.getXpbBuilder\(st, IXpbBuilder\.DPB, nil, 0\);
	Write\('page size\.\.\.'\);
	dpb\.insertInt\(st, isc\_dpb\_page\_size, 4 \* 1024\);
	Write\('user name\.\.\.'\);
	dpb\.insertString\(st, isc\_dpb\_user\_name, 'sysdba'\);
	Write\('password\.\.\.'\);
	dpb\.insertString\(st, isc\_dpb\_password, 'masterkey'\);
	WriteLn\('done\.'\);

//create empty database
if param1='create' then
begin
	  att := prov\.createDatabase\(st, 'fbtests\.fdb', dpb\.getBufferLength\(st\), dpb\.getBuffer\(st\)\);
	  writeln \('Database fbtests\.fdb created'\);

  // start transaction
  tra := att\.startTransaction\(st, 0, nil\);

  // Encrypt database
  att\.execute\(st, tra, 0, 'alter database encrypt with aes128', 3,
    nil, nil, nil, nil\);	// Input parameters and output data not used

  // commit transaction \(will close interface\)
  tra\.commit\(st\);
  tra := nil;

  WriteLn\('Press Enter to continue'\);
  ReadLn;

  // detach from database
  att\.detach\(st\);
  att := nil;

  // remove unneeded any more tag from DPB
  if dpb\.findFirst\(st, isc\_dpb\_page\_size\)
    then dpb\.removeCurrent\(st\);

  // attach it once again
  att := prov\.attachDatabase\(st, 'fbtests\.fdb', dpb\.getBufferLength\(st\), dpb\.getBuffer\(st\)\);
  writeln \('Re\-attached database fbtests\.fdb'\);

  // start transaction
  tra := att\.startTransaction\(st, 0, nil\);

  // create table
  att\.execute\(st, tra, 0, 'create table dates\_table \(d1 date\)', 3,
    nil, nil, nil, nil\);	// Input parameters and output data not used

  // commit transaction retaining
  tra\.commitRetaining\(st\);
  writeln \('Table dates\_table created'\);

  // insert a record into dates\_table
  att\.execute\(st, tra, 0, 'insert into dates\_table values \(CURRENT\_DATE\)', 3,
    nil, nil, nil, nil\);	// Input parameters and output data not used

  // commit transaction \(will close interface\)
  tra\.commit\(st\);
  tra := nil;

  writeln \('Record inserted into dates\_table'\);
end

//open database
else if param1='open' then
begin
  att := prov\.attachDatabase\(st, 'fbtests\.fdb', dpb\.getBufferLength\(st\), dpb\.getBuffer\(st\)\);
  writeln \('Database fbtests\.fdb Opened'\);
  exit;
end;

	// detach from database \(will close interface\)
	att\.detach\(st\);
	att := nil;

	dpb\.dispose;
	dpb := nil;
except
	on e: FbException do PrintError\(e\.getStatus\);
end;

prov\.release;

end.

@firebird-automations
Copy link
Collaborator Author

Commented by: @paulbeach

According to Alexey Kovyazin this compiles fine using Delphi XE6 or XE7, I wonder if there is a problem with earlier versions of Delphi? On cross checking this code will run as well... i.e. Alexey did manage to get the code to also work with an encrypt library and passed the key via the application. So the version of Delphi does seem to be an issue.

@firebird-automations
Copy link
Collaborator Author

Commented by: @aafemt

Yes, the problem is data types. Especially NativeInt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant