home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* CRYPTFIL.MOD *)
- (* Verschlüsselt Files nach FEAL 2.0 *)
- (* (c) 1989 Ralf Hensmann & TOOLBOX *)
- (* ------------------------------------------------------ *)
- MODULE CryptFile;
-
- FROM Lib IMPORT Dos, Sound, Delay, NoSound, FatalError,
- Fill, ParamCount, ParamStr;
- FROM IO IMPORT RdStr, WrChar, WrStr, WrLn, RdKey,
- KeyPressed;
- FROM FEAL IMPORT KeyStr, SetKey, Crypt, DeCrypt;
- FROM Str IMPORT Length, Caps, Slice, Concat, Compare;
- FROM FIO IMPORT Open, Create, Close, Erase, Rename, Size,
- Seek, DirEntry, RdBin, WrBin, File,
- FileAttr, PathTail, readonly, system,
- ReadFirstEntry, ReadNextEntry;
-
- FROM SYSTEM IMPORT Registers, Seg, Ofs, CarryFlag;
-
- CONST StartK = "F2"; (* Beginn des verschlüsselten *)
- (* Files zur Erkennung. *)
- (* Beliebig lang *)
- StartLen = SIZE(StartK) - 1;
- Kennung = "Fx"; (* 2 Buchstaben, um korrektes *)
- (* Passwort zu erkennen *)
- MaxBuf = 5120; (* Puffergröße = 8*MaxBuf *)
- Schreiben = 1; (* Für Sattr *)
- Lesen = 0; (* " *)
-
- TYPE Bit64 = SET OF [0..63];
- (* [1..64] --> SIZE = 9 Bytes ! *)
- THeader = RECORD
- H : ARRAY [1..2] OF CHAR;
- (* Für Kennung *)
- date,
- time : CARDINAL;
- attr : FileAttr;
- (* Werte des Original-Files *)
- R : SHORTCARD;
- (* Anzahl der überflüssigen Bytes am Ende *)
- END;
-
- VAR Buffer : ARRAY [0..MaxBuf-1] OF Bit64;
- (* Datenpuffer *)
- Signature : Bit64; (* Quersumme als Check *)
- Pass : ARRAY [0..23] OF CHAR; (* Passwort *)
- Filename,
- Pathname,
- Outname : ARRAY [1..80] OF CHAR; (* Dateinamen *)
- In, Out : File;
- Head,
- HilfHead : THeader;
- Chk : ARRAY [1..StartLen] OF CHAR;
- (* Für StartK-Vergleich *)
- Lauf,
- Gelesen : CARDINAL;
- DoCrypt : CHAR;
- S, LongLauf: LONGCARD;
- HilfBuf,
- HilfB : Bit64; (* Für CBC-Modus als Übertrag *)
- Dir : DirEntry;
- NoAttr,
- SecAttr : FileAttr;
- (* SecAttr: Attribute, die die geschützte *)
- (* Datei tragen soll *)
- (* (am Anfang initialisiert) *)
- Done : ARRAY [0..400] OF PathTail;
- DoneLast : CARDINAL;
-
- PROCEDURE Beep;
- BEGIN
- Sound(800); Delay(100); NoSound; Delay(30);
- END Beep;
-
- PROCEDURE GetKey(P1, P2, P3 : CHAR) : CHAR;
- VAR
- Ch : CHAR;
- BEGIN
- REPEAT
- Ch := RdKey(); Caps(Ch);
- UNTIL (Ch = P1) OR (Ch = P2) OR (Ch = P3);
- WrChar(Ch); WrLn;
- RETURN Ch;
- END GetKey;
-
- PROCEDURE Sattr(VAR Name : ARRAY OF CHAR;
- VAR attr : FileAttr;
- Set : SHORTCARD );
- (* Liest/Setzt Attribute von Files *)
- VAR
- R : Registers;
- BEGIN
- R.DS := Seg(Name);
- R.DX := Ofs(Name);
- R.CX := VAL(CARDINAL, SHORTCARD(attr));
- R.AL := Set;
- R.AH := 43H;
- Dos(R);
- IF CarryFlag IN R.Flags THEN
- FatalError("Fehler bei Attribut-Setzen");
- END;
- IF Set = 0 THEN
- attr := FileAttr(R.CX);
- END;
- END Sattr;
-
- PROCEDURE dt( F : File;
- VAR date,time : CARDINAL;
- Set : SHORTCARD );
- (* Liest/Setzt Datum und Zeit von Files *)
- VAR
- R : Registers;
- BEGIN
- R.BX := F;
- R.AL := Set;
- R.AH := 57H;
- R.CX := time;
- R.DX := date;
- Dos(R);
- IF CarryFlag IN R.Flags THEN
- FatalError("Falsche KanalNummer");
- END;
- IF Set = 0 THEN
- time := R.CX;
- date := R.DX;
- END;
- END dt;
-
- PROCEDURE RdKeyword(VAR Key : ARRAY OF CHAR);
- VAR
- Sp : CARDINAL;
- Ch : CHAR;
- BEGIN
- Sp := 0;
- LOOP
- Ch := RdKey();
- CASE Ch OF
- 0C : WHILE KeyPressed() DO
- Ch := RdKey();
- END;
- | CHR(8) : IF Sp > 0 THEN (* Buchstaben löschen *)
- DEC( Sp );
- WrStr(CHR(8) + " " + CHR(8));
- END;
- | CHR(13) : IF Sp >= 5 THEN
- Key[Sp] := 0C;
- WrLn;
- RETURN;
- ELSE
- Beep;
- END;
- | " ".."~" : IF Sp <= HIGH(Key) THEN
- WrChar("*");
- Key[Sp] := Ch;
- INC(Sp);
- ELSE
- Beep;
- END;
- END;
- END;
- END RdKeyword;
-
- PROCEDURE GetPassWord(V : BOOLEAN);
- VAR
- VerifyPass : ARRAY [0..23] OF CHAR;
- Lauf, Hilf : CARDINAL;
- BEGIN
- LOOP
- WrStr("Passwort (mind. 6 Buchstaben): ");
- RdKeyword(Pass);
- IF NOT V THEN EXIT END;
- WrStr("Passwort verifizieren : ");
- RdKeyword(VerifyPass);
- IF Compare(Pass, VerifyPass) = 0 THEN EXIT END;
- Beep; WrStr("Passwörter sind verschieden"); WrLn;
- END;
- Hilf := Length(Pass) + 1;
- FOR Lauf := Hilf TO 23 DO
- Pass[Lauf] := Pass[Lauf-Hilf];
- (* Passwort erweitern *)
- END;
- (* Passwort verschlüsseln *)
- SetKey(KeyStr(Pass[16])); Crypt(ADR(Pass[ 8]));
- SetKey(KeyStr(Pass[ 8])); Crypt(ADR(Pass[ 0]));
- SetKey(KeyStr(Pass[ 0]));
- END GetPassWord;
-
- BEGIN (* Hauptprogramm *)
- NoAttr := FileAttr{}; SecAttr := FileAttr{readonly};
- DoneLast := 0;
-
- WrStr(" FEAL 2.0 Verschlüsselungsprogramm "); WrLn;
- WrStr(" 1989 Ralf Hensmann & TOOLBOX "); WrLn; WrLn;
- WrStr(" Datei: ");
- IF ParamCount() = 1 THEN
- ParamStr(Filename, 1); WrStr(Filename);
- ELSE
- RdStr(Filename);
- END;
- WrLn; WrLn;
- WrStr("V(erschlüsseln, E(ntschlüsseln, Q(uit? ");
- DoCrypt := GetKey("V", "E", "Q");
- IF DoCrypt = "Q" THEN HALT END;
-
- IF DoCrypt = "V" THEN GetPassWord(TRUE);
- ELSE GetPassWord(FALSE) END;
-
- IF NOT ReadFirstEntry(Filename,
- FileAttr{readonly..system}, Dir) THEN
- HALT END;
- Done[0] := Dir.Name;
- Lauf := Length(Filename);
- WHILE (Lauf > 0) AND (Filename[Lauf] # "\") AND
- (Filename[Lauf] # ":") DO
- DEC(Lauf);
- END;
- Slice(Pathname, Filename, 0, Lauf);
- Concat(Filename, Pathname, Dir.Name);
-
- LOOP
- LOOP
- WrStr(" Name des Files : "); WrStr(Filename); WrLn;
- Concat(Outname, Pathname, "CRYPT$$$.TMP");
-
- Sattr(Filename, Head.attr, Lesen);
- Sattr(Filename, NoAttr, Schreiben);
-
- In := Open(Filename);
- Out := Create(Outname);
- S := Size(In);
- HilfBuf := Bit64{};
-
- IF DoCrypt = "V" THEN
- LongLauf := S;
- Head.H := Kennung;
- Head.R := (8 - SHORTCARD(S MOD 8)) MOD 8;
- dt(In, Head.date, Head.time, Lesen);
- Crypt(ADR(Head));
- WrBin(Out, StartK, StartLen);
- WrBin(Out, Head, SIZE(Head));
- WrBin(Out, Signature, SIZE(Signature));
- Signature := Bit64{};
- REPEAT
- Gelesen := RdBin(In, Buffer, SIZE(Buffer));
- DEC(S, LONGCARD(Gelesen));
- Gelesen := (Gelesen + 7) DIV 8;
- Signature := Signature / Buffer[0];
- Buffer[0] := Buffer[0] / HilfBuf;
- Crypt(ADR(Buffer[0]));
- FOR Lauf := 1 TO Gelesen-1 DO
- Signature := Signature / Buffer[Lauf];
- Buffer[Lauf] := Buffer[Lauf] / Buffer[Lauf-1];
- Crypt(ADR(Buffer[Lauf]));
- END;
- HilfBuf := Buffer[Gelesen-1];
- WrBin(Out, Buffer, 8 * Gelesen);
- UNTIL S = 0;
- Crypt(ADR(Signature));
- Seek(Out, StartLen+SIZE(Head));
- WrBin(Out, Signature, SIZE(Signature));
- S := LongLauf;
- Seek(In, 0);
- (* --- Altes File überschreiben --- *)
- Fill(ADR(Buffer), SIZE(Buffer), 0F6H);
- FOR LongLauf := 1 TO S DIV SIZE(Buffer) DO
- WrBin(In, Buffer, SIZE(Buffer));
- END;
- WrBin(In, Buffer, CARDINAL(S MOD SIZE(Buffer)));
- ELSE
- Gelesen := RdBin(In, Chk, StartLen);
- IF Compare(Chk , StartK) # 0 THEN
- Close(In); Close(Out); Erase(Outname);
- WrStr
- ("Datei nicht mit diesem Programm verschlüsselt.");
- WrLn; EXIT;
- END;
- Gelesen := RdBin(In, HilfHead, SIZE(Head));
- REPEAT
- Head := HilfHead;
- DeCrypt(ADR(Head));
- IF Compare(Head.H,Kennung) # 0 THEN
- Beep;
- WrStr("Passwort falsch ! Neuer Versuch ? ");
- IF GetKey("J", "Y", "N") = "N" THEN
- Close(In); Close(Out); Erase(Outname); EXIT;
- END;
- GetPassWord(FALSE);
- END;
- UNTIL Compare(Head.H,Kennung) = 0;
- Gelesen := RdBin(In, Signature, SIZE(Signature));
- DeCrypt(ADR( Signature));
- DEC(S, SIZE(Signature) + SIZE(Head) + StartLen);
- REPEAT
- Gelesen := RdBin(In, Buffer, SIZE(Buffer));
- DEC(S, LONGCARD(Gelesen));
- FOR Lauf := 0 TO (Gelesen DIV 8) - 1 DO
- HilfB := Buffer[Lauf];
- DeCrypt(ADR(Buffer[Lauf]));
- Buffer[Lauf] := Buffer[Lauf] / HilfBuf;
- Signature := Signature / Buffer[Lauf];
- HilfBuf := HilfB;
- END;
- IF S = 0 THEN
- DEC(Gelesen, CARDINAL(Head.R));
- END;
- WrBin(Out, Buffer, Gelesen);
- UNTIL S = 0;
- dt(Out, Head.date, Head.time, Schreiben);
- IF Signature # Bit64{} THEN
- Beep; Beep; Beep;
- WrStr( " **********************************" );
- WrLn;
- WrStr( " *** Datei wurde geändert ***" );
- WrLn;
- WrStr( " *** wahrscheinlich unbenutzbar ***" );
- WrLn;
- WrStr( " **********************************" );
- WrLn;
- Delay(400);
- Beep; Beep; Beep;
- END;
- END;
- Close(In); Close(Out);
- Erase(Filename); Rename(Outname, Filename);
- IF DoCrypt = "V" THEN
- Sattr(Filename, SecAttr, Schreiben);
- ELSE
- Sattr(Filename, Head.attr, Schreiben);
- END;
- EXIT;
- END;
- REPEAT
- IF NOT ReadNextEntry(Dir) THEN EXIT END;
- Lauf := 0;
- WHILE (Lauf<=DoneLast) AND
- (Compare(Dir.Name, Done[Lauf]) # 0) DO
- INC(Lauf);
- END;
- UNTIL Lauf > DoneLast;
- INC(DoneLast); Done[DoneLast] := Dir.Name;
- Concat(Filename, Pathname, Dir.Name);
- END;
- END CryptFile.
- (* ------------------------------------------------------ *)
- (* Ende von CRYPTFIL.MOD *)