• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1216
  • Last Modified:

Password protect an application and DB

Hi,

I want to put in a login prompt for my application.  The application uses an Access DB behind it, I want to password protect the DB as well so only a person who knows the passwords can use the application or go into the DB.  So from Delphi app the user will input the username and password for the access DB.

Can anyone offer me a solution here?  I am using ADO and setup a connection to the DB at application startup.  All other forms in the app use the ADO connection from the main form.

I want a simple form to be displayed with a username and password edit box as well as a login and cancel button.  I want to creat my own, not use the built in one as I want to include my logo on it.  

If Login is clicked and the login details are a match then the user gets in, if login details are incorrect then an error box is displayed and they are asked to re-enter the details.  After 3 failed attempts I want the app to close.

If the Cancel button is clicked the app closes cleanly.

Hope someone has a good solution out there for me, look forward to your replies.

I tried using the built in login prompt in the ADO connection but keep getting this error:

---------------------------
Debugger Exception Notification
---------------------------
Project BankManager.exe raised exception class EOleException with message 'Cannot start your application. The workgroup information file is missing or opened exclusively by another user'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------

So if you could also let me know how to setup the Access DB with a username and password that would be create!

I know this is a big ask so if anyone can offer me a working solution I will give more points.....

Below is how I am setting up the connection to the DB from my main form...  Any questions just ask...

********************************************************************

function GetDBLOCATION : String;
var
  Reg : TRegistry;
