home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
monitors
/
rsys
/
source.lha
/
src
/
RSysCrypt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-09
|
21KB
|
769 lines
/*
***************************************************************************
*
* Datei:
* RSysCrypt.c
*
* Inhalt:
* int OpenCryptWindow(void);
* void CryptFile(void);
*
* Bemerkungen:
* Verschlüsselungsroutinen von RSys.
*
* Erstellungsdatum:
* 07-Jul-93 Rolf Böhme
*
* Änderungen:
* 07-Jul-93 Rolf Böhme Erstellung
*
***************************************************************************
*/
#include "RSysFunc.h"
#include "RSysDebug.h"
/*
* Standardtyp der Verschlüsselungart.
*/
static int type = CRY;
static enum
{
GD_SourceStrGad,
GD_CryptStrGad,
GD_SelSourceGad,
GD_SelDestGad,
GD_CryptGad,
GD_DeccryptGad,
GD_PwdGad,
GD_TypeCYGad
};
#define Crypt_CNT 8
/*
* Die Intuition-Objekte für den Aufbau des
* Crypt-Windows.
*/
static struct Window *CryptWnd = NULL;
static struct Gadget *CryptGList = NULL;
static struct Gadget *CryptGadgets[8];
static UWORD CryptLeft = 213;
static UWORD CryptTop = 76;
static UWORD CryptWidth = 278;
static UWORD CryptHeight = 76;
static UBYTE *CryptWdt = (UBYTE *) NAME " " VERSION " - Crypting Files";
/*
* Diese Datei-lokale Struktur beinhaltet die Namen
* der Original- und der verschlüsselten Datei, sowie
* das Paßwort im Falle der Verschlüsselung mit dem
* "zellulären Automaten".
*/
static struct _cryptdata
{
char cr_datafile[MAXFULLNAME],
cr_cryptfile[MAXFULLNAME],
cr_pwd[20];
} cd =
{
"", "", "tiger"
};
static UBYTE *TypeCYGad0Labels[] = {
(UBYTE *)"Crypt",
(UBYTE *)"ROT 13",
NULL };
static UWORD CryptGTypes[] = {
STRING_KIND,
STRING_KIND,
BUTTON_KIND,
BUTTON_KIND,
BUTTON_KIND,
BUTTON_KIND,
STRING_KIND,
CYCLE_KIND
};
static struct NewGadget CryptNGad[] = {
66, 5, 132, 13, (UBYTE *)"Source", NULL, GD_SourceStrGad, PLACETEXT_LEFT, NULL, NULL,
66, 19, 132, 13, (UBYTE *)"Dest", NULL, GD_CryptStrGad, PLACETEXT_LEFT, NULL, NULL,
204, 5, 69, 13, (UBYTE *)"Select", NULL, GD_SelSourceGad, PLACETEXT_IN, NULL, NULL,
204, 19, 69, 13, (UBYTE *)"Select", NULL, GD_SelDestGad, PLACETEXT_IN, NULL, NULL,
98, 59, 81, 13, (UBYTE *)"Encrypt", NULL, GD_CryptGad, PLACETEXT_IN, NULL, NULL,
192, 59, 81, 13, (UBYTE *)"Decrypt", NULL, GD_DeccryptGad, PLACETEXT_IN, NULL, NULL,
66, 39, 207, 13, (UBYTE *)"Passwd", NULL, GD_PwdGad, PLACETEXT_LEFT,NULL,NULL,
4, 59, 81, 13, NULL, NULL, GD_TypeCYGad, 0, NULL, NULL
};
static ULONG *CryptGTags[] = {
(ULONG *)(GTST_MaxChars), (ULONG *)MAXLINESIZE, (ULONG *)(TAG_DONE),
(ULONG *)(GTST_MaxChars), (ULONG *)MAXLINESIZE, (ULONG *)(TAG_DONE),
(ULONG *)(TAG_DONE),
(ULONG *)(TAG_DONE),
(ULONG *)(TAG_DONE),
(ULONG *)(TAG_DONE),
(ULONG *)(GTST_MaxChars), (ULONG *)256, (ULONG *)(TAG_DONE),
(ULONG * )(GTCY_Labels), (ULONG *)&TypeCYGad0Labels[ 0 ], (ULONG *)(TAG_DONE)
};
/*
* Die Prozedur WindTitleInfo() läßt eine Nachricht in
* der Titelzeile des Crypt-Fensters erscheinen.
*/
static void
WindTitleInfo(char *msg)
{
SetWindowTitles(CryptWnd,(UBYTE *)(msg),(UBYTE *)(-1));
return;
}
/*
* OpenCryptWindow() öffnet ein Fenster mit allen Kontrollelementen
*/
int
OpenCryptWindow( void )
{
struct NewGadget ng;
struct Gadget *g;
UWORD lc, tc;
UWORD wleft = CryptLeft, wtop = CryptTop, ww, wh;
int gl[] = {0,1,6};
DPOS;
ComputeFont( Scr,CryptWidth, CryptHeight );
ww = ComputeX( CryptWidth );
wh = ComputeY( CryptHeight );
if (( wleft + ww + OffX + Scr->WBorRight ) > Scr->Width ) wleft = Scr->Width - ww;
if (( wtop + wh + OffY + Scr->WBorBottom ) > Scr->Height ) wtop = Scr->Height - wh;
ww = compute((UWORD) (OffX + Scr->WBorRight), FontX, (int)CryptWidth);
wh = compute((UWORD) (OffY + Scr->WBorBottom), FontY, (int)CryptHeight);
CenterWindow(Scr, &wtop, &wleft, ww, wh);
if ( ! ( g = CreateContext( &CryptGList )))
return( 1L );
for( lc = 0, tc = 0; lc < Crypt_CNT; lc++ ) {
CopyMem((char * )&CryptNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));
ng.ng_VisualInfo = VisualInfo;
ng.ng_TextAttr = Font;
ng.ng_LeftEdge = OffX + ComputeX( ng.ng_LeftEdge );
ng.ng_TopEdge = OffY + ComputeY( ng.ng_TopEdge );
ng.ng_Width = ComputeX( ng.ng_Width );
ng.ng_Height = ComputeY( ng.ng_Height);
CryptGadgets[ lc ] = g = CreateGadgetA((ULONG)CryptGTypes[ lc ], g, &ng, ( struct TagItem * )&CryptGTags[ tc ] );
makelabelvisible(CryptGadgets[lc]);
while( CryptGTags[ tc ] ) tc += 2;
tc++;
if ( NOT g )
return( 2L );
}
if ( ! ( CryptWnd = OpenWindowTags( NULL,
WA_Left, wleft,
WA_Top, wtop,
WA_Width, ww,
WA_Height, wh,
WA_IDCMP, IDCMP_VANILLAKEY|
STRINGIDCMP|
BUTTONIDCMP|
IDCMP_CLOSEWINDOW|
IDCMP_REFRESHWINDOW,
WA_Flags, WFLG_DRAGBAR|
WFLG_DEPTHGADGET|
WFLG_CLOSEGADGET|
WFLG_SMART_REFRESH|
WFLG_ACTIVATE|
WFLG_RMBTRAP,
WA_Gadgets, CryptGList,
WA_Title, CryptWdt,
WA_PubScreenFallBack,TRUE,
WA_PubScreen, Scr,
TAG_DONE )))
return( 4L );
RefreshRastPort(CryptWnd,CryptGadgets,gl, 3);
if(Flags.autofront)
{
WindowToFront(CryptWnd);
ActivateWindow(CryptWnd);
}
return( 0L );
}
/*
* refreshstrgad() erneuert den Inhalt eines Stringgadgets
*/
static void
refreshstrgad(struct Gadget *gad, char *str)
{
GT_SetGadgetAttrs(gad, CryptWnd, NULL,
GTST_String, (UBYTE *) str,
TAG_DONE);
return;
}
/*
* Die nächsten Kommentare sind dem Programm-Quelltext von TERM entnommen.
* Olsen, danke für die Comments :-)
*/
/*
* The width of the cell ring is defined here. A word of warning: never
* encrypt a file and forget the access password, since it will be
* extremely hard to break the code (with 30 cells there are 256^30
* possible values each cell may be initialized to which means that
* you could have to try more than 1.7e+72 combinations for each single
* password character before actually finding the matching password).
* See `Random sequence generation by cellular automata' by Steven
* Wolfram (Institute for Advanced Study; Advances in Applied
* Mathematics) for more information.
*/
#define CELL_WIDTH 30
/*
* The cell ring and the ring index pointers.
*/
static UBYTE Cell[2][CELL_WIDTH + 2],
From,
To;
/*
* Automaton():
*
* A cellular automaton working on a ring of celles, producing
* random data in each single cell .
*/
static UBYTE
Automaton(void)
{
register WORD i;
/*
* Operate on the cell ring...
*/
for (i = 1; i <= CELL_WIDTH; i++)
Cell[To][i] = Cell[From][i - 1] ^ (Cell[From][i] | Cell[From][i + 1]);
/*
* Operate on first and last element.
*/
Cell[To][0] = Cell[From][CELL_WIDTH + 1] ^ (Cell[From][0] | Cell[From][1]);
Cell[To][CELL_WIDTH + 1] = Cell[From][CELL_WIDTH] ^ (Cell[From][CELL_WIDTH + 1] | Cell[From][0]);
/*
* Swap cell rings.
*/
To = From;
From ^= 1;
/*
* Return contents of first cell.
*/
return (Cell[From][0]);
}
/*
* Encrypt(UBYTE *Source,UBYTE *Destination,UBYTE *Key):
* Encrypt data using cellular automaton as a random number generator.
*/
static UBYTE *
Encrypt(UBYTE * Source, long SourceLen, UBYTE * Destination, UBYTE * Key, WORD KeyLen)
{
register long i,
j;
/*
* Set up cell ring index pointers.
*/
From = 0;
To = 1;
/*
* Initialize the cell ring with the key contents.
*/
for (i = 0, j = KeyLen - 1; i < CELL_WIDTH + 2; i++)
{
Cell[0][i] = Key[j];
if (j)
j--;
else
j = KeyLen - 1;
}
/*
* Encrypt the source data.
*/
for (i = 0; i < SourceLen; i++)
Destination[i] = (UBYTE) (((WORD) Source[i] + Automaton())% 256);
/*
* Return result.
*/
return (Destination);
}
/*
* Decrypt(UBYTE *Source,UBYTE *Destination,UBYTE *Key):
*
* Decrypt data using cellular automaton as a random number generator.
*/
static UBYTE *
Decrypt(UBYTE * Source, long SourceLen, UBYTE * Destination, UBYTE * Key, WORD KeyLen)
{
register long i,
j,
Code;
/*
* Set up cell ring index pointers.
*/
From = 0;
To = 1;
/*
* Initialize the cell ring with the key contents.
*/
for (i = 0, j = KeyLen - 1; i < CELL_WIDTH + 2; i++)
{
Cell[0][i] = Key[j];
if (j)
j--;
else
j = KeyLen - 1;
}
/*
* Decrypt the source data.
*/
for (i = 0; i < SourceLen; i++)
{
if ((Code = Source[i] - Automaton())< 0)
Code = 256 + Code;
Destination[i] = (UBYTE) Code;
}
return (Destination);
}
/*
* Die Prozedur MakeROT13() erzeugt aus einem
* Eingabestring buff eine Ausgabestring dest
* dergestalt, daß jeder Buchstabe um 13 Zeichen nach
* vorne oder hinten verschoben wird. Hier die
* Translationsliste:
*
* Input: abcdefghijklmnopqrstuvwxyz
* Output: nopqrstuvwxyzabcdefghijklm
*
* Input: ABCDEFGHIJKLMNOPQRSTUVWXYZ
* Output: NOPQRSTUVWXYZABCDEFGHIJKLM
*/
static void
MakeROT13(UBYTE * buff, UBYTE * dest)
{
UBYTE *destptr = &dest[0];
char ch;
strcpy((char *)dest, (char *)buff);
while (*destptr)
{
ch = (char)(*destptr);
if (isalpha((int)ch))
{
if (((ch >= 'A') && (ch < 'N')) ||
((ch >= 'a') && (ch < 'n')))
*destptr = (UBYTE) (ch + 13);
if (((ch >= 'N') && (ch <= 'Z')) ||
((ch >= 'n') && (ch <= 'z')))
*destptr = (UBYTE) (ch - 13);
}
destptr++;
}
return;
}
/*
* Crypt() ver- oder entschlüsselt eine Datei
*/
static void
Crypt(int encrypt)
{
long fsize;
char pwd[PWDLEN+1],
cpwd[PWDLEN+1];
BPTR Dfile,
Cfile;
UBYTE *Dbuffer,
*Cbuffer;
int pwdlen;
if (strlen(cd.cr_pwd) == 0)
strcpy(pwd, "tiger");
else
strncpy(pwd, cd.cr_pwd, PWDLEN);
pwdlen = strlen(pwd);
if (encrypt)
{
if (NOT(exist(cd.cr_datafile)))
{
ErrorHandle(FILE_ERR, EXIST_FAIL, NO_KILL);
return;
}
if (type == R13)
{
extern int global_type;
filetype(cd.cr_datafile);
if (global_type != TYPE_TEXT)
{
ErrorHandle(FILE_ERR, TYPE_FAIL, NO_KILL);
return;
}
}
fsize = SizeOfFile(cd.cr_datafile);
if (fsize == 0L)
{
ErrorHandle(FILE_ERR, SIZE_FAIL, NO_KILL);
return;
}
if (exist(cd.cr_cryptfile) &&
NOT(Question(CryptWnd, "Crypt file exist!\n"
"Do you want to overwrite them?", YES)))
return;
if (Dfile = Open((UBYTE *) cd.cr_datafile, MODE_OLDFILE))
{
if (Cfile = Open((UBYTE *) cd.cr_cryptfile, MODE_NEWFILE))
{
if ((Dbuffer = MyAllocVec((fsize + 1) * sizeof(UBYTE), MEMF_CLEAR, NO_KILL)) &&
(Cbuffer = MyAllocVec((fsize + 1) * sizeof(UBYTE), MEMF_CLEAR, NO_KILL)))
{
WindTitleInfo("Reading datafile...");
if (fsize == Read(Dfile, Dbuffer, fsize))
{
if (NOT(type))
{
WindTitleInfo("Encrypt password...");
Encrypt((UBYTE *) pwd, (long) pwdlen, (UBYTE *) cpwd,
(UBYTE *) pwd, (WORD) pwdlen);
if (pwdlen != Write(Cfile, cpwd, pwdlen))
ErrorHandle(FILE_ERR, WRITE_FAIL, NO_KILL);
else
{
WindTitleInfo("Encrypt data file...");
Cbuffer = Encrypt(Dbuffer, (long)fsize,
Cbuffer, (UBYTE *) pwd, (WORD) pwdlen);
}
}
else
{
WindTitleInfo("Rotate data file...");
MakeROT13(Dbuffer, Cbuffer);
}
WindTitleInfo(type ? "Writing ROT13 file..." : "Writing crypt file...");
if (fsize != Write(Cfile, Cbuffer, fsize))
ErrorHandle(FILE_ERR, WRITE_FAIL, NO_KILL);
}
else
ErrorHandle(FILE_ERR, READ_FAIL, NO_KILL);
MyFreeVec(Cbuffer);
MyFreeVec(Dbuffer);
}
Close(Cfile);
}
else
ErrorHandle(FILE_ERR, OPEN_FAIL, NO_KILL);
Close(Dfile);
}
else
ErrorHandle(FILE_ERR, OPEN_FAIL, NO_KILL);
}
else
{
if (NOT(exist(cd.cr_cryptfile)))
{
ErrorHandle(FILE_ERR, EXIST_FAIL, NO_KILL);
return;
}
fsize = SizeOfFile(cd.cr_cryptfile);
if (fsize == 0L)
{
ErrorHandle(FILE_ERR, SIZE_FAIL, NO_KILL);
return;
}
if (exist(cd.cr_datafile) &&
NOT(Question(CryptWnd, "Data file exist!\n"
"Do you want to overwrite them?", YES)))
return;
if (Dfile = Open((UBYTE *) cd.cr_datafile, MODE_NEWFILE))
{
if (Cfile = Open((UBYTE *) cd.cr_cryptfile, MODE_OLDFILE))
{
if ((Dbuffer = MyAllocVec((fsize + 1) * sizeof(UBYTE), MEMF_CLEAR, NO_KILL)) &&
(Cbuffer = MyAllocVec((fsize + 1) * sizeof(UBYTE), MEMF_CLEAR, NO_KILL)))
{
WindTitleInfo(type ? "Reading ROT13 file..." : "Reading crypt file...");
if (fsize == Read(Cfile, Cbuffer, fsize))
{
if (NOT(type))
{
WindTitleInfo("Decrypt password...");
strncpy(cpwd, (char *)Cbuffer, pwdlen);
Decrypt((UBYTE *) cpwd, (long)pwdlen,
(UBYTE *) pwd, (UBYTE *) pwd, (WORD) pwdlen);
if (strcmp(cd.cr_pwd, pwd))
ErrorHandle(MISC_ERR, WRONG_FAIL, NO_KILL);
else
{
WindTitleInfo("Decrypt crypt file...");
Dbuffer = Decrypt(&Cbuffer[pwdlen], (long)(fsize - pwdlen),
Dbuffer, (UBYTE *) pwd, (WORD) pwdlen);
}
}
else
{
WindTitleInfo("Derotate ROT13-File...");
MakeROT13(Cbuffer, Dbuffer);
}
WindTitleInfo("Writing data file...");
fsize -= (type ? 0 : pwdlen);
if (fsize != Write(Dfile, Dbuffer, fsize))
ErrorHandle(FILE_ERR, WRITE_FAIL, NO_KILL);
}
else
ErrorHandle(FILE_ERR, READ_FAIL, NO_KILL);
MyFreeVec(Cbuffer);
MyFreeVec(Dbuffer);
}
Close(Cfile);
}
else
ErrorHandle(FILE_ERR, OPEN_FAIL, NO_KILL);
Close(Dfile);
}
else
ErrorHandle(FILE_ERR, OPEN_FAIL, NO_KILL);
}
WindTitleInfo((char *)CryptWdt);
return;
}
/*
* CryptFile() bietet eine kleine Benutzeroberfläche an und
* kontrolliert die Ein- und Ausgabedateien sowie das Paßwort
*/
void
CryptFile(void)
{
register struct IntuiMessage *message;
ULONG class,
code;
APTR object;
APTR req = NULL,reqcrypt = NULL;
char *gadbuff;
DPOS;
Flags.quit_cr = 0;
cd.cr_datafile[0] = STRINGEND;
cd.cr_cryptfile[0] = STRINGEND;
strcpy(cd.cr_pwd,"tiger");
if (OpenASysWindow(OpenCryptWindow,NO_KILL))
{
if (SysWnd)
req = LockWindow(SysWnd);
refreshstrgad(CryptGadgets[GD_SourceStrGad],cd.cr_datafile);
refreshstrgad(CryptGadgets[GD_CryptStrGad],cd.cr_cryptfile);
refreshstrgad(CryptGadgets[GD_PwdGad],cd.cr_pwd);
do
{
Wait(1L << CryptWnd->UserPort->mp_SigBit);
while ((message = (struct IntuiMessage *)
GT_GetIMsg(CryptWnd->UserPort)) != NULL)
{
object = message->IAddress;
class = message->Class;
code = message->Code;
GT_ReplyIMsg(message);
switch (class)
{
case IDCMP_GADGETUP:
switch (((struct Gadget *) object)->GadgetID)
{
case GD_SourceStrGad:
gadbuff = gadgetbuff(CryptGadgets[GD_SourceStrGad]);
strncpy(cd.cr_datafile, gadbuff, MAXFULLNAME);
strncpy(cd.cr_cryptfile, gadbuff, MAXFULLNAME);
strcat(cd.cr_cryptfile, (type ? ".ROT" : ".CPT"));
refreshstrgad(CryptGadgets[GD_CryptStrGad],
cd.cr_cryptfile);
break;
case GD_CryptStrGad:
gadbuff = gadgetbuff(CryptGadgets[GD_CryptStrGad]);
strncpy(cd.cr_cryptfile, gadbuff, MAXFULLNAME);
break;
case GD_SelSourceGad:
if (GetFile(CryptWnd,NULL,NULL,NULL,
"Select File to crypt","Select"))
{
strncpy(cd.cr_datafile,(char *)_fullpath,
MAXFULLNAME);
strncpy(cd.cr_cryptfile,(char *)_fullpath,
MAXFULLNAME-4);
strcat(cd.cr_cryptfile, (type ? ".ROT" : ".CPT"));
refreshstrgad(CryptGadgets[GD_SourceStrGad],
cd.cr_datafile);
refreshstrgad(CryptGadgets[GD_CryptStrGad],
cd.cr_cryptfile);
}
break;
case GD_SelDestGad:
if (GetFile(CryptWnd,NULL,NULL,
(type ? "#?.ROT" :"#?.CPT"),
(type ? "Select ROT13 file" :"Select Crypt file"),
"Select"))
{
strncpy(cd.cr_cryptfile, (char *)_fullpath,MAXFULLNAME);
refreshstrgad(CryptGadgets[GD_CryptStrGad],
cd.cr_cryptfile);
}
break;
case GD_CryptGad:
reqcrypt = LockWindow(CryptWnd);
Crypt(TRUE);
if(reqcrypt)
UnlockWindow(reqcrypt);
break;
case GD_DeccryptGad:
reqcrypt = LockWindow(CryptWnd);
Crypt(FALSE);
if(reqcrypt)
UnlockWindow(reqcrypt);
break;
case GD_PwdGad:
strncpy(cd.cr_pwd, gadgetbuff(CryptGadgets[GD_PwdGad]), 20);
break;
case GD_TypeCYGad:
type = (int)code;
GT_SetGadgetAttrs(CryptGadgets[GD_PwdGad], CryptWnd,
NULL,
GA_Disabled, type,
TAG_DONE);
if(cd.cr_datafile[0])
{
strncpy(cd.cr_cryptfile, cd.cr_datafile, MAXFULLNAME-4);
strcat(cd.cr_cryptfile, (type ? ".ROT" : ".CPT"));
refreshstrgad(CryptGadgets[GD_CryptStrGad],
cd.cr_cryptfile);
}
break;
}
break;
case IDCMP_VANILLAKEY:
if (code == '\33')
Flags.quit_cr = 1;
break;
case IDCMP_CLOSEWINDOW:
Flags.quit_cr = 1;
break;
}
}
}
while (NOT(Flags.quit_cr));
CloseASysWindow(&CryptWnd, &CryptGList, NULL);
if (SysWnd)
{
UnlockWindow(req);
RefreshMainWindowPattern();
RefreshList(LastID);
}
}
return;
}