Browse Source

Build 1.1 minor change for daemons

Minor changes for Linux daemons
PascalCoin 8 years ago
parent
commit
01eee30859
3 changed files with 238 additions and 189 deletions
  1. 22 4
      Units/PascalCoin/URPC.pas
  2. 212 0
      Units/PascalCoin/upcdaemon.pas
  3. 4 185
      pascalcoin_daemon.pp

+ 22 - 4
Units/PascalCoin/URPC.pas

@@ -51,6 +51,8 @@ Type
     FIniFile : TIniFile;
     procedure SetActive(AValue: Boolean);
     procedure SetIniFileName(const Value: AnsiString);
+  protected
+    Function IsValidClientIP(Const clientIp : String; clientPort : Word) : Boolean;
   public
     Constructor Create;
     Destructor Destroy; override;
@@ -122,6 +124,15 @@ begin
   end;
 end;
 
+function TRPCServer.IsValidClientIP(const clientIp: String; clientPort: Word): Boolean;
+begin
+  Result := (clientIp='127.0.0.1');
+  If Not Result then begin
+    // TODO: Allow other IP clients
+  end;
+  //
+end;
+
 constructor TRPCServer.Create;
 begin
   FIniFile := Nil;
@@ -175,6 +186,11 @@ var
   i : Integer;
   Headers : TStringList;
 begin
+  // IP Protection
+  If (Not _RPCServer.IsValidClientIP(FSock.GetRemoteSinIP,FSock.GetRemoteSinPort)) then begin
+    TLog.NewLog(lterror,Classname,FSock.GetRemoteSinIP+':'+inttostr(FSock.GetRemoteSinPort)+' INVALID IP');
+    exit;
+  end;
   Headers := TStringList.Create;
   errNum := CT_RPC_ErrNum_InternalError;
   errDesc := 'No data';
@@ -228,7 +244,7 @@ begin
       except
         On E:Exception do begin
           errDesc:='Error decoding JSON: '+E.Message;
-          TLog.NewLog(lterror,Classname,'Error decoding JSON: '+E.Message);
+          TLog.NewLog(lterror,Classname,FSock.GetRemoteSinIP+':'+inttostr(FSock.GetRemoteSinPort)+' Error decoding JSON: '+E.Message);
           exit;
         end;
       end;
@@ -239,7 +255,7 @@ begin
             errNum := 0;
             errDesc := '';
             try
-              TLog.NewLog(ltinfo,Classname,'Processing method '+jsonobj.AsString('method',''));
+              TLog.NewLog(ltinfo,Classname,FSock.GetRemoteSinIP+':'+inttostr(FSock.GetRemoteSinPort)+' Processing method '+jsonobj.AsString('method',''));
               Valid := ProcessMethod(jsonobj.AsString('method',''),jsonobj.GetAsObject('params'),jsonresponse,errNum,errDesc);
               if not Valid then begin
                 if (errNum<>0) or (errDesc<>'') then begin
@@ -265,7 +281,7 @@ begin
           js.free;
         end;
       end else begin
-        TLog.NewLog(lterror,ClassName,'Received data is not a JSON: '+jsonrequesttxt+' (length '+inttostr(length(jsonrequesttxt))+' bytes)');
+        TLog.NewLog(lterror,ClassName,FSock.GetRemoteSinIP+':'+inttostr(FSock.GetRemoteSinPort)+' Received data is not a JSON: '+jsonrequesttxt+' (length '+inttostr(length(jsonrequesttxt))+' bytes)');
       end;
     until (FSock.LastError <> 0) Or (protocol<>'');
   Finally
@@ -1113,7 +1129,9 @@ begin
       Try
         if canread(1000) then begin
           ClientSock:=accept;
-          if lastError=0 then TRPCProcess.create(ClientSock);
+          if lastError=0 then begin
+            TRPCProcess.create(ClientSock);
+          end;
         end;
       Except
         On E:Exception do begin

+ 212 - 0
Units/PascalCoin/upcdaemon.pas