begin
  Result := '';
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey ('\Software\'+application.title, true) then
      Result := Reg.ReadString ('DBNAME');
      Reg.CloseKey;
  finally
    Reg.Free;
  end;
end;

procedure TForm1.Startup(Sender: TObject);
var
  Reg : TRegistry;
  flag : Boolean;
begin
  flag := True;
  if Not DBConnected then
  begin
    DBPath := GetDBlocation;
    while not FileExists(DBPath) do
    begin
      OpenDialog1.Title := 'Database Location';
      OpenDialog1.Filter := 'Access Database|*.mdb';
      if OpenDialog1.Execute then
      begin
        Reg := TRegistry.Create;
        DBPath := OpenDialog1.FileName;
        try
          Reg.RootKey := HKEY_CURRENT_USER;
          Reg.OpenKey ('\Software\'+application.title, true); // Write path and address to register
          Reg.CloseKey;
        finally
          Reg.Free;
        end; // try
      end // if
      else
      begin
        showmessage('Unable to connect to the Database.');
        flag:=false;
        break;
      end;
    end;
    if flag then
      BankManagerConnection.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
                                + DBPath
                                + ';Persist Security Info=False';
    DBConnected := True;
  end;
end;

********************************************************************

Bego
0
begonz
Asked:
begonz
  • 4
  • 2
1 Solution
 
Ivanov_GCommented:
in your DPR file put something like this:

    if TfrmLogin.Login = 0 then
      begin
        Application.Title := 'Applicant Tracker';
        Application.CreateForm(TfrmMain, frmMain);
        Application.Run;
      end
    else
      begin
        Exit;
      end

you main ADOConnection sits on the DataModule named DM and you try to open the connection with User and Pass you enter.
TfrmLogin implementation should look like this:

unit frLogin;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, frEntity, ExtCtrls, StdCtrls, Buttons, IniFiles;

type
  TfrmLogin = class(TfrmEntity)
    lblUsername: TLabel;
    edtUsername: TEdit;
    edtPassword: TEdit;
    lblPassword: TLabel;
    imgStop: TImage;
    lblLoginInfo: TLabel;
    btnLogin: TBitBtn;
    btnCancel: TBitBtn;
    btnOptions: TBitBtn;
    procedure btnLoginClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
  private
    DBParams  : String;
    procedure InitDBConnection;
  public
    ButtonClicked    : Integer;
    class function Login : Integer;
  end;

var
  frmLogin: TfrmLogin;

implementation

{$R *.dfm}

uses frLoginOptions
  , uConfiguration
  , frDataModule
  , uClientVars
  , frBusy
  ;

procedure TfrmLogin.btnLoginClick(Sender: TObject);
begin
  inherited;
  // try to login in the DB
  InitDBConnection;
  DM.DB.Params.Add('user_name=' + edtUsername.Text);
  DM.DB.Params.Add('password='  + edtPassword.Text);
  try
    TfrmBusy.OpenDB(DM.DB);
  except
    on E: Exception do
      begin
        // put back the params
        DM.DB.Params.CommaText := DBParams;
        // show the message
        MessageDlg(E.Message, mtError, [mbOK], 0);
        // Exit procedure
        Exit;
      end;
  end;
  ClientVar.UserName := edtUsername.Text;
  ButtonClicked := 0;
  ModalResult := mrOK;
end;

class function TfrmLogin.Login: Integer;
var
  frm_login     : TfrmLogin;
begin
  // show the login form
  Result := -1;
  frm_login := TfrmLogin.Create(nil);
  try
    frm_login.ShowModal;
  finally
    if Result = -1 then
      Result := frm_login.ButtonClicked;  
    frm_login.Free;
  end;
end;

procedure TfrmLogin.btnCancelClick(Sender: TObject);
begin
  inherited;
  ButtonClicked := 1;
  ModalResult := mrOK;
end;

procedure TfrmLogin.InitDBConnection;
var
  FName       : String;
  IniFile     : TIniFile;
  lc_str      : String;
  lc_int      : Integer;
  db_name     : String;
  db_server   : String;
begin
  FName := GetConfigFile(Application.ExeName);
  if not FileExists(FName) then
    begin
      MessageDlg('Configuration file missing!', mtError, [mbOK], 0);
      Exit;
    end;
  // open configuration file
  IniFile := TIniFile.Create(FName);
  try
    lc_int := IniFile.ReadInteger('DBConnection', 'ServerType', 0);
    if lc_int = 0 then
      begin
        // Local server
        db_name := IniFile.ReadString('DBConnection', 'Database', '');
        DM.DB.DatabaseName := db_name;
      end
    else
      begin
        // Remote server
        db_server := IniFile.ReadString('DBConnection', 'ServerAddr', '');
        db_name   := IniFile.ReadString('DBConnection', 'Database', '');
        lc_str    := IniFile.ReadString('DBConnection', 'Protocol', '');
        if UpperCase(lc_str) = 'TCP/IP' then
          begin
            // TCP/IP Connection
            // format -       <server_name>:<filename>
            DM.DB.DatabaseName := db_server + ':' + db_name;
          end
        else if UpperCase(lc_str) = 'NETBEUI' then
          begin
            // Named Pipe connection
            // format -       \\<server_name>\<filename>
            DM.DB.DatabaseName := '\\' + db_server + '\' + db_name;
          end
        else if UpperCase(lc_str) = 'SPX' then
          begin
            // SPX connection
            // format -       <server_name>@<filename>
            DM.DB.DatabaseName := db_server + '@' + db_name;
          end;
        // SQL Role
        lc_str := IniFile.ReadString('DBConnection', 'SQLRole', '');
        DM.DB.Params.Add('sql_role_name=' + lc_str);
        lc_str := IniFile.ReadString('DBConnection', 'CharSet', '');
        DM.DB.Params.Add('lc_ctype=' + lc_str);
        // copy the params in case of bad login
        DBParams := DM.DB.Params.CommaText;
      end;
  finally
    IniFile.Free;
  end;
end;

end.
0
 
VoodoomanCommented:
Hi

It depends on the level of security that you are looking for.

I have been doing the following for several years and it has been very effective.

Setup a default password on your database.  Then hardcode the password into your executable (open a connection with the password).

Now your database is secure from casual opening with Access (users must have the password).

If you want users to Login - Within your database create a table with UserName and Password. A few simple forms in your App will allow you to create and remove users and passwords and verify Users and Passwords.

Before anyone screams at me that this is not very secure - in most cases we just want to hide the database from prying eyes and button clickers - ultimate security is not the issue.

Beware - you can buy Access Database password cracking tools on the Internet for $20 - how many users know (or care) to go to the trouble?

Voodooman
0
 
begonzAuthor Commented:
Thanks for your responses guys.  Ivanov, your solution seems complex, will take me a bit of time to go through it, still not sure how to setup the access DB though.

Voodooman, I like your idea, seems simple, hardcode the password and then have a table in the DB that contains the users own username and password.  Could you give me a bit more info on how I could do this?  Seems simpler than Ivanov's.  If I hard code the password, my connection string to the DB will be different I guess.

When the user puts in their user name and password, I guess it is just an SQL query to check that they both match.

I would like this app to be secure as it is a Banking tool and will contain the users bank details and transactions.  Needs to be password protected.  I know it isn't impossible to hack into anything but having a username and password set does make it a little harder.

Thanks.
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
VoodoomanCommented:
Hi

I dont use the Access DB with Delphi myself as I dont like ADO. (I use it with Visual Basic though).

Start off by opening the DB with no password - so that will give you the string for the connection.

Now open your Access DB with Access and create the password. Now add the required pwd=voodooman (or whatever).  Once you can open your password protected DB - you are half way there.

Now create a table called Passwords with Username and Password as the fields (create a unique index on the UserName is always a good idea).

In the show event of your main form call a modal form (F_Password.showmodal).

On the form put a box for the user name and another for the password (Perhaps TB_UserName and TB_Password)

Under the cancel put Application.Terminate

Under the Login Button put some code to verify the user name and password (Just query the database for the user name and password)

Something like

Try

mydataset.sql.clear;
mydataset.sql.add('Select * from Passwords were Username=' + QuotedStr(TB_User.Text) + 'Password=' + QuotedStr(Tb_Password.Text);

mydataset.active:=false;
mydataset.active:=true; //Open the recordset

If mydataset.recordcount>0 then self.close

Except

On E: Except do

//some error message here - I use my own routines called IMessage and EMessage

End;


This is easy and works well

Voodooman
0
 
begonzAuthor Commented:
Hi Voodooman.

I like you solution, makes sense, I think I can deal with the checking username and password thing fine but connecting to the DB is proving to be impossible.

I set a password as you said but when I try and build a test connection using ADO I keep getting the following error:

---------------------------
Microsoft Data Link Error
---------------------------
Test connection failed because of an error in initializing provider. Cannot start your application. The workgroup information file is missing or opened exclusively by another user.
---------------------------
OK  
---------------------------

Once I have this connection sorted I think I may be fine....

Help  :o(

Bego
0
 
begonzAuthor Commented:
PS:  Please see my original question to see how to make the DB connection.  Thanks.
0
 
begonzAuthor Commented:
Not quiet the full answer but thanks guys....I have posted another question re the connection to a password protected access DB...take a look here:

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_21128519.html
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now