static int internal_init_mcrypt(MCRYPT td, const void *key, int lenofkey, const void *IV) { int *sizes = NULL; int num_of_sizes, i, ok = 0; int key_size = mcrypt_enc_get_key_size(td); if (lenofkey > key_size || lenofkey==0) { return MCRYPT_KEY_LEN_ERROR; /* error */ } sizes = mcrypt_enc_get_supported_key_sizes(td, &num_of_sizes); if (sizes != NULL) { for (i = 0; i < num_of_sizes; i++) { if (lenofkey == sizes[i]) { ok = 1; break; } } } else { /* sizes==NULL */ if (num_of_sizes == 0 && lenofkey <= mcrypt_enc_get_key_size(td)) ok = 1; } if (ok == 0) { /* not supported key size */ key_size = mcrypt_enc_get_key_size(td); if (sizes != NULL) { for (i = 0; i < num_of_sizes; i++) { if (lenofkey <= sizes[i]) { key_size = sizes[i]; break; } } } else { /* well every key size is supported! */ key_size = lenofkey; } } else { key_size = lenofkey; } free(sizes); td->keyword_given = mxcalloc(1, mcrypt_enc_get_key_size(td)); if (td->keyword_given==NULL) return MCRYPT_MEMORY_ALLOCATION_ERROR; memmove(td->keyword_given, key, lenofkey); i = mcrypt_get_size(td); td->akey = mxcalloc(1, i); if (td->akey==NULL) { free(td->keyword_given); return MCRYPT_MEMORY_ALLOCATION_ERROR; } i = mcrypt_mode_get_size(td); if (i > 0) { td->abuf = mxcalloc(1, i); if (td->abuf==NULL) { free(td->keyword_given); free(td->akey); return MCRYPT_MEMORY_ALLOCATION_ERROR; } } ok = init_mcrypt(td, td->abuf, key, key_size, IV); if (ok!=0) { free(td->keyword_given); free(td->akey); free(td->abuf); return MCRYPT_UNKNOWN_ERROR; /* algorithm error */ } ok = mcrypt_set_key(td, (void *) td->akey, (void *) td->keyword_given, key_size, IV, IV!=NULL ? mcrypt_enc_get_iv_size(td) : 0); if (ok!=0) { internal_end_mcrypt(td); return MCRYPT_UNKNOWN_ERROR; /* algorithm error */ } return 0; }
int main(int argc, char *argv[]) { init_new_term(); /*-------- Get options ---------------------*/ int option; int option_index; static struct option long_options[] = { {"log", required_argument, NULL, 'l'}, {"encrypt", no_argument, NULL, 'e'}, {"port", required_argument, NULL, 'p'} }; while((option = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) switch(option) { case 'p': port_no = *((int *)optarg); break; case 'l': log_on = true; if((log_fd = dup(open(optarg, O_CREAT|O_TRUNC|O_WRONLY, 0644))) == ERROR) { fprintf(stderr, "Error: %s\n", strerror(errno)); exit(RC=EXIT_FAILURE); } break; case 'e': encrypt_on = true; break; } /*--------- Setup client --------------------*/ if((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) { fprintf(stderr, "Error: could not create server_socket_fd.\n"); } /*--------- Setup server client will be connecting to ----------*/ server_addr.sin_addr.s_addr = inet_addr(LOCALHOST); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port_no); /*--------- Connecting to server --------------*/ fprintf(stdout, "Waiting to connect to server...\n"); if(connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == ERROR) { fprintf(stderr, "Error: could not connect to server.\n"); exit(RC=EXIT_FAILURE); } fprintf(stdout, "Connected to %s on port %d!\n", LOCALHOST, port_no); /*--------- Process server output ---------------*/ pthread_t process_server_thread; pthread_create(&process_server_thread, NULL, &process_server_output, &socket_fd); /*--------- Initialize mcrypt -------------------*/ if(encrypt_on) init_mcrypt(); /*--------- Get input from terminal -------------*/ char buffer; while(1) { // Read error if(read(STDIN_FILENO, &buffer, NREAD) == 0) { fprintf(stderr, "Error: could not read c from stdin.\n"); close(socket_fd); exit(RC=RECEIVED_EOF_READERROR); } // buffer == ^D if(buffer == EOT) { fprintf(stdout, "Recieved ^D.\n"); close(socket_fd); exit(RC=RECEIVED_D); } /*--- Map <cr> or <lf> to <cr><lf> ------*/ else if(buffer == CR || buffer == LF) { // Echo to stdout if(write(STDOUT_FILENO, &CR, 1) != 1) { fprintf(stderr, "Error: could not write <cr> to stdout.\n"); exit(RC=EXIT_FAILURE); } if(write(STDOUT_FILENO, &LF, 1) != 1) { fprintf(stderr, "Error: could not write <lf> to stdout.\n"); exit(RC=EXIT_FAILURE); } /*--- Write <cr><lf>, <cr>, <lf> to server as <lf> ---*/ buffer = LF; // Encrypt if(encrypt_on && mcrypt_generic(td, &buffer, NREAD) != 0) { fprintf(stderr, "Error: encryption to write to server failed.\n"); exit(RC=EXIT_FAILURE); } // Write to server if(write(socket_fd, &buffer, 1) != 1) { fprintf(stderr, "Error: could not write <lf> to server.\n"); exit(RC=EXIT_FAILURE); } } // All other characters else { // Echo to stdout if(write(STDOUT_FILENO, &buffer, NREAD) != NREAD) { fprintf(stderr, "Error: could not write buffer to stdout.\n"); exit(RC=EXIT_FAILURE); } // Encrypt if(encrypt_on && mcrypt_generic(td, &buffer, NREAD) != 0) { fprintf(stderr, "Error: encryption to write to server failed.\n"); exit(RC=EXIT_FAILURE); } // Write to server if(write(socket_fd, &buffer, NREAD) != NREAD) { fprintf(stderr, "Error: could not write buffer to server.\n"); exit(RC=EXIT_FAILURE); } } // Write to log if(log_on) { write(log_fd, &LOG_SENT_PREFIX, SENT_PREFIX_LENGTH); write(log_fd, &buffer, NREAD); write(log_fd, &LF, 1); } } exit(RC=EXIT_SUCCESS); }