{$IFDEF WtrGate}{$IFDEF UseOvr}{$O+,F+}{$ENDIF}{$ENDIF}
UNIT Gateway;

{$i platform.inc}

{ Gateway.Pas                                                           }
{                                                                       }
{ Deze unit regelt de toegang tot de gateway                            }
{ Een node kan toestemming hebben om de gate way te gebruiken als :     }
{                                                                       }
{ Zijn/Haar record in de userbase dat toe staat :                       }
{                                                                       }
{       All/Allow/None   All = Alle berichten die van deze node komen   }
{                       Allow= Alleen berichten direct van deze node    }
{                       None = Geen berichten die van deze node komen   }
{                                                                       }
{ Als de userbase het toestaat wordt vervolgens gekeken of er in de     }
{ disallow lijst een uitzondering voor deze node wordt gemaakt.         }
{                                                                       }
{ Als de userbase het NIET toestaat wordt er gekeken of er in de allow  }
{ lijsten een uitzondering gemaakt wordt.                               }

INTERFACE

USES Database;

PROCEDURE AddAllowFIDOLine (Adres : STRING);
PROCEDURE AddDisAllowFIDOLine (Adres : STRING);
FUNCTION  CheckGateway (Adres : FidoAddrType; Name : STRING; VAR Reason : STRING) : BOOLEAN;
PROCEDURE JunkGatewayChecks;


IMPLEMENTATION

USES Ramon,
     Fido,
     Msgs,
     DList,
     Language;

TYPE GatewayPtr  = ^GatewayList;
     GatewayList = RECORD
                         UserType : SystemType;

                         CASE Integer OF
                        { Fido }  1 : (Address : FidoAddrType;
                                       User    : STRING[MaxLenSysopName];
                                       );
                       (*
                       { Usenet } 2 : (Name    : STRING[240]);
                       *)
                   END;

VAR GatewayAccess   : List;
    GatewayRestrict : List;


{--------------------------------------------------------------------------}
{ ParseFIDOLine                                                            }
{                                                                          }
{ Deze routine verwerkt een ingelezen ALLOW-FIDO of FORBID-FIDO regel.     }
{                                                                          }
PROCEDURE ParseFIDOLine (Regel : STRING; VAR Tmp : GateWayPtr);

VAR Z,N   : BYTE;
    Error : ValNop;
    User  : STRING;

LABEL Verder;

BEGIN
     { Strip het allow fido van de lijst }
     Regel:=DeleteFrontSpaces (Regel);
     Tmp:=NIL;

     IF (Pos (' ',Regel) > 0) THEN
     BEGIN
          User:=DeleteFrontSpaces (Copy (Regel,Pos (' ',Regel),255));
          Regel:=DeleteBackSpaces (Copy (Regel,1,Pos (' ',Regel)));
     END ELSE
     BEGIN
          Regel:=DeleteBackSpaces (Regel);
          User:='';
     END;

     IF (Regel = '') THEN
        Exit;

     { Reserveer geheugen voor een nieuw object }
     GetMem (Tmp,SizeOf (GatewayList));

     { Invoer Regel op 0 zetten }
     FidoSplit ('0',Tmp^.Address);

     Z:=Pos (':',Regel);
     IF (Z > 0) THEN
        Val (Copy (Regel,1,Z-1),Tmp^.Address.Zone,Error)
     ELSE
     BEGIN
          Tmp^.Address.Zone:=65535;
          GOTO Verder;
     END;

     IF (Regel[Z+1] = '*') THEN
     BEGIN
          Tmp^.Address.Net:=65535;
          GOTO Verder;
     END;

     N:=Pos ('/',Regel);
     IF (N > 0) THEN
        Val (Copy (Regel,Z+1,N-(Z+1)),Tmp^.Address.Net,Error)
     ELSE
         Val (Copy (Regel,Z+1,Length (Regel)),Tmp^.Address.Net,Error);

     IF (Regel[N+1] = '*') THEN
     BEGIN
          Tmp^.Address.Node:= 65535;
          GOTO Verder;
     END;

     Z:=Pos ('.',Regel);
     IF (Z > 0) THEN
        Val (Copy (Regel,N+1,Z-(N+1)),Tmp^.Address.Node,Error)
     ELSE
         Val (Copy (Regel,N+1,Length (Regel)),Tmp^.Address.Node,Error);

     IF (Regel[Z+1] = '*') THEN
     BEGIN
          Tmp^.Address.Point:=65535;
          GOTO Verder;
     END;

     IF (Z > 0) THEN
        Val (Copy (Regel,Z+1,Length(Regel)),Tmp^.Address.Point,Error);

Verder:

     Tmp^.UserType:=_F;
     Tmp^.User:=UpCaseString (User);

     {
     IF (User <> '') THEN
        Tmp^.User:=UpcaseString (User)
     ELSE
         Tmp^.User:='';
     }
END;


