/* * Jubal's encrypting tool * * This program reads in a file and: * decrypts the file if it ends in EXTENSION (#defined below) * encrypts the file otherwise * The encryption is done by rotating with a key that the user selects * The first lines of the file are the header * Then, the next line is the key encrypted with crypt() (for checking keys) * After that is the data. * * This is a bin/ type command. To invoke it, call the function main() * * Enjoy, Jubal (Dave Ljung, DaveSource.com/GetDave.com) */ /* * This program has been successfully ported to the following drivers: * 2.4.5, 3.1.2, 3.1.2 -DR, 3.1.2 -CD and 3.2 (amylaar) * * This code is copyright 1993, David Ljung Madison (DaveSource.com/GetDave.com) * * It may be freely redistributed, but it may not be sold in any form. */ /* consideration: make the write_file a diff. function * and then do a call_out to help take care of too long eval error (big files) * This won't work on most systems, because call_outs often can't do file I/O */ #define MAX_ARRAY 1000 /* last character of header MUST be '\n' */ /* Don't change the HEADER or else you won't be able to uncrypt files! */ #define HEADER "\ This file was created by Jubal's 'crypt' program\n\ Please do not alter it in ANY way as this will destroy the contents\n\ -------------------------------------------------------------------\n" /* filename extension */ #define EXTENSION ".x" /* don't touch this! :) */ #define CHARS ({"`","1","2","3","4","5","6","7","8","9","0","-","="," ", \ "q","w","e","r","t","y","u","i","o","p","[","]","\\","a","s","d","f","g","h", \ "j","k","l",";","'","z","x","c","v","b","n","m",",",".","/"," ","~","!","@", \ "#","$","%","^","&","*","(",")","_","+","Q","W","E","R","T","Y","U","I","O", \ "P","{","}","|","A","S","D","F","G","H","J","K","L",":","\"","Z","X","C","V", \ "B","N","M","<",">","?"}) /* global variables! Don't let two players use this command at once! */ string name,newname; int crypt,overwrite; string tmpkey; main(what) { int totlines,l; if(!what) return !notify_fail("Usage: crypt \n"); name=mk_path(what); l=file_size(name); if(l==-1) { if(file_size(name+EXTENSION)==-1) return write(name+" does not exist\n"), 1; name=name+EXTENSION; l=file_size(name); } if(l==-2) return write(name+" is a directory\n"), 1; if(l==0) return write(name+" is empty\n"), 1; l=strlen(name); if(name[l-strlen(EXTENSION)..l-1]==EXTENSION) { newname=name[0..l-strlen(EXTENSION)-1]; crypt=0; } else { newname=name+EXTENSION; crypt=1; } overwrite=0; write((crypt?"En":"De")+"crypting: " +name+" ("+(l/1000)+"."+(l-(l/1000*1000))+"k) to "+newname+"\n"); write("Key: "); if(!crypt) input_to("get_key2",1); else input_to("get_key1",1); return 1; } get_key1(key) { tmpkey=key; write("\nKey (again): "); input_to("get_key2",1); } get_key2(key) { int i,l; write("\n"); if(crypt && key!=tmpkey) { write("You changed!\n"); tmpkey=0; key=0; return 1; } tmpkey=0; if(file_crypt(key,!crypt,name,newname)) { if(!rm(name)) write("Couldn't remove file: "+name+"\n"); else write("Done.\n"); } key=0; return 1; } /* the encryption routine */ file_crypt(key,decrypt,name,newname) { int lines,len,i,j,s1,s2,c,k; string in,out,*chars,seed,hdr; chars=CHARS; s1=sizeof(chars); s2=strlen(key)-1; k=0; i=1; if(file_size(newname)!=-1) if(!overwrite) return write(newname+" already exists\n"), 0; else if(!rm(newname)) return write("Could not remove "+newname+"\n"), 0; if(!crypt) { hdr=explode(HEADER,"\n"); while(i<=sizeof(hdr)) { if(read_file(name,i)!=hdr[i-1]+"\n") return write("Corrupt header\n"), 0; i++; } in=read_file(name,i); if(crypt(key,in)!=in[0..strlen(in)-2]) return write("Wrong key\n"), 0; i++; } else { j=random(s1); if(chars[j]=="\n") j=5; seed=chars[j]; j=random(s1); if(chars[j]=="\n") j=6; seed+=chars[j]; if(!write_file(newname,HEADER+crypt(key,seed)+"\n")) return write("ERROR: writing header\n"), 0; } while(in=read_file(name,i)) { i++; len=strlen(in); out=""; for(j=0;j=s1) c-=s1; k=k+1>s2?0:k+1; out+=chars[c]; } } if(!write_file(newname,out)) return write("ERROR: writing line: "+i+" to: "+newname+"\n"), 0; } return 1; } /* this can be altered in many ways -- use valid_write, mk_path, whatever */ /* make sure it returns the prepending "/" */ mk_path(name) { /* resolve_path and prepending '/' for use on Virtual Realities */ return "/"+resolve_path(this_player()->query_path(),name); return this_player()->mk_path(name); }