/**************************************************************************** * mangler * v4.7 * * created: 12-2005 by fortschreiten (@gmail.com) * updated: 03-2006 by Israel Torres (@israeltorres.org) * * thanks are extended to cynric * * http://tools.israeltorres.org/mangler.php * * File encryption for educational/entertainment purposes only. ****************************************************************************/ /* Changelog: * 4.7 - 040106 - moved remove(), changed buf declaration back and added flags to work both in win32 and *nix * 4.6 - 033106 - added remove() when -pi passwords don't match - fortschreiten * 4.5 - 033106 - removed extra char in #ifdef for linux to fix buffer problem * 4.4 - 032906 - added formatting to match perl test * 4.3 - 032906 - linux buffer issue - fortschreiten * 4.2 - 032806 - linux buffer issue * 4.1 - 032806 - cosmetic changes, buffer * 4.0 - 032806 - param handling, functionality, ... a whole lot. * 3.6 - More massaging... * 3.5 - Massaged the linux side of things * 3.4 - Added linux/windows termios/conio compatibility * 3.3 - Added Interactive/Non-interactive distinction * 3.2 - Fixed buffer issue. * 3.1 - Interactive mode removed for batch file usage. * 3.1 - complete logic restructure, prototype, fucntions, define * 3.1 - Now works in Visual Studio 6 * 2.1 - Password/Key is a prompt instead of an option: * This is to keep them from being logged in something * such as a .bash_history. * 2.0 - Added keyfile option (-k) * 1.0 - Initial version. NOT XOR w/ password * ****************************************************************************/ #include #include #include #ifdef WIN32 #include #else #include #endif /* defines */ #define MAX_PATH 256 #define MAX_PARAM 4 #define MAX_PARAM_L 4 #define PARAM_FILENAME_S 0 /*Self Filename*/ #define PARAM_C_FUNCTION 1 /*Function*/ #define PARAM_FILENAME_I 2 /*Filename In*/ #define PARAM_FILENAME_O 3 /*Filename Out*/ #define PARAM_PASSW_KEYF 4 /*Password/KeyFile*/ /* Prototypes */ #ifdef WIN32 /**/ #else void echo_off(void); void echo_on(void); #endif void usage(char *prog); int crypt(int key_type, int interact, char in_filename[MAX_PATH], char out_filename[MAX_PATH], char key[MAX_PATH]); #ifdef WIN32 /**/ #else static struct termios stored_settings; #endif /* Functions */ #ifdef WIN32 /**/ #else /* Make characters typed "invisible" */ void echo_off(void) { struct termios new_settings; tcgetattr(0,&stored_settings); new_settings = stored_settings; new_settings.c_lflag &= (~ECHO); tcsetattr(0,TCSANOW,&new_settings); return; } void echo_on(void) { tcsetattr(0,TCSANOW,&stored_settings); return; } #endif void usage(char *prog) { printf("mangler 4.7 - mangle your file\n"); printf("http://tools.israeltorres.org/mangler.php\n\n"); printf("Usage: %s [-pn/-pi/-kn/-ki] input_file output_file [password/keyfile]\n", prog); printf("\t-pn Use a password (non-interactive)\n"); printf("\t-pi Use a password (interactive)\n"); printf("\t-kn Use keyfile (non-interactive)\n"); printf("\t-ki Use keyfile (interactive)\n"); exit(1); } int crypt(int key_type, int interact, char in_filename[MAX_PATH], char out_filename[MAX_PATH], char key[MAX_PATH]) { char keynew[MAX_PATH]="\0"; char keyconfirm[MAX_PATH]="\0"; char keytemp1[MAX_PATH]="\0"; char keytemp2[MAX_PATH]="\0"; int index_key = 0; int index_key_confirm = 0; int nFlag_remove = 0; FILE *infile, *outfile,*keyfile; int passposition = 0; /* Used to determine which letter of the key we're on */ int passmax = 0; /* Needed to determine when end of key is reached */ char read_byte; /* Byte read from the infile */ char modified_byte; /* Encrypted/Decrypted byte */ char keyfile_byte; /* Open input file */ if ((infile = fopen(in_filename,"rb")) == NULL) { printf("Error: Could not open %s for reading.\n", in_filename); exit(1); } /* Test if the file already exists so we don't overwrite anything important */ if(!((outfile = fopen(out_filename,"rb")) == NULL)) { printf("Error: File already exists: %s\n", out_filename); fclose(outfile); exit(1); } /* Open output file */ if((outfile = fopen(out_filename,"wb")) == NULL) { printf("Error: Cannot create file: %s\n", out_filename); exit(1); } /* Encrypt or decrypt the file with a password */ if (key_type == 0) { if (interact == 1) { #ifdef WIN32 /*Interactive password functions same as Non-interactive password*/ printf("Enter password (first): "); while (keytemp1[index_key - 1] != 13) { keytemp1[index_key] = getch(); if (keytemp1[index_key] != 13) { keynew[index_key] = keytemp1[index_key]; } printf("*"); index_key++; } printf("\n"); printf("Enter password (again): "); while (keytemp2[index_key_confirm - 1] != 13) { keytemp2[index_key_confirm] = getch(); if (keytemp2[index_key_confirm] != 13) { keyconfirm[index_key_confirm] = keytemp2[index_key_confirm]; } printf("*"); index_key_confirm++; } printf("\n"); if (strcmp(keynew,keyconfirm) != 0) { printf("Error: Passwords do not match.\n"); fclose(outfile); nFlag_remove = 1; } /* overwrite old key with new key */ strcpy(key,keynew); #else char buf[MAX_PATH]="\0"; printf("Enter password (first): "); echo_off(); scanf("%256s",key); printf("\n"); printf("Enter password (again): "); scanf("%256s",buf); echo_on(); printf("\n"); if (strcmp(key,buf) != 0) { printf("Error: Passwords do not match.\n"); fclose(outfile); nFlag_remove = 1; } #endif } else { /* Nothing */ } /* Check flag coming back from win32/*nix for interactive password match*/ if (nFlag_remove == 1) { if (remove(out_filename)) { fclose(outfile); printf("Error: could not remove %s\n", out_filename); } exit(1); } passmax = strlen(key); read_byte = getc(infile); while (!feof(infile)) { if (passposition == passmax) { passposition = 0; } /* Encrypt/Decrypt byte*/ modified_byte = ~(key[passposition] ^ read_byte); putc(modified_byte, outfile); passposition++; read_byte = getc(infile); } } /* Encrypt or decrypt the file with a keyfile */ if (key_type == 1) { if ((keyfile = fopen(key,"rb"))== NULL) { printf("Error: keyfile %s could not be opened.\n",key); exit(1); } keyfile_byte = getc(keyfile); read_byte = getc(infile); while (!feof(infile)) { if(feof(keyfile)) { rewind(keyfile); } /* Encrypt/Decrypt byte */ modified_byte = ~(keyfile_byte ^ read_byte); putc(modified_byte, outfile); keyfile_byte = getc(keyfile); read_byte = getc(infile); } } if (key_type == 1) { fclose(keyfile); } fclose(outfile); fclose(infile); return 0; } /* Main */ int main(int argc, char *argv[]) { /* Declar Variables for Usage */ char cfunction[MAX_PARAM]="\0"; char in_filename[MAX_PATH]="\0"; char out_filename[MAX_PATH]="\0"; char key[MAX_PATH]="\0"; int interact = 0; /*1=yes, 0=no */ int key_type = 0; /*1=keyfile, 0=password */ int nRtn = 0; /*0 = success, 1 = fail*/ int cflag = 0; /* automatic usage */ if (argc < MAX_PARAM_L) { usage(argv[PARAM_FILENAME_S]); } strcpy(in_filename, argv[PARAM_FILENAME_I]); strcpy(out_filename, argv[PARAM_FILENAME_O]); /* password or keyfile passing through */ if (argc == MAX_PARAM_L +1) { strcpy(key, argv[PARAM_PASSW_KEYF]); if (strcmp(key,"")==0) { printf("The password/keyfile cannot be blank\n"); exit(1); } } /* check param for correct 1 of 4 possible functions */ strcpy(cfunction, argv[PARAM_C_FUNCTION]); /* using non-interactive password */ if (strcmp(cfunction,"-pn")==0) { interact = 0; /* no interaction */ key_type = 0; /* password */ if (strcmp(key,"")==0) { printf("The password cannot be blank\n"); exit(1); } nRtn = crypt(key_type, interact, in_filename, out_filename, key); cflag = 1; } /* using interactive password */ if (strcmp(cfunction,"-pi")==0) { interact = 1; /* interaction */ key_type = 0; /* password */ nRtn = crypt(key_type, interact, in_filename, out_filename, key); cflag = 1; } /* using keyfile non-interactive*/ if (strcmp(cfunction,"-kn")==0) { interact = 0; /* no interaction */ key_type = 1; /* keyfile */ if (strcmp(key,"")==0) { printf("The keyfile cannot be blank\n"); exit(1); } nRtn = crypt(key_type, interact, in_filename, out_filename, key); cflag = 1; } /* using keyfile interactive*/ if (strcmp(cfunction,"-ki")==0) { interact = 1; /* interaction */ key_type = 1; /* keyfile attached keyfile */ printf("Enter keyfile including full path: "); scanf("%256s",key); if (strcmp(key,"")==0) { printf("The keyfile cannot be blank\n"); exit(1); } nRtn = crypt(key_type, interact, in_filename, out_filename, key); cflag = 1; } if (cflag == 0) { usage(argv[PARAM_FILENAME_S]); } return nRtn; }