@@ -0,0 +1,212 @@
+unit upcdaemon;
+
+{$mode objfpc}{$H+}
+
+{ Copyright (c) 2016 by Albert Molina
+
+  Distributed under the MIT software license, see the accompanying file LICENSE
+  or visit http://www.opensource.org/licenses/mit-license.php.
+
+  This unit is a part of Pascal Coin, a P2P crypto currency without need of
+  historical operations.
+
+  If you like it, consider a donation using BitCoin:
+  16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk
+
+  }
+
+interface
+
+uses
+  Classes, SysUtils, daemonapp,
+  SyncObjs, UOpenSSL, UCrypto, UNode, UFileStorage, UFolderHelper, UWalletKeys, UConst, ULog, UNetProtocol,
+  UThread, URPC;
+
+Type
+  { TPCDaemonThread }
+
+  TPCDaemonThread = Class(TPCThread)
+  private
+  protected
+    Procedure BCExecute; override;
+  public
+  end;
+
+  { TPCDaemon }
+
+  TPCDaemon = Class(TCustomDaemon)
+  Private
+    FThread : TPCDaemonThread;
+    Procedure ThreadStopped (Sender : TObject);
+  public
+    Function Start : Boolean; override;
+    Function Stop : Boolean; override;
+    Function Pause : Boolean; override;
+    Function Continue : Boolean; override;
+    Function Execute : Boolean; override;
+    Function ShutDown : Boolean; override;
+    Function Install : Boolean; override;
+    Function UnInstall: boolean; override;
+  end;
+
+  { TPCDaemonMapper }
+
+  TPCDaemonMapper = Class(TCustomDaemonMapper)
+  private
+    FLog : TLog;
+    procedure OnPascalCoinInThreadLog(logtype : TLogType; Time : TDateTime; AThreadID : Cardinal; Const sender, logtext : AnsiString);
+  public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+  end;
+
+
+implementation
+
+{ TPCDaemonThread }
+
+procedure TPCDaemonThread.BCExecute;
+var
+  FNode : TNode;
+  FWalletKeys : TWalletKeysExt;
+  FRPC : TRPCServer;
+begin
+  TLog.NewLog(ltinfo,Classname,'START PascalCoin Server');
+  try
+    try
+      FWalletKeys := TWalletKeysExt.Create(Nil);
+      // Load Node
+      // Check OpenSSL dll
+      if Not LoadSSLCrypt then raise Exception.Create('Cannot load '+SSL_C_LIB+#10+'To use this software make sure this file is available on you system or reinstall the application');
+      TCrypto.InitCrypto;
+      FWalletKeys.WalletFileName := TFolderHelper.GetPascalCoinDataFolder+PathDelim+'WalletKeys.dat';
+      // Creating Node:
+      FNode := TNode.Node;
+      // RPC Server
+      FRPC := TRPCServer.Create;
+      FRPC.WalletKeys := FWalletKeys;
+      FRPC.Active:=true;
+      // Check Database
+      FNode.Bank.StorageClass := TFileStorage;
+      TFileStorage(FNode.Bank.Storage).DatabaseFolder := TFolderHelper.GetPascalCoinDataFolder+PathDelim+'Data';
+      // Reading database
+      FNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
+      FWalletKeys.SafeBox := FNode.Node.Bank.SafeBox;
+      FNode.Node.AutoDiscoverNodes(CT_Discover_IPs);
+      FNode.Node.NetServer.Active := true;
+
+      Repeat
+        Sleep(100);
+      Until Terminated;
+
+      FreeAndNil(FRPC);
+      FNode.NetServer.Active := false;
+      TNetData.NetData.Free;
+      FreeAndNil(FNode);
+    except
+      on e:Exception do begin
+        TLog.NewLog(lterror,Classname,'Exception '+E.Classname+': '+E.Message);
+      end;
+    end;
+  finally
+    TLog.NewLog(ltinfo,Classname,'EXIT PascalCoin Server');
+  end;
+end;
+
+
+{ TPCDaemon }
+
+procedure TPCDaemon.ThreadStopped(Sender: TObject);
+begin
+  FreeAndNil(FThread);
+end;
+
+function TPCDaemon.Start: Boolean;
+begin
+  Result:=inherited Start;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Start '+BoolToStr(Result));
+  FThread:=TPCDaemonThread.Create(True);
+  FThread.OnTerminate:=@ThreadStopped;
+  FThread.FreeOnTerminate:=False;
+  FThread.Resume;
+end;
+
+function TPCDaemon.Stop: Boolean;
+begin
+  Result:=inherited Stop;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Stop: '+BoolToStr(Result));
+  FThread.Terminate;
+end;
+
+function TPCDaemon.Pause: Boolean;
+begin
+  Result:=inherited Pause;
+  TLog.NewLog(ltinfo,ClassName,'Daemon pause: '+BoolToStr(Result));
+  FThread.Suspend;
+end;
+
+function TPCDaemon.Continue: Boolean;
+begin
+  Result:=inherited Continue;
+  TLog.NewLog(ltinfo,ClassName,'Daemon continue: '+BoolToStr(Result));
+  FThread.Resume;
+end;
+
+function TPCDaemon.Execute: Boolean;
+begin
+  Result:=inherited Execute;
+  TLog.NewLog(ltinfo,ClassName,'Daemon execute: '+BoolToStr(Result));
+end;
+
+function TPCDaemon.ShutDown: Boolean;
+begin
+  Result:=inherited ShutDown;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Shutdown: '+BoolToStr(Result));
+  FThread.Terminate;
+end;
+
+function TPCDaemon.Install: Boolean;
+begin
+  Result:=inherited Install;
+  TLog.NewLog(ltinfo,ClassName,'Daemon Install: '+BoolToStr(Result));
+end;
+
+function TPCDaemon.UnInstall: boolean;
+begin
+  Result:=inherited UnInstall;
+  TLog.NewLog(ltinfo,ClassName,'Daemon UnInstall: '+BoolToStr(Result));
+end;
+
+{ TPCDaemonMapper }
+
+procedure TPCDaemonMapper.OnPascalCoinInThreadLog(logtype: TLogType;
+  Time: TDateTime; AThreadID: Cardinal; const sender, logtext: AnsiString);
+Var s : AnsiString;
+begin
+  if AThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:';
+  WriteLn(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(AThreadID,8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext);
+end;
+
+constructor TPCDaemonMapper.Create(AOwner: TComponent);
+Var D : TDaemonDef;
+begin
+  inherited Create(AOwner);
+  FLog := TLog.Create(Nil);
+  FLog.SaveTypes:=CT_TLogTypes_ALL;
+  FLog.FileName:=TFolderHelper.GetPascalCoinDataFolder+PathDelim+'pascalcoin_'+FormatDateTime('yyyymmddhhnn',Now)+'.log';
+  D:=DaemonDefs.Add as TDaemonDef;
+  D.DisplayName:='Pascal Coin Daemon';
+  D.Name:='PascalCoinDaemon';
+  D.DaemonClassName:='TPCDaemon';
+  D.WinBindings.ServiceType:=stWin32;
+end;
+
+destructor TPCDaemonMapper.Destroy;
+begin
+  FLog.OnInThreadNewLog:=Nil;
+  FreeAndNil(FLog);
+  inherited Destroy;
+end;
+
+end.
+

+ 4 - 185
pascalcoin_daemon.pp

@@ -9,196 +9,15 @@ uses
   cthreads,
   {$ENDIF}{$ENDIF}
   sysutils,
-  Classes, daemonapp, 
-  SyncObjs,
-  UOpenSSL, UCrypto, UNode, UFileStorage, UFolderHelper, UWalletKeys, UConst, ULog, UNetProtocol,
-  URPC;
+  Classes, daemonapp,
+  UCrypto, upcdaemon;
 
-Type
 
-  { TPCDaemonThread }
-
-  TPCDaemonThread = Class(TThread)
-    procedure OnPascalCoinLog(logtype : TLogType; Time : TDateTime; AThreadID : Cardinal; Const sender, logtext : AnsiString);
-    Procedure Execute; override;
-  end;
-
-  { TPCDaemon }
-
-  TPCDaemon = Class(TCustomDaemon)
-  Private
-    FThread : TPCDaemonThread;
-    Procedure ThreadStopped (Sender : TObject);
-  public
-    Function Start : Boolean; override;
-    Function Stop : Boolean; override;
-    Function Pause : Boolean; override;
-    Function Continue : Boolean; override;
-    Function Execute : Boolean; override;
-    Function ShutDown : Boolean; override;
-    Function Install : Boolean; override;
-    Function UnInstall: boolean; override;
-  end;
-
-{ TPCDaemonThread }
-
-procedure TPCDaemonThread.OnPascalCoinLog(logtype: TLogType; Time: TDateTime;
-  AThreadID: Cardinal; const sender, logtext: AnsiString);
-Var s : AnsiString;
-begin
-  if (logtype=ltdebug)  then exit;
-  if AThreadID=MainThreadID then s := ' MAIN:' else s:=' TID:';
-  WriteLn(formatDateTime('dd/mm/yyyy hh:nn:ss.zzz',Time)+s+IntToHex(AThreadID,8)+' ['+CT_LogType[Logtype]+'] <'+sender+'> '+logtext);
-end;
-
-Procedure AWriteln(MSg : String; B : Boolean);
-begin
-  Application.Log(etcustom,Msg+BoolToStr(B));
-end;
-
-procedure TPCDaemonThread.Execute;
-var
-  FNode : TNode;
-  FWalletKeys : TWalletKeysExt;
-  FRPC : TRPCServer;
-  FLog : TLog;
-begin
-  FLog := TLog.Create(Nil);
-  FLog.OnInThreadNewLog:=@OnPascalCoinLog;
-  try
-  FWalletKeys := TWalletKeysExt.Create(Nil);
-
-  TLog.NewLog(ltinfo,Classname,'PascalCoin Server');
-  // Load Node
-  // Check OpenSSL dll
-  if Not LoadSSLCrypt then raise Exception.Create('Cannot load '+SSL_C_LIB+#10+'To use this software make sure this file is available on you system or reinstall the application');
-  TCrypto.InitCrypto;
-  FWalletKeys.WalletFileName := TFolderHelper.GetPascalCoinDataFolder+PathDelim+'WalletKeys.dat';
-  // Creating Node:
-  FNode := TNode.Node;
-  // RPC Server
-  FRPC := TRPCServer.Create;
-  FRPC.WalletKeys := FWalletKeys;
-  FRPC.Active:=true;
-  // Check Database
-  FNode.Bank.StorageClass := TFileStorage;
-  TFileStorage(FNode.Bank.Storage).DatabaseFolder := TFolderHelper.GetPascalCoinDataFolder+PathDelim+'Data';
-  // Reading database
-  FNode.Node.Bank.DiskRestoreFromOperations(CT_MaxBlock);
-  FWalletKeys.SafeBox := FNode.Node.Bank.SafeBox;
-  FNode.Node.AutoDiscoverNodes(CT_Discover_IPs);
-  FNode.Node.NetServer.Active := true;
-
-  Repeat
-    Sleep(100);
-  Until Terminated;
-
-
-
-  FreeAndNil(FRPC);
-  FNode.NetServer.Active := false;
-  TNetData.NetData.Free;
-  FreeAndNil(FNode);
-  except
-    on e:Exception do begin
-      TLog.NewLog(lterror,Classname,'Exception '+E.Classname+': '+E.Message);
-      AWriteln('Exception '+E.Classname+': '+E.Message,false);
-    end;
-  end;
-end;
-
-{ TPCDaemon }
-
-procedure TPCDaemon.ThreadStopped(Sender: TObject);
-begin
-  FreeAndNil(FThread);
-end;
-
-function TPCDaemon.Start: Boolean;
-begin
-  Result:=inherited Start;
-  AWriteln('Daemon Start',Result);
-  FThread:=TPCDaemonThread.Create(True);
-  FThread.OnTerminate:=@ThreadStopped;
-  FThread.FreeOnTerminate:=False;
-  FThread.Resume;
-end;
-
-function TPCDaemon.Stop: Boolean;
-begin
-  Result:=inherited Stop;
-  AWriteln('Daemon Stop: ',Result);
-  FThread.Terminate;
-end;
-
-function TPCDaemon.Pause: Boolean;
-begin
-  Result:=inherited Pause;
-  AWriteln('Daemon pause: ',Result);
-  FThread.Suspend;
-end;
-
-function TPCDaemon.Continue: Boolean;
-begin
-  Result:=inherited Continue;
-  AWriteln('Daemon continue: ',Result);
-  FThread.Resume;
-end;
-
-function TPCDaemon.Execute: Boolean;
-begin
-  Result:=inherited Execute;
-  AWriteln('Daemon execute: ',Result);
-end;
-
-function TPCDaemon.ShutDown: Boolean;
-begin
-  Result:=inherited ShutDown;
-  AWriteln('Daemon Shutdown: ',Result);
-  FThread.Terminate;
-end;
-
-function TPCDaemon.Install: Boolean;
 begin
-  Result:=inherited Install;
-  AWriteln('Daemon Install: ',Result);
-end;
-
-function TPCDaemon.UnInstall: boolean;
-begin
-  Result:=inherited UnInstall;
-  AWriteln('Daemon UnInstall: ',Result);
-end;
-
-Type
-
-  { TPCDaemonMapper }
-
-  TPCDaemonMapper = Class(TCustomDaemonMapper)
-    Constructor Create(AOwner : TComponent); override;
-  end;
-
-{ TPCDaemonMapper }
-
-constructor TPCDaemonMapper.Create(AOwner: TComponent);
-
-Var
-  D : TDaemonDef;
-
-begin
-  inherited Create(AOwner);
-  D:=DaemonDefs.Add as TDaemonDef;
-  D.DisplayName:='Pascal Coin Daemon';
-  D.Name:='PascalCoinDaemon';
-  D.DaemonClassName:='TPCDaemon';
-  D.WinBindings.ServiceType:=stWin32;
-end;
-
-begin
-  TCrypto.InitCrypto;
+  Application.Title:='PascalCoin Daemon application';
   RegisterDaemonClass(TPCDaemon);
   RegisterDaemonMapper(TPCDaemonMapper);
-  Application.Title:='Daemon application';
+  TCrypto.InitCrypto;
   Application.Run;
 end.