EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Simple demo for sFTP for a newbie

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#32450
Posted: 03/03/2015 14:29:21
by T SMITH (Standard support level)
Joined: 03/02/2015
Posts: 18

Hi

This is a really newbie "stop being lazy" kind of question and for that I appologise.

OK, so I have downloaded the evaluation VCL version for Delphi\Freepascal for use with Lazarus and FPC. I have never used or tried commercial code libraries so I am finding my way somewhat.

I acknowledge use of the license key so I have created a new project, saved the project, and added the paths to the SecureBox.VLC folder in my libaries and unit paths. It finds the units OK.

Code
...
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  SBSimpleSftp, SBSftpCommon, SBSSHConstants, SBSSHKeyStorage, SBTypes, SBUtils, SBStrUtils;
...
procedure TfrmMain.FormCreate(Sender: TObject);
begin    
SBUtils.SetLicenseKey('6600675....AD3CA8');
end


I have run the form, clicked the button. I assume this means any code in the project will work and be compiled OK etc? Activation codes with software libraries are totally alien to me so I am sorry for the stupidity.

I then try to use the demo project supplied in C:\Users\Public\Documents\EldoS\SecureBlackbox.VCL\Samples\Delphi\SFTPBlackbox\Client\SimpleSFTPClient

I see there is no Lazarus projects in the sample - only Delphi ones. And although Freepascal and Delphi are very similar, they are not identical so one has to convert a Delphi project in Lazarus via Tools --> Convert Delphi unit\project\package to Lazarus unit\project\package. This I have done for the SimpleSftpDemo delphi project.

But, I can't use the sample form because it is a Delphi form. So whenever I try to use or show the form, Lazarus complains that it can't access a Delphi form. Without the form I am struggling to see what parts of the sample code I could use or how they all interact.

All I want to do with this SecureBox sFTP library is create a project in Lazarus with one form. On the form will be three edit fields for the user to enter the sFTP server address (192.168.0.X), his username and his password. And a button to connect and a second button to disconnect. I then want the program to connect to the server when the connect button is clicked. For now, that is all I want to do. I will look at moving files up and down once I have this bit done.

A similar example that I attempted with open-source code (which failed to successfully connect) is this function that passes the properties of three edit fields and a filename to an sFTP server. It nearly worked except the login always failed. This is why I am now looking at SecureBox. :

Code
function TForm1.SendUsingEncryptedFTP(Host, Username, Password, SourcefileName : string) : boolean;
var
SourceFile: string;
FSFTP:TSimpleSFTP;  // from Synapse library http://synapse.ararat.cz/files/contrib/sftp.zip
SSLSettings : TCustomSSL;
FConnected:Boolean;
FAbortFlag:Boolean;
begin
  FSFTP := TSimpleSFTP.Create;
  SSLSettings := TCustomSSL.Create(nil);
    try
      SSLSettings.SSLType := LT_SSHv2;
      SSLSettings.Username:= Username;
      SSLSettings.Password:= Password;
      FSFTP.Connect(Host, '22', Username, Password);
      FSFTP.PutFile(Sourcefilename, '/');
      FSFTP.Disconnect;
    finally
      FSFTP.Free;
      SSLSettings.Free;
    end;
  end;    


Can anyone help me or point me in the direction to achieve this. If I can do that, I will be buying a license for the sFTP package. But until I can check it works as I need, I can't assess its suitability (which I know of course it is suitable given your history and client base but if I am too dumb to use it, then it isn't suitable for me, if you understand what I mean!)
#32453
Posted: 03/04/2015 02:04:45
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

Quote
I have run the form, clicked the button. I assume this means any code in the project will work and be compiled OK etc?

