// Comentar la linea que corresponda //#define WINDOWS 1 #define LINUX 2 // Includes de /usr/include #include #include #include #ifdef WINDOWS #include //-- Para que password no sea visible #endif #ifdef LINUX #include //-- Para que password no sea visible #endif #define LONG_CRC 4 #define PARAM_OPERAC_ENCRIPTAR 1 #define PARAM_OPERAC_DESENCRIPTAR_TO_FILE 2 #define PARAM_OPERAC_DESENCRIPTAR_TO_STDOUT 3 #define PARAM_ECHO_SI 1 #define PARAM_ECHO_NO 2 // No hacer echo al introducir la password #define PARAM_PASSWORD_SI 1 // La password va como argumento de entrada del programa #define PARAM_PASSWORD_NO 2 #define VERSION "crenalme 1.0.0\n" #define COPYLEFT "Copyright 2004 Eneko Alvarez Mendia for Free Software\n" #define VERSION_CRC "NcbH" // Para compilar en Linux // gcc hello.c -g -Wall -o hello //////////////////////////////////////// // Devolver CRC de una cadena ///////////////////////////// void Crc (char* crc, char* password, unsigned long int* sum) { int llen,li,lcrc; char c; //int ctoi; unsigned long int ctoi; unsigned long int memoria=0; llen = strlen (password) - 1; // Calcular la suma de todos los caracteres de la password for (li=0; li 255 ) { ctoi = ctoi % 256; } // Esto calcula un CRC de 65-90 y 97-122 (A-Z y a-z) // Son 26 letras mayusculas y 26 minusculas // Lo convierto a un numero entre 0 y 51 (26+26) (0-25, 26-51) // El hueco esta entre la 91 y 96 que convertido a 0 y 51 es // desde el 26 al 31 ctoi = ctoi % ((90-65) + (122-97) + 1); if (ctoi <= (90-65) ) { ctoi = ctoi + 65; } else { ctoi = ctoi + 65 + (97-90) - 1; } crc [lcrc] = (char) ctoi; lcrc++; } } // Comprobar que nos pasan los parámetros correctos // 1: -e -- Encriptar // -d -- Desencriptar // -D -- Desencriptar directamente a pantalla // 2: [-n] -- No echo password // 2/3: [-p] -- Password // 3/4: [p] -- Password // 2/3/5: f -- Fichero // // Combinaciones distintas de parámetros // OPCION_1 -e fichero // OPCION_2 -e -n fichero // OPCION_3 -e -p password fichero // /////////////////////////////////////////////////////// int ErrorParametros (int argc, char* argv[], int* paramOperac, int* paramEcho, int* paramHayPassword, char* paramPassword, char* nombrefichero) { int lError=0; int lposFichero; // Posición donde está el fichero en la entrada FILE *fichero; char controlversion[128]; char crc [LONG_CRC+1] = "0000\0"; unsigned long int sum = 0; *paramEcho = PARAM_ECHO_SI; // Por defecto, se hace echo de la password *paramHayPassword = PARAM_PASSWORD_NO; // Por defecto, no hay password por parametro strcpy (controlversion, VERSION); strcat (controlversion, COPYLEFT); Crc (crc, controlversion, &sum); if (strcmp (crc, VERSION_CRC)) return 1; // Número de argumentos mínimos if ( argc <= 1 ) lError = 1; // Si quiere ver la version le dejo y me salgo if ( lError == 0 ) { if (! strcmp (argv[1], "--version")) return 0; } // Argumento 1 if ( lError == 0 ) { if ( strcmp (argv[1], "-e") && strcmp (argv[1], "-d") && strcmp (argv[1], "-D") ) lError = 1; } // Argumento 2 if ( lError == 0 ) { if ( argc <= 2 ) { lError = 1; } else { if ( strcmp (argv[2], "-n") && strcmp (argv[2], "-p") ) { // OPCION_1 (-e fichero) if ( argc != 3 ) { lError = 1; } else { lposFichero = 2; } } else { if ( ! strcmp (argv[2], "-n")) { // OPCION_2 (-e -n fichero) *paramEcho = PARAM_ECHO_NO; if ( argc != 4 ) { lError = 1; } else { lposFichero = 3; } } else { // OPCION_3 (-e -p password fichero) *paramHayPassword = PARAM_PASSWORD_SI; if ( argc != 5 ) { lError = 1; } else { lposFichero = 4; // Devoler la password strcpy (paramPassword, argv[3]); } } } } } // El fichero debe existir if ( lError == 0 ) { fichero = fopen(argv[lposFichero], "rb" ); if(!fichero) lError = 2; else fclose(fichero); } // Visualizar el mensaje de error if ( lError == 1 ) { printf("%s%s%s\n", "usage: ", argv[0], " -[edD] [[-n] | [-p password]] file"); printf(" -e: Encrypt file\n"); printf(" -d: Decrypt file\n"); printf(" -D: Decrypt to stdout\n"); printf(" -n: No password's echo\n"); printf(" -p: Password as argument\n"); printf(" --version: Program's version\n"); } if ( lError == 2 ) { printf("unable to open %s\n", argv[lposFichero]); } // Devolver la operacion a realizar if ( lError == 0 ) { if ( !strcmp (argv[1], "-e") ) *paramOperac = PARAM_OPERAC_ENCRIPTAR; if ( !strcmp (argv[1], "-d") ) *paramOperac = PARAM_OPERAC_DESENCRIPTAR_TO_FILE; if ( !strcmp (argv[1], "-D") ) *paramOperac = PARAM_OPERAC_DESENCRIPTAR_TO_STDOUT; // Devolver el nombre del fichero strcpy (nombrefichero, argv[lposFichero]); } return lError; } // Pedir la Password //////////////////// int AskPassword (char* password, int paramOperac, int paramEcho, int paramHayPassword, char* paramPassword) { // Si me han metido la password por parámetro no la pido, sino que la devuelvo if (paramHayPassword == PARAM_PASSWORD_SI) { strcpy (password, paramPassword); return 0; } #ifdef WINDOWS HANDLE h; int md; char verifypassword [129]; // Quitar el echo de la consola sólo si no quiere que haya echo if ( paramEcho == PARAM_ECHO_NO) { h = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(h, &md); SetConsoleMode(h, md & ~ENABLE_ECHO_INPUT); } // Pedir la Password printf("Password: "); fflush(stdout); fgets(password, 128, stdin); // Si no hay echo de la password, la pido 2 veces y la verifico if (paramEcho == PARAM_ECHO_NO) { printf("\nReenter Password: "); fflush(stdout); fgets(verifypassword, 128, stdin); if (strcmp (password, verifypassword)) { printf("\nPassword does not match\n"); fflush(stdout); return 1; } } // Volver a poner el echo if ( paramEcho == PARAM_ECHO_NO) { SetConsoleMode(h, md); } //printf("\n"); fflush(stdout); // Al pedir la password, se mete también el caracter de INTRO // Lo quito para que sea igual el pedirla que el meterla por parámetro password [strlen (password) - 1] = '\0'; #endif #ifdef LINUX char* cp; char* verifypassword; // Quitar el echo de la consola sólo si no quiere que haya echo if ( paramEcho == PARAM_ECHO_NO) { // Pedir la Password sin que se vea el echo cp = getpass("Password: "); strcpy (password, cp); } else { // Pedir la password viendose el echo printf( "Password: "); fgets(password, 128, stdin); fflush(stdin); } // Si no hay echo de la password, la pido 2 veces y la verifico if (paramEcho == PARAM_ECHO_NO) { verifypassword = getpass("Reenter Password: "); if (strcmp (password, verifypassword)) { printf("Password does not match\n"); fflush(stdout); return 1; } } // Al pedir la password, se mete también el caracter de INTRO // Lo quito para que sea igual el pedirla que el meterla por parámetro // Sólo lo hago si la password se ha visualizado por pantalla // Si no se ha visualizado por pantalla no hace falta quitarle el último caracter (esto sólo en Linux. En Windows sí hace falta) if ( ! (paramEcho == PARAM_ECHO_NO)) { password [strlen (password) - 1] = '\0'; } #endif // Que la password sea como mínimo de 1 caracter if (strlen (password) < 1) { printf("Invalid password\n"); return 1; } return 0; } // Encriptar cada caracter ////////////////////////// char EncripChar (char c, char* password, int* posinpass, long int posinfile, unsigned long int sum ) { long int l=0; int lposinpass; int cencriptado=0; // Reposicionar dentro de la password if (*posinpass == strlen (password)) lposinpass=0; else lposinpass = *posinpass; // Obtener numero aleatorio (caracter, password, pos in passw, pos in file, sum password) l = lposinpass + posinfile; l = l + (int) c; l = l + (int) password [lposinpass]; l = l + sum; l = l + 23 + 6 + 2004; if (l > 255 ) { cencriptado = l % 256; } else cencriptado = (int) l; lposinpass++; // Devolver la posicion de la password *posinpass = lposinpass; return (char) cencriptado; } // Encriptar el fichero /////////////////////// int Encript (char* file, char* password, unsigned long int sum ) { char ficheronombre [255] = ""; FILE *fichero, *fichero2; int c; int cencriptado, lposinpassword = 0; long int position; strcpy (ficheronombre, file); fichero = fopen(ficheronombre, "rb" ); if(!fichero) { printf( "Error al abrir el fichero\n" ); return 1; } fichero2 = fopen(ficheronombre, "r+b" ); //fichero2 = fopen("prueba.txt", "r+b" ); if(!fichero2) { printf( "Error al abrir el fichero\n" ); return 1; } // Abrir el fichero y modificarlo segun se va leyendo position = 0; while(!feof(fichero)) { // while(!feof(fichero) && position != 10) { if (position == 8158) position = 8158; c=getc(fichero); if(!feof(fichero)) { cencriptado = EncripChar (c, password, &lposinpassword, position, sum); putc(cencriptado,fichero2); position++; } } if( fclose(fichero) ) { printf( "Error al cerrar el fichero\n" ); return 1; } if( fclose(fichero2) ) { printf( "Error al cerrar el fichero\n" ); return 1; } return 0; } // DesEncriptar cada caracter ///////////////////////////// char DesEncripChar (char c, char* password, int* posinpass, long int posinfile, unsigned long int sum ) { long int l=0; int lposinpass; int cencriptado=0; // Reposicionar dentro de la password if (*posinpass == strlen (password)) lposinpass=0; else lposinpass = *posinpass; // Deshacer numero aleatorio (caracter, password, pos in passw, pos in file, sum password) l = (int) c - lposinpass - (int) password [lposinpass] - posinfile - sum - 23 - 6 - 2004; if (l < 0 ) { cencriptado = l + 256; } else cencriptado = (int) l; lposinpass++; // Devolver la posicion de la password *posinpass = lposinpass; return (char) cencriptado; } // DesEncriptar el fichero ////////////////////////// int DesEncript (char* file, char* password, unsigned long int sum, int pstdout ) { char ficheronombre [255] = ""; FILE *fichero, *fichero2; int c; int cencriptado, lposinpassword = 0; long int position; strcpy (ficheronombre, file); fichero = fopen(ficheronombre, "rb" ); if(!fichero) { printf( "Error al abrir el fichero\n" ); return 1; } // Si me he pasado stdout no abro el fichero sino que lo imprimo por pantalla if (pstdout == PARAM_OPERAC_DESENCRIPTAR_TO_FILE) { fichero2 = fopen(ficheronombre, "r+b" ); if(!fichero2) { printf( "Error al abrir el fichero\n" ); return 1; } } // Abrir el fichero y modificarlo segun se va leyendo position = 0; while(!feof(fichero)) { c=getc(fichero); if(!feof(fichero)) { cencriptado = DesEncripChar (c, password, &lposinpassword, position, sum); // Imprimir o no por pantalla if (pstdout == PARAM_OPERAC_DESENCRIPTAR_TO_FILE) { putc(cencriptado,fichero2); position++; } else { printf("%c", cencriptado); position++; } } } if( fclose(fichero) ) { printf( "Error al cerrar el fichero\n" ); return 1; } // Imprimir o no por pantalla if (pstdout == PARAM_OPERAC_DESENCRIPTAR_TO_FILE) { if( fclose(fichero2) ) { printf( "Error al cerrar el fichero\n" ); return 1; } } return 0; } // Main /////// int main(int argc, char **argv) { char crc [LONG_CRC+1] = "0000\0"; char password [129]; unsigned long int sum = 0; int paramOperac, paramEcho, paramHayPassword; char paramPassword[129]; char nombrefichero[129]; // Comprobar que los parámetros son correctos if (ErrorParametros (argc, argv, ¶mOperac, ¶mEcho, ¶mHayPassword, paramPassword, nombrefichero)) return 1; // Mostrar versión del programa if ( argc == 2 ) { if (! strcmp (argv[1], "--version")) { printf (VERSION); printf (COPYLEFT); return 0; } } // Pedir la Password if (AskPassword (password, paramOperac, paramEcho, paramHayPassword, paramPassword)) { return 1; } // CRC de password Crc (crc, password, &sum); // Operaciones a Realizar switch (paramOperac) { // Encriptar el fichero case PARAM_OPERAC_ENCRIPTAR: Encript (nombrefichero, password, sum); break; // Desencriptar el fichero case PARAM_OPERAC_DESENCRIPTAR_TO_FILE: DesEncript (nombrefichero, password, sum, PARAM_OPERAC_DESENCRIPTAR_TO_FILE); break; // Desencriptar el fichero case PARAM_OPERAC_DESENCRIPTAR_TO_STDOUT: DesEncript (nombrefichero, password, sum, PARAM_OPERAC_DESENCRIPTAR_TO_STDOUT); break; } return 0; }