{--------------------------------------------------------------------------}
{ AddAllowFIDOLine                                                         }
{                                                                          }
{ Voegt een uitzondering toe aan de lijst, in deze lijst wordt het         }
{ bepaalde users toegestaan om van de gateway gebruikt te maken.           }
{                                                                          }
{ Voorbeeld:                                                               }
{                                                                          }
{ ALLOW-FIDO 2:280/802.6             Martijn Dijksterhuis                  }
{ ALLOW-FIDO 2:280/*                                                       }
{ ALLOW-FIDO 2:280/801                                                     }
{                                                                          }
PROCEDURE AddAllowFIDOLine (Adres : STRING);

VAR Tmp : GatewayPtr;

BEGIN
     Delete (Adres,1,10);
     ParseFIDOLine (Adres,Tmp);

     IF (Tmp <> NIL) THEN
        GatewayAccess.Add (Tmp);
END;


{--------------------------------------------------------------------------}
{ AddDisallowFIDOline                                                      }
{                                                                          }
{ Voeg een regel toe aan de configutie om bepaalde user het gebruik van    }
{ de gateway onmogenlijk te maken.                                         }
{                                                                          }
{ Voorbeeld:                                                               }
{                                                                          }
{ DISALLOW-FIDO 2:280/804                                                  }
{ DISALLOW-FIDO 2:280/803 Joop Stokvis                                     }
{ DISALLOW-FIDO 2:2800/*                                                   }
{                                                                          }
PROCEDURE AddDisAllowFIDOLine (Adres : STRING);

VAR Tmp : GatewayPtr;

BEGIN
     Delete (Adres,1,11);
     ParseFIDOLine (Adres,Tmp);

     IF (Tmp <> NIL) THEN
        GatewayRestrict.Add (Tmp);
END;


{--------------------------------------------------------------------------}
{ CheckAccesss                                                             }
{                                                                          }
{ Controleerd tot wat voor level de user niet van de gateway gebruik mag   }
{ maken. Deze routine wordt zowel voor ALLOW-FIDO als FORBID-FIDO controle }
{ gebruikt (RWI 950625).                                                   }
{                                                                          }
FUNCTION CheckAccess (Adres : FidoAddrType; Name : STRING; VAR Gateway : List; VAR Reason : STRING) : BYTE;

VAR Tmp       : GatewayPtr;
    Match,
    HighMatch : BYTE;

LABEL Verder;

BEGIN
     Tmp:=Gateway.GetFirstItem;
     HighMatch:=0;

     WHILE (Tmp <> NIL) DO
     BEGIN
          { Controleer of het een fido entry is }
          IF (Tmp^.UserType <> _F) THEN
             GOTO Verder;

          { Controleer of de namen overeenkomen }
          IF (Tmp^.User <> '') THEN
             IF (Tmp^.User <> Name) THEN
                GOTO Verder;

          { RWI 950625: deze vergelijkingen kunnen een ietwat minder,   }
          {             maar ik weet nog niet zeker of 1:* nou evenveel }
          {             match is als * alleen.                          }
          Match:=0;

          IF (Tmp^.Address.Zone = 65535) THEN                { * }
             Match:=1
          ELSE
              IF (Tmp^.Address.Zone = Adres.Zone) THEN
              BEGIN
                   Match:=2;

                   IF (Tmp^.Address.Net = 65535) THEN      { Z:* }
                      Match:=2
                   ELSE
                       IF (Tmp^.Address.Net = Adres.Net) THEN
                       BEGIN
                            Match:=3;

                            IF (Tmp^.Address.Node = 65535) THEN  { Z:N/* }
                               Match:=3
                            ELSE
                                IF (Tmp^.Address.Node = Adres.Node) THEN
                                BEGIN
                                     Match:=4;

                                     IF (Tmp^.Address.Point = 65535) THEN  { Z:N/F.* }
                                        Match:=4
                                     ELSE
                                         IF (Tmp^.Address.Point = Adres.Point) THEN
                                            Match:=5
                                         ELSE
                                             Match:=0;

                                END ELSE
                                    Match:=0;
                       END ELSE
                           Match:=0;
              END ELSE
                  Match:=0;

          IF (Match > HighMatch) THEN
          BEGIN
               HighMatch:=Match;
               Reason:=Fido2Str (Adres); { RAWI 980221: report failed address }
               {Reason:=Fido2Str (Tmp^.Address); { just the address }
          END;

     Verder:
          Tmp:=Gateway.GetNextItem;
     END; { while }

     { run the reason through the language entry }
     Reason:=GetLang1 (125,Reason);

     CheckAccess:=HighMatch;
END;


{--------------------------------------------------------------------------}
{ CheckGateway                                                             }
{                                                                          }
{ Checks whether a certain user is allowed to use the gateway based on the }
{ ALLOW-FIDO and FORBID-FIDO statements. Returns TRUE when the user is     }
{ allowed to use the gateway and FALSE when not allowed to gate.           }
{                                                                          }
FUNCTION CheckGateway (Adres : FidoAddrType; Name : STRING; VAR Reason : STRING) : BOOLEAN;

VAR Yes,No : BYTE;

BEGIN
     Name:=UpCaseString (DeleteBackSpaces (Name));

     Yes:=CheckAccess (Adres,Name,GatewayAccess,Reason);
     No:=CheckAccess (Adres,Name,GatewayRestrict,Reason);

     IF (No = 0) AND (Yes = 0) THEN    { not Found }
     BEGIN
          CheckGateway:=TRUE;
          Exit; { met TRUE -> allowed to use }
     END;

     IF (No = 5) THEN                   { 100 % denied }
        CheckGateWay:=FALSE
     ELSE
         IF (Yes = 5) THEN              { 100 % accepted }
            CheckGateWay:=TRUE
         ELSE
             CheckGateway:=(Yes > No);  { More yes then no? }
                                        { 2:280/* > 2:*     }
END;


{--------------------------------------------------------------------------}
{ JunkGatewayChecks                                                        }
{                                                                          }
PROCEDURE JunkGatewayChecks;
BEGIN
     GatewayAccess.Clear;
     GatewayRestrict.Clear;
END;


{--------------------------------------------------------------------------}
{ unit initialization                                                      }
{                                                                          }
BEGIN
     GatewayAccess.Init (Sizeof (GatewayList),NIL);
     GatewayRestrict.Init (Sizeof (GatewayList),NIL);
END.