You should use SetLicenseKey if you use pre-compiled units provided in evaluation package. If you compile from source (you'll receive it after license purchase) then this method is not needed. Details: https://www.eldos.com/documentation/sb...sekey.html

If you can't run a sample with a GUI then its better to start with ConsoleSFTP sample to understand how the components works. These articles will also help: https://www.eldos.com/documentation/sb...imple.html
#32457
Posted: 03/04/2015 04:37:22
by T SMITH (Standard support level)
Joined: 03/02/2015
Posts: 18

https://www.eldos.com/documentation/sbb/documentation/ref_fun_setlicensekey.html states :

Use this function to pass license key to the library.

Pascal:
procedure SetLicenseKey(const Key: string);

So, I have :

Code
procedure TfrmMain.Button1Click(Sender: TObject);
begin   SBUtils.SetLicenseKey('660067560EFA9ACA818A0F134ED8D16D6D425561114AC7B9510ABB6C1953587A' +
  '189F66FFBAC...blah blah blah...C582FAAD3CA8');
end;      


Yet whenever I run my program, after clicking Button1, I still get the error:

"Key validation handler is not assigned. Please handle the OnKeyValidate event and implement proper key validation code there."

Code
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  SBSimpleSftp, SBSftpCommon, SBSSHConstants, SBSSHKeyStorage, SBTypes, SBUtils, SBStrUtils;

type

  { TfrmMain }

  TfrmMain = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Connect;
    procedure Disconnect;

  private
    { private declarations }
  public
    SftpClient : TElSimpleSFTPClient
    { public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.lfm}

{ TfrmMain }

procedure TfrmMain.FormCreate(Sender: TObject);
begin
// To be safe, add license code at form creation too:
SBUtils.SetLicenseKey('660067560EFA9ACA818A0F134ED8D16D6D425561114AC7B9510ABB6C1953587A' +
  '189F66FFB...blah...blah...C582FAAD3CA8');
   SFTPClient := TElSimpleSFTPClient.Create(self);
end;

procedure TfrmMain.Button1Click(Sender: TObject);

begin
   SBUtils.SetLicenseKey('660067560EFA9ACA818A0F134ED8D16D6D425561114AC7B9510ABB6C1953587A' +
  '189F66FFBAC...blah...blah...788C582FAAD3CA8');
end;


procedure TfrmMain.Button2Click(Sender: TObject);
begin
  Connect;
end;

procedure TfrmMain.Button3Click(Sender: TObject);
begin
  Disconnect;
end;

procedure TfrmMain.Connect;
begin
  SftpClient.Address := '192.168.0.9'; // an internal network address where sFTP server lives
  SftpClient.Port := 22;
  SftpClient.CompressionAlgorithms[SSH_CA_ZLIB] := true;
  SftpClient.Username := 'My_sFTP_USERNAME';
  SftpClient.Password := 'My_sFTP_PASSWORD';
  Memo1.Lines.Add('Connecting to ' + SftpClient.Address);

    try
      SftpClient.Open;
      Memo1.Lines.Add('Sftp connection established');
      //FCurrentDir := '.';
      Refresh;
    except
      on E: Exception do
      begin
        Memo1.Lines.Add('Sftp connection failed with message [' + E.Message + ']');
        if Length(SftpClient.ServerSoftwareName) > 0 then
          Memo1.Lines.Add('Server software identified itself as: ' + SftpClient.ServerSoftwareName);
        SftpClient.Close;
        Exit;
      end;
    end;;
end;

procedure TfrmMain.Disconnect;
begin
  Memo1.Lines.Add('Disconnecting');
  SftpClient.Close;
  SftpClient.free;
end;

end.


#32458
Posted: 03/04/2015 04:42:54
by Vsevolod Ievgiienko (EldoS Corp.)

Quote
"Key validation handler is not assigned. Please handle the OnKeyValidate event and implement proper key validation code there."

The message is thrown by SFTP class and is not related to the license key. Please check the article for details: https://www.eldos.com/documentation/sb...idate.html

Also both samples show how to implement this handler.
#32465
Posted: 03/04/2015 05:19:41
by T SMITH (Standard support level)
Joined: 03/02/2015
Posts: 18

Thanks for the pointer.

Using the samples, I have adjusted to :

Code
...
procedure ClientKeyValidate(Obj : TObject; Sender: TObject;
  ServerKey: TElSSHKey; var Validate: Boolean);
begin
  Validate := true;
  // NEVER do this in production code. You MUST check the key validity. The sample procedure is described in SecureBlackbox FAQ on http://www.eldos.com/sbb/articles/
end;
...

  KeyValidateMethod.Code := @ClientKeyValidate;
  KeyValidateMethod.Data := nil;

    try
      SFTPClient.OnKeyValidate := TSSHKeyValidateEvent(KeyValidateMethod);;
      SftpClient.Open();
...

but the use of the @ pointer symbol is generating :

Code
unit1.pas(100,29) Error: Incompatible types: got "<procedure variable type of procedure(TObject,TObject,TElSSHKey,var Boolean) of object;Register>" expected "Pointer"

If I remove the @ symbol, it then says
Code
unit1.pas(100,48) Error: Wrong number of parameters specified for call to "ClientKeyValidate"

??

Sorry to be a nuisance.
#32467
Posted: 03/04/2015 05:30:58
by Vsevolod Ievgiienko (EldoS Corp.)

Try to do next way:

Code
type
  TMy = class
  public
    class procedure ClientKeyValidate(Obj : TObject; Sender: TObject;
  ServerKey: TElSSHKey; var Validate: Boolean);
  end;

class procedure TMy.ClientKeyValidate(Obj : TObject; Sender: TObject;
  ServerKey: TElSSHKey; var Validate: Boolean);
begin
  Validate := true;
end;

...

SFTPClient.OnKeyValidate := TMy.ClientKeyValidate;
#32468
Posted: 03/04/2015 05:48:41
by T SMITH (Standard support level)
Joined: 03/02/2015
Posts: 18

Thankyou and aplogies.

Your suggestion still generates the second error :

Code
unit1.pas(110,56) Error: Wrong number of parameters specified for call to "ClientKeyValidate"


It looks as though I need to pass "serverkey" to ClientKeyValidate (which I assume is the hex and colon seperated string of the key)? But where is that referenced? Again, the sample, when I do a search for "ServerKey" is only referenced at

Code
procedure ClientKeyValidate(Obj : TObject; Sender: TObject;
  ServerKey: TElSSHKey; var Validate: Boolean);  

e.g. ClientKeyValidate(strServerKey, true);
#32469
Posted: 03/04/2015 06:00:58
by Eugene Mayevski (EldoS Corp.)

Class procedure won't work. You need an instance method to handle the event.


Sincerely yours
Eugene Mayevski
#32471
Posted: 03/04/2015 06:09:11
by Vsevolod Ievgiienko (EldoS Corp.)

Quote
Your suggestion still generates the second error


Please remove this parameter: Obj : TObject.

Server key is returned by the server during the connection process and is passed to this event handler as TElSSHKey instance that you can check.
#32472
Posted: 03/04/2015 06:30:05
by T SMITH (Standard support level)
Joined: 03/02/2015
Posts: 18

I cant fatham this. It is all enough to drive a man to insanity.

Using both the normal way and the Tmy. method, even after removing Obj: TObject, it still generates the same error "Wrong number of parameters specified for call to "ClientKeyValidate".

So, I have tried these two ways :

Code
...

type
  { KeyChecker }
  TMy = class
  public
    class procedure ClientKeyValidate(Sender: TObject; ServerKey: TElSSHKey; var Validate: Boolean);
  end;

  { TfrmMain }

  TfrmMain = class(TForm)
    Button1: TButton;                
    // etc etc
...
class procedure Tmy.ClientKeyValidate(Sender: TObject; ServerKey: TElSSHKey; var Validate: Boolean);
begin
  Validate := true;
end;
...
  KeyValidateMethod.Code := TMy.ClientKeyValidate;
  KeyValidateMethod.Data := nil;

    try
      SFTPClient.OnKeyValidate := TSSHKeyValidateEvent(KeyValidateMethod);;
      SftpClient.Open();                                                  
...


and I have tried

Code
...
type
{ TfrmMain }

  TfrmMain = class(TForm)
    Button1: TButton;      
    procedure ClientKeyValidate(Obj : TObject; Sender: TObject; ServerKey: TElSSHKey; var Validate: Boolean);    
...
procedure ClientKeyValidate(Obj : TObject; Sender: TObject; ServerKey: TElSSHKey; var Validate: Boolean);
begin
  Validate := true;
end;
...
  KeyValidateMethod.Code := @ClientKeyValidate;
  KeyValidateMethod.Data := nil;

    try
      SFTPClient.OnKeyValidate := TSSHKeyValidateEvent(KeyValidateMethod);;
      SftpClient.Open();                                                  
...

Both return the same error or, in the second code paste, the pointer error.

If there isn't a way to resolve this I will leave you alone. But given that other programmers, who also use Lazarus and Freepascal, use this library, it must be something I am doing wrong, surely?
Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.

Reply

Statistics

Topic viewed 1542 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!