home *** CD-ROM | disk | FTP | other *** search
/ Chip 1999 January / Chip_1999-01_cd.bin / zkuste / delphi / D4 / BLOWNREG.ZIP / EXAMPLES / PASSGARD / MAINFORM.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-09-08  |  25.4 KB  |  966 lines

  1. unit mainform;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, Blowfish, Registry, ComCtrls, Buttons, ExtCtrls, ShellAPI;
  8.  
  9. type
  10.   TPassRecord = record
  11.     AccountName: string;
  12.     LoginID: string;
  13.     Password: string;
  14.     Notes: string;
  15. end;
  16.  
  17. type
  18.   TfrmMain = class(TForm)
  19.     cboAccount: TComboBox;
  20.     edtLogin: TEdit;
  21.     edtPassword: TEdit;
  22.     Blowfish1: TBlowfish;
  23.     sdlDataFile: TSaveDialog;
  24.     stbMain: TStatusBar;
  25.     pnlControls: TPanel;
  26.     spdNew: TSpeedButton;
  27.     spdOpen: TSpeedButton;
  28.     spdSave: TSpeedButton;
  29.     spdClose: TSpeedButton;
  30.     lblAccount: TLabel;
  31.     lblLogin: TLabel;
  32.     lblPassword: TLabel;
  33.     Bevel1: TBevel;
  34.     spdAdd: TSpeedButton;
  35.     spdDelete: TSpeedButton;
  36.     mmoNotes: TMemo;
  37.     lblNotes: TLabel;
  38.     spdExit: TSpeedButton;
  39.     odlDataFile: TOpenDialog;
  40.     spdSaveAs: TSpeedButton;
  41.     spdChangePassword: TSpeedButton;
  42.     spdAboutTSM: TSpeedButton;
  43.     lblVersion: TLabel;
  44.     Label1: TLabel;
  45.     Label2: TLabel;
  46.     Bevel2: TBevel;
  47.     procedure FormCreate(Sender: TObject);
  48.     procedure cboAccountChange(Sender: TObject);
  49.     procedure spdNewClick(Sender: TObject);
  50.     procedure spdOpenClick(Sender: TObject);
  51.     procedure spdSaveClick(Sender: TObject);
  52.     procedure spdAddClick(Sender: TObject);
  53.     procedure spdDeleteClick(Sender: TObject);
  54.     procedure edtLoginChange(Sender: TObject);
  55.     procedure edtPasswordChange(Sender: TObject);
  56.     procedure mmoNotesChange(Sender: TObject);
  57.     procedure spdCloseClick(Sender: TObject);
  58.     procedure spdExitClick(Sender: TObject);
  59.     procedure spdSaveAsClick(Sender: TObject);
  60.     procedure spdChangePasswordClick(Sender: TObject);
  61.     procedure spdAboutTSMClick(Sender: TObject);
  62.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  63.   private
  64.     DataMAC: string;
  65.     RecordList: TStringList;
  66.     Changed: Boolean;
  67.     Loading: Boolean;
  68.     CurrentRecord: TPassRecord;
  69.     function  Unpack(const StringToUnpack: string): TPassRecord;
  70.     function  Pack(const RecordToPack: TPassRecord): string;
  71.     procedure LoadCombo;
  72.     procedure ClearData;
  73.     procedure SaveData;
  74.     procedure LoadData;
  75.     procedure UpdateData(const DataToUpdate: TPassRecord);
  76.     function  GatherData: TPassRecord;
  77.     procedure SpreadData(const DataToSpread: TPassRecord);
  78.     function  GetPassword: string;
  79.     function  CheckPassword(const DataFileToCheck: string): Boolean;
  80.     procedure OpenFile(const FileToOpen: string);
  81.     procedure CheckSave;
  82.     procedure SetChanged(const NewState: Boolean);
  83.     procedure SetButtons;
  84.     procedure SetFields;
  85.     function  FindRecord(const DataToFind: TPassRecord): integer;
  86.     procedure BurnString(var StringToBurn: string);
  87.     procedure BurnDataRecord(var DataRecord: TPassRecord);
  88.   public
  89.     Password: string;
  90.     DataFileName: string;
  91.   end;
  92.  
  93. var
  94.   frmMain: TfrmMain;
  95.  
  96. implementation
  97.  
  98. {$R *.DFM}
  99.  
  100. uses
  101.      newacct, login;
  102.  
  103. const
  104.      RELVER            = '1.03';
  105.      LIT_PAD           = 'TSM padd';
  106.      LIT_IV            = 'afafaqerJHV87%RhG(/f8zf';
  107.      LIT_WRONGPASSWORD = 'The password was not correct. The data file was not opened';
  108.      LIT_OVERWRITE     = ' exists already. Do you want to overwrite it?';
  109.      LIT_SAVECHANGES   = 'You have changed your data. Do you want to save your changes?';
  110.  
  111. procedure TfrmMain.SetChanged(const NewState: Boolean);
  112. begin
  113.      // if NewState is true, then we always set
  114.      // if NewState is false we always reset
  115.      if NewState then
  116.      begin
  117.           // save previous changed states
  118.           Changed := Changed or NewState;
  119.      end
  120.      else
  121.      begin
  122.           // reset
  123.           Changed := false;
  124.      end; {if Newstate}
  125.  
  126.      if Changed then
  127.      begin
  128.           stbMain.Panels[1].Text := 'MOD';
  129.      end
  130.      else
  131.      begin
  132.           stbMain.Panels[1].Text := '';
  133.      end; {if Changed}
  134. end; {TfrmMain.SetChanged}
  135.  
  136. procedure TfrmMain.BurnString(var StringToBurn: string);
  137. var
  138.      i: integer;
  139. begin
  140.      for i := 1 to Length(StringToBurn) do
  141.      begin
  142.           // reset each byte of the string
  143.           StringToBurn[i] := ' ';
  144.      end; {for i}
  145.  
  146.      // set the length to zero
  147.      StringToBurn := '';
  148. end; {TfrmMain.BurnString}
  149.  
  150. function TfrmMain.GetPassword: string;
  151. var
  152.      frmLogin: TfrmLogin;
  153.      PasswordTotest: string;
  154.      TempString: string;
  155. begin
  156.      // show the password screen and get a passord
  157.      frmLogin := TfrmLogin.Create(self);
  158.      frmLogin.ShowModal;
  159.      PasswordToTest := frmLogin.edtPassword.Text;
  160.      frmLogin.Free;
  161.  
  162.      // only proceed if we have a password
  163.      if PasswordToTest <> '' then
  164.      begin
  165.           // set up blowfish
  166.           Blowfish1.CipherMode := CBC;
  167.           Blowfish1.LoadIVString(PasswordToTest);
  168.           Blowfish1.InitialiseString(PasswordToTest);
  169.           Blowfish1.EncryptString(PasswordToTest, TempString);
  170.           Blowfish1.CBCMACString(TempString);
  171.           Blowfish1.Burn;
  172.  
  173.           // store the password and MAC
  174.           DataMAC := TempString;
  175.           Password := PasswordToTest;
  176.  
  177.           Result := DataMAC;
  178.      end;
  179.  
  180.      // Burn Data
  181.      BurnString(PasswordToTest);
  182.      BurnString(TempString);
  183. end; {TfrmMain.GetPassword}
  184.  
  185. function TfrmMain.CheckPassword(const DataFileToCheck: string): Boolean;
  186. var
  187.      DataFile: TextFile;
  188.      MACFromFile: string;
  189. begin
  190.      if not FileExists(DataFileToCheck) then
  191.      begin
  192.           Result := False;
  193.           Exit;
  194.      end;
  195.  
  196.      AssignFile(DataFile, DataFileToCheck);
  197.  
  198.      Reset(DataFile);
  199.  
  200.      // read the mac
  201.      ReadLn(DataFile, MACFromFile);
  202.  
  203.      CloseFile(DataFile);
  204.  
  205.  
  206.      if MACFromFile <> DataMAC then
  207.      begin
  208.           // password is not verified, exit;
  209.           Result := False;
  210.      end
  211.      else
  212.      begin
  213.           Result := True;
  214.      end;
  215.  
  216.      // Burn
  217.      BurnString(MACFromFile);
  218. end; {TfrmMain.CheckPassword}
  219.  
  220. procedure TfrmMain.ClearData;
  221. begin
  222.      // stop the combo box autolocate
  223.      Loading := True;
  224.  
  225.      RecordList.Clear;
  226.  
  227.      cboAccount.Items.Clear;
  228.      cboAccount.Text := '';
  229.      edtLogin.Text := '';
  230.      edtPassword.Text := '';
  231.      mmoNotes.Lines.Clear;
  232.  
  233.      // set the input fields
  234.      SetFields;
  235.  
  236.      Loading := False;
  237. end; {TfrmMain.ClearData}
  238.  
  239. procedure TfrmMain.LoadData;
  240. var
  241.      DataFile: TextFile;
  242.      DataLine: string;
  243. begin
  244.      // load in the account names from the data file
  245.      AssignFile(DataFile, DataFileName);
  246.  
  247.      Reset(DataFile);
  248.  
  249.      // read the mac - this is a dummy read as we have already
  250.      // checked this.
  251.      ReadLn(DataFile, DataLine);
  252.  
  253.      // read in the records
  254.      while not EOF(DataFile) do
  255.      begin
  256.           // read the data record and add to the list
  257.           ReadLn(DataFile,DataLine);
  258.           RecordList.Add(DataLine);
  259.      end;
  260.  
  261.      CloseFile(DataFile);
  262.  
  263.      // update the status bar
  264.      stbMain.Panels[2].Text := DataFileName;
  265.  
  266.      LoadCombo;
  267.  
  268.      // reset the changed status
  269.      SetChanged(False);
  270. end; {TfrmMain.LoadData}
  271.  
  272. procedure TfrmMain.SaveData;
  273. var
  274.      DataFile: TextFile;
  275.      i: integer;
  276. begin
  277.      // save the information back to the file
  278.      // update the status panel
  279.      stbMain.Panels[2].Text := DataFileName;
  280.  
  281.      // open the data file
  282.      AssignFile(DataFile, DataFileName);
  283.  
  284.      FileMode := 1;
  285.  
  286.      Rewrite(DataFile);
  287.  
  288.      // save the MAC
  289.      WriteLn(DataFile, DataMAC);
  290.  
  291.      for i := 0 to RecordList.Count-1 do
  292.      begin
  293.           WriteLn(DataFile, RecordList.Strings[i]);
  294.      end;
  295.  
  296.      // close the file
  297.      CloseFile(DataFile);
  298.  
  299.      // update the changed status
  300.      SetChanged(False);
  301. end; {TfrmMain.SaveData}
  302.  
  303. procedure TfrmMain.UpdateData(const DataToUpdate: TPassRecord);
  304. var
  305.      i: integer;
  306. begin
  307.      if RecordList.Count > 0 then
  308.      begin
  309.           i := FindRecord(DataToUpdate);
  310.           RecordList.Strings[i] := Pack(DataToUpdate);
  311.      end;
  312. end; {TfrmMain.UpdateData}
  313.  
  314. function TfrmMain.FindRecord(const DataToFind: TPassRecord): integer;
  315. var
  316.      i: integer;
  317.      TempString: string;
  318.      KeyString: string;
  319.      KeyString1: string;
  320. begin
  321.      Result := 0;
  322.  
  323.      TempString := Pack(DataToFind);
  324.      KeyString := Copy(TempString,1, Pos(';',TempString)-1);
  325.  
  326.      for i := 0 to RecordList.Count-1 do
  327.      begin
  328.           KeyString1 := Copy(RecordList.Strings[i], 1, Pos(';', RecordList.Strings[i])-1);
  329.           if KeyString1 = KeyString then
  330.           begin
  331.                Result := i;
  332.                Exit;
  333.           end;
  334.      end;
  335. end; {TfrmMain.FindRecord}
  336.  
  337. procedure TfrmMain.LoadCombo;
  338. var
  339.      DataRecord: TPassRecord;
  340.      i: integer;
  341. begin
  342.      // we should implement some sort of burn here
  343.      cboAccount.Items.Clear;
  344.  
  345.      // load from scratch
  346.      for i := 0 to RecordList.Count-1 do
  347.      begin
  348.           DataRecord := UnPack(RecordList.Strings[i]);
  349.           cboAccount.Items.Add(DataRecord.AccountName);
  350.      end;
  351.  
  352.      // update the status line
  353.      stbMain.Panels[0].Text := IntToStr(RecordList.Count);
  354.  
  355.      // reset the default display
  356.      if cboAccount.Items.Count > 0 then
  357.      begin
  358.           cboAccount.ItemIndex := 0;
  359.           cboAccountChange(self);
  360.      end
  361.      else
  362.      begin
  363.           // there are no records - clear
  364.           cboAccount.Text := '';
  365.           edtLogin.Text := '';
  366.           edtPassword.Text := '';
  367.           mmoNotes.Lines.Clear;
  368.      end;
  369.  
  370.      // set the enabled state of the fields
  371.      SetFields;
  372.  
  373.      // Burn the temp record
  374.      BurnDataRecord(DataRecord);
  375. end; {TfrmMain.LoadCombo}
  376.  
  377. procedure TfrmMain.FormCreate(Sender: TObject);
  378. var
  379.      Reg: TRegistry;
  380. begin
  381.      // display the version on the main window
  382.      lblVersion.Caption := RELVER;
  383.      
  384.      // create list
  385.      RecordList := TStringList.Create;
  386.  
  387.      // get the name of the file to read if there is one
  388.      Reg := TRegistry.Create;
  389.  
  390.      // try to find the default file
  391.      if Reg.OpenKey('Software\TSMInc\PassKeep',False) then
  392.      begin
  393.           DataFileName := Reg.ReadString('Datafile');
  394.  
  395.           OpenFile(DataFileName);
  396.      end
  397.      else
  398.      begin
  399.           SetButtons;
  400.           SetFields;
  401.      end;
  402.  
  403.      Reg.Free;
  404. end; {TfrmMain.FormCreate}
  405.  
  406. procedure TfrmMain.OpenFile(const FileToOpen: string);
  407. begin
  408.      // if there is a data file, then attempt to open it
  409.      if FileExists(FileToOpen) and (FileToOpen <> '') then
  410.      begin
  411.           // clear the current data
  412.           ClearData;
  413.  
  414.           // get the password for the new file
  415.           GetPassword;
  416.  
  417.           if not CheckPassword(FileToOpen) then
  418.           begin
  419.                // password did not verify - clear the info
  420.                DataFileName := '';
  421.                stbMain.Panels[2].Text := 'No data file';
  422.  
  423.                // tell the user
  424.                MessageDlg(LIT_WRONGPASSWORD, mtError, [mbOK], 0);
  425.           end
  426.           else
  427.           begin
  428.                DataFileName := FileToOpen;
  429.  
  430.                // Load the data
  431.                LoadData;
  432.           end;
  433.      end
  434.      else
  435.      begin
  436.           // no data file - clear the info
  437.           DataFileName := '';
  438.           stbMain.Panels[2].Text := 'Data file not found';
  439.      end;
  440.  
  441.      SetButtons;
  442.      SetFields;
  443.  
  444. end; {TfrmMain.OpenFile}
  445.  
  446. function TfrmMain.Pack(const RecordToPack: TPassRecord): string;
  447. var
  448.      TempString: string;
  449.      TempString1: string;
  450. begin
  451.      // load blowfish
  452.      Blowfish1.CipherMode := CBC;
  453.      Blowfish1.LoadIVString(LIT_IV);
  454.      Blowfish1.InitialiseString(Password + LIT_PAD);
  455.  
  456.      TempString := '';
  457.      Blowfish1.EncryptString(RecordToPack.AccountName, TempString1);
  458.      TempString := TempString + TempString1;
  459.      TempString := TempString + ';';
  460.      Blowfish1.EncryptString(RecordToPack.LoginId, TempString1);
  461.      TempString := TempString + TempString1;
  462.      TempString := TempString + ';';
  463.      Blowfish1.EncryptString(RecordToPack.Password, TempString1);
  464.      TempString := TempString + TempString1;
  465.      TempString := TempString + ';';
  466.      Blowfish1.EncryptString(RecordToPack.Notes, TempString1);
  467.      TempString := TempString + TempString1;
  468.      Result := TempString;
  469.  
  470.      // burn Blowfish
  471.      Blowfish1.Burn;
  472.  
  473.      // burn temp variables
  474.      BurnString(TempString);
  475.      BurnString(TempString1);
  476. end; {TfrmMain.Pack}
  477.  
  478. function TfrmMain.Unpack(const StringToUnpack: string): TPassRecord;
  479. var
  480.      ParsePos: integer;
  481.      TempString: string;
  482. begin
  483.      // load blowfish
  484.      Blowfish1.CipherMode := CBC;
  485.      Blowfish1.LoadIVString(LIT_IV);
  486.      Blowfish1.InitialiseString(Password + LIT_PAD);
  487.  
  488.      // parse the data record
  489.      TempString := StringToUnpack;
  490.      ParsePos := Pos(';',TempString);
  491.      Result.AccountName := Copy(TempString,1,ParsePos-1);
  492.      TempString := Copy(TempString,ParsePos+1,Length(TempString)-ParsePos);
  493.      ParsePos := Pos(';',TempString);
  494.      Result.LoginId := Copy(TempString,1,ParsePos-1);
  495.      TempString := Copy(TempString,ParsePos+1,Length(TempString)-ParsePos);
  496.      ParsePos := Pos(';',TempString);
  497.      Result.Password := Copy(TempString,1,ParsePos-1);
  498.      TempString := Copy(TempString,ParsePos+1,Length(TempString)-ParsePos);
  499.      Result.Notes := TempString;
  500.  
  501.      // decrypt the strings
  502.      Blowfish1.DecryptString(Result.AccountName, TempString);
  503.      Result.AccountName := TempString;
  504.      Blowfish1.DecryptString(Result.LoginId, TempString);
  505.      Result.LoginId := TempString;
  506.      Blowfish1.DecryptString(Result.Password, TempString);
  507.      Result.Password := TempString;
  508.      Blowfish1.DecryptString(Result.Notes, TempString);
  509.      Result.Notes := TempString;
  510.  
  511.      // burn Blowfish
  512.      Blowfish1.Burn;
  513.  
  514.      // burn temp variables
  515.      BurnString(TempString);
  516. end; {TfrmMain.Unpack}
  517.  
  518. procedure TfrmMain.cboAccountChange(Sender: TObject);
  519. var
  520.      i: integer;
  521.      DataRecord: TPassRecord;
  522. begin
  523.      Loading := True;
  524.  
  525.      // set defaults
  526.      edtLogin.Text := '';
  527.      edtPassword.Text := '';
  528.      mmoNotes.Lines.Clear;
  529.      CurrentRecord.AccountName := '';
  530.      CurrentRecord.LoginID := '';
  531.      CurrentRecord.Password := '';
  532.  
  533.      // find a matching record
  534.      for i := 0 to RecordList.Count-1 do
  535.      begin
  536.           DataRecord := UnPack(RecordList.Strings[i]);
  537.           if DataRecord.AccountName = cboAccount.Text then
  538.           begin
  539.                SpreadData(DataRecord);
  540.                CurrentRecord := DataRecord;
  541.           end;
  542.      end;
  543.  
  544.      Loading := False;
  545.  
  546.      SetFields;
  547.  
  548.      // Burn the temp record
  549.      BurnDataRecord(DataRecord);
  550. end; {TfrmMain.cboAccountChange}
  551.  
  552. procedure TfrmMain.BurnDataRecord(var DataRecord: TPassRecord);
  553. begin
  554.      // burn each of the strings individually
  555.      BurnString(DataRecord.AccountName);
  556.      BurnString(DataRecord.LoginId);
  557.      BurnString(DataRecord.Password);
  558.      BurnString(DataRecord.Notes);
  559. end; {TfrmMain.BurnDataRecord}
  560.  
  561. procedure TfrmMain.SetFields;
  562. begin
  563.      //set the edit boxes
  564.      if cboAccount.Text = '' then
  565.      begin
  566.           edtLogin.Enabled := False;
  567.           edtPassword.Enabled := False;
  568.           mmoNotes.Enabled := False;
  569.      end
  570.      else
  571.      begin
  572.           edtLogin.Enabled := True;
  573.           edtPassword.Enabled := True;
  574.           mmoNotes.Enabled := True;
  575.      end;
  576. end; {TfrmMain.SetFields}
  577.  
  578. procedure TfrmMain.spdNewClick(Sender: TObject);
  579. var
  580.      Reg: TRegistry;
  581. begin
  582.      // if the old file has changed, save the changes to it
  583.      CheckSave;
  584.  
  585.      Reg := TRegistry.Create;
  586.  
  587.      // create a new data file
  588.      if odlDataFile.Execute then
  589.      begin
  590.           // check if the file exists
  591.           if FileExists(odlDataFile.FileName) then
  592.           begin
  593.                // file exists - should we overwrite?
  594.                if MessageDlg(odlDataFile.FileName + LIT_OVERWRITE, mtConfirmation, [mbOK, mbCancel] ,0) = mrOK then
  595.                begin
  596.                     // set the data filename
  597.                     DataFileName := odlDataFile.FileName;
  598.  
  599.                     // get the password f≤r the file
  600.                     GetPassword;
  601.  
  602.                     // Save the file
  603.                     SaveData;
  604.  
  605.                     // set the current file in the registry
  606.                     Reg.OpenKey('Software\TSMInc\PassKeep',True);
  607.                     Reg.WriteString('Datafile', DataFileName);
  608.                end; {if MessageDlg}
  609.           end
  610.           else
  611.           begin
  612.                // set the data filename
  613.                DataFileName := odlDataFile.FileName;
  614.  
  615.                // get the password f≤r the file
  616.                GetPassword;
  617.  
  618.                // Save the file
  619.                SaveData;
  620.  
  621.                // set the current file in the registry
  622.                Reg.OpenKey('Software\TSMInc\PassKeep',True);
  623.                Reg.WriteString('Datafile', DataFileName);
  624.           end; {if FileExists}
  625.      end;
  626.  
  627.      // Update the button and field status
  628.      SetButtons;
  629.      SetFields;
  630.  
  631.      // release the registry
  632.      Reg.Free;
  633. end; {TfrmMain.spdNewClick}
  634.  
  635. procedure TfrmMain.spdOpenClick(Sender: TObject);
  636. var
  637.      Reg: TRegistry;
  638. begin
  639.      // if the old file has changed, save the changes to it
  640.      CheckSave;
  641.  
  642.      // create the registy object to save the path to the file
  643.      Reg := TRegistry.Create;
  644.  
  645.      if odlDataFile.Execute then
  646.      begin
  647.           DataFileName := odlDataFile.FileName;
  648.  
  649.           OpenFile(DataFileName);
  650.  
  651.           // set the current file in the registry
  652.           Reg.OpenKey('Software\TSMInc\PassKeep',True);
  653.           Reg.WriteString('Datafile', DataFileName);
  654.      end;
  655.      Reg.Free;
  656. end; {TfrmMain.spdOpenClick}
  657.  
  658. procedure TfrmMain.spdSaveClick(Sender: TObject);
  659. begin
  660.      SaveData;
  661. end; {TfrmMain.spdSaveClick}
  662.  
  663. procedure TfrmMain.spdSaveAsClick(Sender: TObject);
  664. var
  665.      Reg: TRegistry;
  666. begin
  667.      Reg := TRegistry.Create;
  668.  
  669.      if sdlDataFile.Execute then
  670.      begin
  671.           DataFileName := sdlDataFile.FileName;
  672.           SaveData;
  673.  
  674.           // set the current file in the registry
  675.           Reg.OpenKey('Software\TSMInc\PassKeep',True);
  676.           Reg.WriteString('Datafile', DataFileName);
  677.      end;
  678.      Reg.Free;
  679. end; {TfrmMain.spdSaveAsClick}
  680.  
  681. procedure TfrmMain.spdAddClick(Sender: TObject);
  682. var
  683.      frmNewAcct: TfrmNewAcct;
  684.      TempString: string;
  685.      NewAccount: TPassRecord;
  686.      i: integer;
  687. begin
  688.      frmNewAcct := TfrmNewAcct.Create(self);
  689.      frmNewAcct.ShowModal;
  690.      if frmNewAcct.NewAccountName <> '' then
  691.      begin
  692.           // create the new record
  693.           NewAccount.AccountName := frmNewAcct.NewAccountName;
  694.           TempString := Pack(NewAccount);
  695.           RecordList.Add(TempString);
  696.           RecordList.Sort;
  697.  
  698.           // update the changed status
  699.           SetChanged(True);
  700.      end; {if}
  701.      frmNewAcct.Free;
  702.  
  703.      // load in any new records into the combobox
  704.      LoadCombo;
  705.  
  706.      // find the record in the list
  707.      for i := 0 to cboAccount.Items.Count-1 do
  708.      begin
  709.           if cboAccount.Items.Strings[i] = NewAccount.AccountName then
  710.           begin
  711.                cboAccount.ItemIndex := i;
  712.                cboAccountChange(self);
  713.                SetButtons;
  714.                edtLogin.SetFocus;
  715.                Exit;
  716.           end;
  717.      end;
  718.  
  719.      // set the state of the speed buttons
  720.      SetButtons;
  721.  
  722.      // Burn the temp record
  723.      BurnDataRecord(NewAccount);
  724. end; {TfrmMain.spdAddClick}
  725.  
  726. procedure TfrmMain.spdDeleteClick(Sender: TObject);
  727. var
  728.      i: integer;
  729.      DataRecord: TPassRecord;
  730. begin
  731.      // find a matching record
  732.      for i := 0 to RecordList.Count-1 do
  733.      begin
  734.           DataRecord := UnPack(RecordList.Strings[i]);
  735.           if DataRecord.AccountName = cboAccount.Text then
  736.           begin
  737.                RecordList.Delete(i);
  738.                Break;
  739.           end;
  740.      end;
  741.  
  742.      // Load the combo box again
  743.      LoadCombo;
  744.  
  745.      // update the changed status
  746.      SetChanged(True);
  747.  
  748.      // set the state of the speed buttons
  749.      SetButtons;
  750.  
  751.      // Burn the temp record
  752.      BurnDataRecord(DataRecord);
  753. end; {TfrmMain.spdDeleteClick}
  754.  
  755. procedure TfrmMain.edtLoginChange(Sender: TObject);
  756. var
  757.      DataRecord: TPassRecord;
  758. begin
  759.      if Loading then Exit;
  760.  
  761.      DataRecord := GatherData;
  762.  
  763.      if edtLogin.Text <> CurrentRecord.LoginID then
  764.      begin
  765.           UpdateData(DataRecord);
  766.           SetChanged(True);
  767.      end;
  768.  
  769.      // Burn the temp record
  770.      BurnDataRecord(DataRecord);
  771. end; {TfrmMain.edtLoginChange}
  772.  
  773. procedure TfrmMain.edtPasswordChange(Sender: TObject);
  774. var
  775.      DataRecord: TPassRecord;
  776. begin
  777.      if Loading then Exit;
  778.  
  779.      DataRecord := GatherData;
  780.  
  781.      if edtPassword.Text <> CurrentRecord.Password then
  782.      begin
  783.           UpdateData(DataRecord);
  784.           SetChanged(True);
  785.      end;
  786.  
  787.      // Burn the temp record
  788.      BurnDataRecord(DataRecord);
  789. end; {TfrmMain.edtPasswordChange}
  790.  
  791. procedure TfrmMain.mmoNotesChange(Sender: TObject);
  792. var
  793.      DataRecord: TPassRecord;
  794. begin
  795.      if Loading then Exit;
  796.  
  797.      DataRecord := GatherData;
  798.  
  799.      if DataRecord.Notes <> CurrentRecord.Notes then
  800.      begin
  801.           UpdateData(DataRecord);
  802.           SetChanged(True);
  803.      end;
  804.  
  805.      // Burn the temp record
  806.      BurnDataRecord(DataRecord);
  807. end; {TfrmMain.mmoNotesChange}
  808.  
  809. function TfrmMain.GatherData: TPassRecord;
  810. var
  811.      i: integer;
  812. begin
  813.      Result.AccountName := cboAccount.Text;
  814.      Result.LoginID := edtLogin.Text;
  815.      Result.Password := edtPassword.Text;
  816.      Result.Notes := '';
  817.      for i := 0 to mmoNotes.Lines.Count-1 do
  818.      begin
  819.           Result.Notes := Result.Notes + mmoNotes.Lines[i] + ';';
  820.      end;
  821. end; {TfrmMain.GatherData}
  822.  
  823. procedure TfrmMain.SpreadData(const DataToSpread: TPassRecord);
  824. var
  825.      SepPos: integer;
  826.      TempString: string;
  827.      TempString1: string;
  828. begin
  829.      cboAccount.Text := DataToSpread.AccountName;
  830.      edtLogin.Text := DataToSpread.LoginID;
  831.      edtPassword.Text := DataToSpread.Password;
  832.      mmoNotes.Lines.Clear;
  833.      TempString := DataToSpread.Notes;
  834.      SepPos := Pos(';', TempString);
  835.      while SepPos <> 0 do
  836.      begin
  837.           TempString1 := Copy(TempString,1,SepPos-1);
  838.           mmoNotes.Lines.Add(TempString1);
  839.           TempString := Copy(TempString,SepPos+1,Length(TempString));
  840.           SepPos := Pos(';', TempString);
  841.      end;
  842.  
  843.      // burn the temp variables
  844.      BurnString(TempString);
  845.      BurnString(TempString1);
  846. end; {TfrmMain.SpreadData}
  847.  
  848. procedure TfrmMain.spdCloseClick(Sender: TObject);
  849. begin
  850.      // check if there is data to be saved
  851.      CheckSave;
  852.  
  853.     // Close the data file
  854.     DataFileName := '';
  855.  
  856.     // clear the display
  857.     ClearData;
  858.     stbMain.Panels[0].Text := '0';
  859.     stbMain.Panels[1].Text := '';
  860.     stbMain.Panels[2].Text := 'No data file';
  861.  
  862.     SetButtons;
  863. end; {TfrmMain.spdCloseClick}
  864.  
  865. procedure TfrmMain.CheckSave;
  866. begin
  867.      if Changed then
  868.      begin
  869.           // ask if we want to save
  870.           if MessageDlg(LIT_SAVECHANGES, mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  871.           begin
  872.                SaveData;
  873.           end;
  874.      end;
  875. end; {TfrmMain.CheckSave}
  876.  
  877. procedure TfrmMain.SetButtons;
  878. begin
  879.      if DataFileName = '' then
  880.      begin
  881.           spdNew.Enabled := True;
  882.           spdOpen.Enabled := True;
  883.           spdSave.Enabled := False;
  884.           spdSaveAs.Enabled := False;
  885.           spdClose.Enabled := False;
  886.           spdAdd.Enabled := False;
  887.           spdDelete.Enabled := False;
  888.           spdChangePassword.Enabled := False;
  889.      end
  890.      else
  891.      begin
  892.           spdNew.Enabled := True;
  893.           spdOpen.Enabled := True;
  894.           spdSave.Enabled := True;
  895.           spdSaveAs.Enabled := True;
  896.           spdClose.Enabled := True;
  897.           spdAdd.Enabled := True;
  898.           spdDelete.Enabled := True;
  899.           spdChangePassword.Enabled := True;
  900.      end;
  901.  
  902.      spdDelete.Enabled := (RecordList.Count > 0);
  903. end; {TfrmMain.SetButtons}
  904.  
  905. procedure TfrmMain.spdExitClick(Sender: TObject);
  906. begin
  907.      // check for save
  908.      CheckSave;
  909.      Halt;
  910. end; {TfrmMain.spdExitClick}
  911.  
  912. procedure TfrmMain.spdChangePasswordClick(Sender: TObject);
  913. var
  914.      OldPassword: string;
  915.      NewPassword: string;
  916.      TempRecord: TPassRecord;
  917.      i: integer;
  918. begin
  919.      // save the old password
  920.      OldPassword := Password;
  921.  
  922.      // get the new password
  923.      GetPassword;
  924.      NewPassword := Password;
  925.  
  926.      if Password <> '' then
  927.      begin
  928.           // rename the password file
  929.           DeleteFile(DataFileName + '.bak');
  930.           RenameFile(DataFileName, DataFileName + '.bak');
  931.  
  932.           // convert the encrypted passwords
  933.           for i := 0 to RecordList.Count-1 do
  934.           begin
  935.                // decrypt the old password
  936.                Password := OldPassword;
  937.                TempRecord := UnPack(RecordList.Strings[i]);
  938.                Password := NewPassword;
  939.                RecordList.Strings[i] := Pack(TempRecord);
  940.           end;
  941.  
  942.           // Save the file
  943.           SaveData;
  944.      end;
  945.  
  946.      // Burn the temp passwords
  947.      BurnString(OldPassword);
  948.      BurnString(NewPassword);
  949.  
  950.      // Burn the temp record
  951.      BurnDataRecord(TempRecord);
  952. end; {TfrmMain.spdChangePasswordClick}
  953.  
  954. procedure TfrmMain.spdAboutTSMClick(Sender: TObject);
  955. begin
  956.      ShellExecute(GetDesktopWindow(), nil, PChar('http://www.crypto-central.com/software.html'), nil, nil, SW_SHOWNORMAL);
  957. end; {TfrmMain.spdAboutTSMClick}
  958.  
  959. procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  960. begin
  961.      CheckSave;
  962. end;
  963.  
  964. end.
  965.  
  966.