/*************************************************************
 * crack                                                     *
 * analyze the communications between loadserver and -client *
 * try to determine the secret key and decipher the protocol *
 *                                                           *
 *************************************************************
 * Usage: crack <filename>                                   *
 ************************************************************/
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
/* max length of line */
#define MAXLINE 128
/* max lines in file */
#define MAXLINES 256
/* request string */
#define REQUEST_STRING "getload\n"
/* reply string */
#define REPLY_STRING "myload"


/**/
void usage(char* name) {
    printf("%s - analyze messages between loadserver and -client\n", name);
    printf("Usage: %s <filename>\n", name);
    exit(1);
}


/* decrypts cipher using the xor-operation */
void decrypt(char key, char* cipher, char* plain) {
    int i;
    for (i = 0; i < strlen(cipher); i++) {
	plain[i] = key ^ cipher[i];
    }
    plain[i] = '\0';
}


void main (int argc, char** argv) {
    char plain[MAXLINE];		/* buffer for I/O */
    char cipher[MAXLINE];		/* buffer for I/O */
    
    char c, key;			/* for trying out the different keys */
    int found = 0;			/* log if the key was found */
    
    FILE* file;
    char* filename;
        
    /* check for arguments */
    if (argc == 2) {
	filename = argv[1];
    } else {
	usage(argv[0]);
    }

    file = fopen(filename, "r");
    fscanf(file, "%s", cipher);
    fclose(file);

    /* try to find the key and decrypt the message 
       this assumes that the key is an upper case letter */
    for (c = 'A'; c <= 'Z'; c++) {

        key = c;
        decrypt(key, cipher, plain);
	
        if (!strcmp(plain, REQUEST_STRING)) {
            printf("encryption key    : %c\n", key);
            printf("decrypted message : %s\n", plain);
	    found = 1;
            break;
	}
	
	if (strstr(plain, REPLY_STRING) != NULL) {
	    printf("Used key is : %c\n", key);
	    printf("Message was : %s\n", plain);
	    found = 1;
	    break;
	}
	
    }

    if (found == 1) {
        printf("Messages :\n");
        while(1) {
            file = fopen(filename, "r");
    	    fscanf(file, "%s", cipher);
	    fclose(file);
            decrypt(key, cipher, plain);
            printf("%s\n", plain);
        }    
    } else {
        printf("Key couldn't be cracked ...\n");
    }
    
    /*while(1) {
            file = fopen(filename, "r");
    	    fscanf(file, "%s", cipher);
	    fclose(file);
            decrypt(key, cipher, plain);
            printf("%s", plain);
    }*/    
    
    printf("done...\n");

}