Added work from my other class repositories before deletion

This commit is contained in:
2017-11-29 10:28:24 -08:00
parent cb0b5f4d25
commit 5ea24c81b5
198 changed files with 739603 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
#!/bin/bash
make clean
make build

View File

@@ -0,0 +1,51 @@
/*
* File: keygen.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:27 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define ASCII_START 65
int main(int argc, char** argv) {
//Some error handling for bad inputs
if(argc < 2){
fprintf(stderr, "No arguments entered. Please try again.\n");
exit(PROGRAM_FAILURE);
}else if (argc > 2){
fprintf(stderr, "Extra arguments entered. Ignoring all but the "
"first.\n");
}else if(atoi(argv[1]) <= 0){
fprintf(stderr, "Key length too small. Number must be greater than "
"zero.\n");
exit(PROGRAM_FAILURE);
}
time_t t;
srand((unsigned) time(&t));
//Get the number passed in as an argument
int key_length = atoi(argv[1]);
//Loop through and output a new character based on the number generated
for(int i = 0 ; i < key_length ; i++){
int rand_char = rand() % 27;
if(rand_char == 26){
printf(" ");
}else{
printf("%c", (char)(rand_char + ASCII_START));
}
}
//Print the final newline and exit successfully.
printf("\n");
exit(PROGRAM_SUCCESS);
}

View File

@@ -0,0 +1,15 @@
all: build
clean:
rm -f otp_dec
rm -f otp_dec_d
rm -f otp_enc
rm -f otp_enc_d
rm -f keygen
build:
gcc otp_dec.c -o otp_dec -std=c99
gcc otp_dec_d.c -o otp_dec_d -std=c99
gcc otp_enc.c -o otp_enc -std=c99
gcc otp_enc_d.c -o otp_enc_d -std=c99
gcc keygen.c -o keygen -std=c99

View File

@@ -0,0 +1,296 @@
/*
* File: otp_enc.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PROGRAM_FAILURE_PORT 2
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
int main(int argc, char** argv) {
int comms_sfd;
unsigned long int comms_port_number; //0 - 65535
struct hostent *server;
struct sockaddr_in server_address;
FILE *input_file;
FILE *key_file;
//Verify correct number of arguments
if(argc < 4){
fprintf(stderr, "Not enough arguments provided. Exiting...\n");
fprintf(stderr, "Correct usage: "
"%s input_file key_file port\n", argv[0]);
exit(PROGRAM_FAILURE);
}else if(argc > 4){
fprintf(stderr, "Extra arguments entered. Ignoring all but the first "
"three.\n");
}
//Get port number, and make sure it's valid
comms_port_number = atoi(argv[3]);
if((comms_port_number > PORT_MAX) || (comms_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Open the files
input_file = fopen(argv[1], "r");
key_file = fopen(argv[2], "r");
//Make sure they opened successfully
if(input_file == NULL){
fprintf(stderr, "Input file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}else if(key_file == NULL){
fprintf(stderr, "Key file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read in input file
char* temp_buffer = malloc(sizeof(char) * 1000000);
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, input_file);
char* input_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(input_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(input_text, temp_buffer);
//Remove input file newline
int input_str_len = strlen(input_text);
if(input_text[input_str_len - 1] == '\n'){
input_text[input_str_len - 1] = '\0';
}
//Read in key file
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, key_file);
char* key_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(key_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(key_text, temp_buffer);
//Remove input file newline
input_str_len = strlen(key_text);
if(key_text[input_str_len - 1] == '\n'){
key_text[input_str_len - 1] = '\0';
}
free(temp_buffer);
//Exit as error is input_string is longer than the key
if(strlen(input_text) > strlen(key_text)){
fprintf(stderr, "Key file too small. Please try again with larger "
"file. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Check files for bad characters
for(unsigned long i = 0 ; i < strlen(input_text) ; i ++){
if(get_mapped_num_from_char(input_text[i]) == -1){
fprintf(stderr, "Bad characters in input text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
for(unsigned long i = 0 ; i < strlen(key_text) ; i ++){
if(get_mapped_num_from_char(key_text[i]) == -1){
fprintf(stderr, "Bad characters in key text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
//Create listening socket, check if created successfully
comms_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(comms_sfd < 0){
fprintf(stderr, "Could not create comms socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get localhost as server, check if valid
server = gethostbyname("localhost");
if(server == NULL){
fprintf(stderr, "localhost is not a valid host! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up comms parameters for the server we're connecting to.
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(comms_port_number);
memcpy(&server_address.sin_addr, server->h_addr_list[0], server->h_length);
server_address.sin_family = AF_INET;
//Make the server connection and verify it didn't fail.
int connect_result = connect(comms_sfd, \
(struct sockaddr *)&server_address, \
sizeof(server_address));
if(connect_result < 0){
fprintf(stderr, "Connection failed! Is the port correct? Exiting...\n");
exit(PROGRAM_FAILURE_PORT);
}
//Set up writing and reading variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 1);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Write message to tell the daemon what program we are
write_return = write(comms_sfd, OTP_DEC_IDENT TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read the servers response to our message
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
if(strstr(concat_buffer, OTP_CONTINUE TEXT_DONE) != NULL){
//In this case, the response from the server is to continue
//We write the input text to the daemon
write_return = write(comms_sfd, input_text, strlen(input_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Then we write the ending characters
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Now we write the key file to the daemon
write_return = write(comms_sfd, key_text, strlen(key_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//And the ending characters again
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in the response from the daemon
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Print out the cleaned up response from the daemon
for(int i = 0 ; i < strlen(concat_buffer) ; i++){
printf("%c", concat_buffer[i]);
}
printf("\n");
}else if(strstr(concat_buffer, OTP_FAILURE TEXT_DONE) != NULL){
//Print an error if we try to connect to the wrong daemon
fprintf(stderr, "OTP_DEC may NOT connect to OTP_ENC_D. Exiting...\n");
exit(PROGRAM_FAILURE);
}else{
//Print an error if we get erroneous data.
fprintf(stderr, "Got bad data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}

View File

@@ -0,0 +1,309 @@
/*
* File: otp_enc_d.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
char get_mapped_char_from_num(int number);
char encode_character(char letter, char key_letter);
char decode_character(char input_letter, char key_letter);
int main(int argc, char** argv) {
int listen_sfd; //sfd == socked_file_descriptor
int comms_sfd;
unsigned long int listen_port_number; //0 - 65535
socklen_t client_length;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//Check if we have enough arguments, error and exit if not.
if(argc < 2){
fprintf(stderr, "No port provided! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Create our listening socket, check if created successfully
listen_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sfd < 0){
fprintf(stderr, "Could not create listening socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get port number, and make sure it's valid
listen_port_number = atoi(argv[1]);
if((listen_port_number > PORT_MAX) || (listen_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up listening parameters
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(listen_port_number);
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_family = AF_INET;
//Bind server to settings set above, let system know we're ready
int bind_result = bind(listen_sfd, (struct sockaddr *)&server_address, \
sizeof(server_address));
if(bind_result < 0){
fprintf(stderr, "Failed to bind listening port! "
"Please choose a different port! Exiting...\n");
exit(PROGRAM_FAILURE);
}
while(1){
//Call waitpid to kill off any zombie processes. Don't let it block.
static int process_status;
waitpid(-1, &process_status, WNOHANG);
//Listen to the port, and allow up to five connections
listen(listen_sfd, 5); //Listen to the port
//Block until a valid connection is made, then accept it.
//Also make sure it's accepted correctly
socklen_t client_length = sizeof(client_address);
comms_sfd = accept(listen_sfd, (struct sockaddr *) &client_address, \
&client_length);
if (comms_sfd < 0){
fprintf(stderr, "Client accept failed. Trying next "
"connection...\n");
}else{
//We've made a valid connection, so spawn off a new process to
//handle it to free up the main thread for accepting a new client.
pid_t spawned_pid;
spawned_pid = fork();
//Only run the child code if it's a child process
if(spawned_pid == 0){
//Initialize read write variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read initial message telling us who the client is
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Choose a response appropriate for who is communicating
if(strstr(concat_buffer, OTP_DEC_IDENT TEXT_DONE) != NULL){
//In this case, the client/server match and we can continue
//Write a message to the client that we'll continue
write_return = write(comms_sfd, OTP_CONTINUE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in first input file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store input text for later use
char* input_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(input_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(input_text, concat_buffer);
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in key file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store key file for later
char* key_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(key_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(key_text, concat_buffer);
free(concat_buffer);
//Write the decrypted data to the client
for(unsigned long int i = 0 ; i < strlen(input_text) ;\
i++){
char new_char = decode_character(input_text[i], \
key_text[i]);
write_return = write(comms_sfd, &new_char, 1);
}
//Write the end of text marker
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}else if(strstr(concat_buffer, OTP_ENC_IDENT TEXT_DONE) \
!= NULL){
//In this case, client and server don't match
//Write failure message so client exits
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}else{
//Error and messages for erroneous data
fprintf(stderr, "Got bad data. Alerting sender and "
"exiting...\n");
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}
//Since this is a child process, once it's done it should die.
exit(PROGRAM_SUCCESS);
}
}
}
close(listen_sfd);
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}
char get_mapped_char_from_num(int number){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(number == letter_number_assignment[i][1]){
return letter_number_assignment[i][0];
}
}
return -1;
}
char encode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int summed = (letter_mapped + key_mapped);
if(summed >= LETTER_OPTIONS){
summed -= LETTER_OPTIONS;
}
return get_mapped_char_from_num(summed);
}
char decode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int subbed = (letter_mapped - key_mapped);
if(subbed < 0){
subbed += LETTER_OPTIONS;
}
return get_mapped_char_from_num(subbed);
}

View File

@@ -0,0 +1,294 @@
/*
* File: otp_enc.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PROGRAM_FAILURE_PORT 2
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
int main(int argc, char** argv) {
int comms_sfd;
unsigned long int comms_port_number; //0 - 65535
struct hostent *server;
struct sockaddr_in server_address;
FILE *input_file;
FILE *key_file;
//Verify correct number of arguments
if(argc < 4){
fprintf(stderr, "Not enough arguments provided. Exiting...\n");
fprintf(stderr, "Correct usage: "
"%s input_file key_file port\n", argv[0]);
exit(PROGRAM_FAILURE);
}else if(argc > 4){
fprintf(stderr, "Extra arguments entered. Ignoring all but the first "
"three.\n");
}
//Get port number, and make sure it's valid
comms_port_number = atoi(argv[3]);
if((comms_port_number > PORT_MAX) || (comms_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Open the files
input_file = fopen(argv[1], "r");
key_file = fopen(argv[2], "r");
//Make sure they opened successfully
if(input_file == NULL){
fprintf(stderr, "Input file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}else if(key_file == NULL){
fprintf(stderr, "Key file does not exist or cannot be read! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read in input file
char* temp_buffer = malloc(sizeof(char) * 1000000);
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, input_file);
char* input_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(input_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(input_text, temp_buffer);
//Remove input file newline
int input_str_len = strlen(input_text);
if(input_text[input_str_len - 1] == '\n'){
input_text[input_str_len - 1] = '\0';
}
//Read in key file
memset(temp_buffer, '\0', sizeof(char) * 1000000);
fgets(temp_buffer, 1000000, key_file);
char* key_text = malloc(sizeof(char) * (strlen(temp_buffer) + 1));
memset(key_text, '\0', sizeof(char) * (strlen(temp_buffer) + 1));
strcpy(key_text, temp_buffer);
//Remove input file newline
input_str_len = strlen(key_text);
if(key_text[input_str_len - 1] == '\n'){
key_text[input_str_len - 1] = '\0';
}
free(temp_buffer);
//Exit as error is input_string is longer than the key
if(strlen(input_text) > strlen(key_text)){
fprintf(stderr, "Key file too small. Please try again with larger "
"file. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Check files for bad characters
for(unsigned long i = 0 ; i < strlen(input_text) ; i ++){
if(get_mapped_num_from_char(input_text[i]) == -1){
fprintf(stderr, "Bad characters in input text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
for(unsigned long i = 0 ; i < strlen(key_text) ; i ++){
if(get_mapped_num_from_char(key_text[i]) == -1){
fprintf(stderr, "Bad characters in key text. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}
//Create listening socket, check if created successfully
comms_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(comms_sfd < 0){
fprintf(stderr, "Could not create comms socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get localhost as server, check if valid
server = gethostbyname("localhost");
if(server == NULL){
fprintf(stderr, "localhost is not a valid host! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up comms parameters for the server we're connecting to.
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(comms_port_number);
memcpy(&server_address.sin_addr, server->h_addr_list[0], server->h_length);
server_address.sin_family = AF_INET;
//Make the server connection and verify it didn't fail.
int connect_result = connect(comms_sfd, \
(struct sockaddr *)&server_address, \
sizeof(server_address));
if(connect_result < 0){
fprintf(stderr, "Connection failed! Is the port correct? Exiting...\n");
exit(PROGRAM_FAILURE_PORT);
}
//Set up writing and reading variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 1);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Write message to tell the daemon what program we are
write_return = write(comms_sfd, OTP_ENC_IDENT TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Read the servers response to our message
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
if(strstr(concat_buffer, OTP_CONTINUE TEXT_DONE) != NULL){
//In this case, the response from the server is to continue
//We write the input text to the daemon
write_return = write(comms_sfd, input_text, strlen(input_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Then we write the ending characters
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Now we write the key file to the daemon
write_return = write(comms_sfd, key_text, strlen(key_text));
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//And the ending characters again
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to write data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in the response from the daemon
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Print out the cleaned up response from the daemon
for(int i = 0 ; i < strlen(concat_buffer) ; i++){
printf("%c", concat_buffer[i]);
}
printf("\n");
}else if(strstr(concat_buffer, OTP_FAILURE TEXT_DONE) != NULL){
//Print an error if we try to connect to the wrong daemon
fprintf(stderr, "OTP_ENC may NOT connect to OTP_DEC_D. Exiting...\n");
exit(PROGRAM_FAILURE);
}else{
//Print an error if we get erroneous data.
fprintf(stderr, "Got bad data. Exiting...\n");
exit(PROGRAM_FAILURE);
}
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}

View File

@@ -0,0 +1,310 @@
/*
* File: otp_enc_d.c
* Author: Corwin Perren
*
* Created on November 29, 2016, 7:26 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#define PROGRAM_SUCCESS 0
#define PROGRAM_FAILURE 1
#define PORT_MAX 65535
#define PORT_MIN 0
#define OTP_ENC_IDENT "#"
#define OTP_DEC_IDENT "$"
#define TEXT_DONE "@@"
#define OTP_FAILURE "%"
#define OTP_CONTINUE "&"
#define LETTER_OPTIONS 27
int letter_number_assignment[LETTER_OPTIONS][2] = {
'A', 10,
'B', 11,
'C', 12,
'D', 13,
'E', 14,
'F', 15,
'G', 16,
'H', 17,
'I', 18,
'J', 19,
'K', 20,
'L', 21,
'M', 22,
'N', 23,
'O', 24,
'P', 25,
'Q', 26,
'R', 0,
'S', 1,
'T', 2,
'U', 3,
'V', 4,
'W', 5,
'X', 6,
'Y', 7,
'Z', 8,
' ', 9
};
int get_mapped_num_from_char(char letter);
char get_mapped_char_from_num(int number);
char encode_character(char letter, char key_letter);
char decode_character(char input_letter, char key_letter);
int main(int argc, char** argv) {
int listen_sfd; //sfd == socked_file_descriptor
int comms_sfd;
unsigned long int listen_port_number; //0 - 65535
socklen_t client_length;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//Check if we have enough arguments, error and exit if not.
if(argc < 2){
fprintf(stderr, "No port provided! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Create our listening socket, check if created successfully
listen_sfd = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sfd < 0){
fprintf(stderr, "Could not create listening socket! Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Get port number, and make sure it's valid
listen_port_number = atoi(argv[1]);
if((listen_port_number > PORT_MAX) || (listen_port_number < PORT_MIN)){
fprintf(stderr, "Port out of range! Please choose a different port! "
"Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Set up listening parameters
memset((char *)&server_address, '\0', sizeof(server_address));
server_address.sin_port = htons(listen_port_number);
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_family = AF_INET;
//Bind server to settings set above, let system know we're ready
int bind_result = bind(listen_sfd, (struct sockaddr *)&server_address, \
sizeof(server_address));
if(bind_result < 0){
fprintf(stderr, "Failed to bind listening port! "
"Please choose a different port! Exiting...\n");
exit(PROGRAM_FAILURE);
}
while(1){
//Call waitpid to kill off any zombie processes. Don't let it block.
static int process_status;
waitpid(-1, &process_status, WNOHANG);
//Listen to the port, and allow up to five connections
listen(listen_sfd, 5); //Listen to the port
//Block until a valid connection is made, then accept it.
//Also make sure it's accepted correctly
socklen_t client_length = sizeof(client_address);
comms_sfd = accept(listen_sfd, (struct sockaddr *) &client_address, \
&client_length);
if (comms_sfd < 0){
fprintf(stderr, "Client accept failed. Trying next "
"connection...\n");
}else{
//We've made a valid connection, so spawn off a new process to
//handle it to free up the main thread for accepting a new client.
pid_t spawned_pid;
spawned_pid = fork();
//Only run the child code if it's a child process
if(spawned_pid == 0){
//Initialize read write variables
int read_return;
int write_return;
unsigned int concat_index = 0;
char read_buffer[10];
char* concat_buffer = malloc(sizeof(char) * 1000000);
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read initial message telling us who the client is
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Choose a response appropriate for who is communicating
if(strstr(concat_buffer, OTP_ENC_IDENT TEXT_DONE) != NULL){
//In this case, the client/server match and we can continue
//Write a message to the client that we'll continue
write_return = write(comms_sfd, OTP_CONTINUE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in first input file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
int input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store this for later use
char* input_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(input_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(input_text, concat_buffer);
//Reset variables to receive data
concat_index = 0;
memset(read_buffer, '\0', 10);
memset(concat_buffer, '\0', sizeof(char) * 1000000);
//Read in key file from client
while(strstr(concat_buffer, TEXT_DONE) == NULL){
read_return = read(comms_sfd, read_buffer, 1);
if(read_return != -1){
concat_buffer[concat_index] = read_buffer[0];
concat_index++;
}
}
//Null out our marker characters
input_string_length = strlen(concat_buffer);
concat_buffer[input_string_length-1] = '\0';
concat_buffer[input_string_length-2] = '\0';
//Store key file for later
char* key_text = malloc(sizeof(char) * \
(strlen(concat_buffer) + 1));
memset(key_text, '\0', sizeof(char) * \
(strlen(concat_buffer) + 1));
strcpy(key_text, concat_buffer);
free(concat_buffer);
//Write the encrypted data to the client
for(unsigned long int i = 0 ; i < strlen(input_text) ;\
i++){
char new_char = encode_character(input_text[i], \
key_text[i]);
write_return = write(comms_sfd, &new_char, 1);
}
//Write the end of text marker
write_return = write(comms_sfd, TEXT_DONE, 2);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
exit(PROGRAM_FAILURE);
}
}else if(strstr(concat_buffer, OTP_DEC_IDENT TEXT_DONE) \
!= NULL){
//In this case, client and server don't match
//Write failure message so client exits
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}else{
//Error and messages for erroneous data
fprintf(stderr, "Got bad data. Alerting sender and "
"exiting...\n");
write_return = write(comms_sfd, OTP_FAILURE TEXT_DONE, 3);
if(write_return < 0){
fprintf(stderr, "Failed to alert sender. Exiting...\n");
}
exit(PROGRAM_FAILURE);
}
//Since this is a child process, once it's done it should die.
exit(PROGRAM_SUCCESS);
}
}
}
close(listen_sfd);
exit(PROGRAM_SUCCESS);
}
int get_mapped_num_from_char(char letter){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(letter == letter_number_assignment[i][0]){
return letter_number_assignment[i][1];
}
}
return -1;
}
char get_mapped_char_from_num(int number){
for(int i = 0 ; i < LETTER_OPTIONS ; i++){
if(number == letter_number_assignment[i][1]){
return letter_number_assignment[i][0];
}
}
return -1;
}
char encode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int summed = (letter_mapped + key_mapped);
if(summed >= LETTER_OPTIONS){
summed -= LETTER_OPTIONS;
}
return get_mapped_char_from_num(summed);
}
char decode_character(char input_letter, char key_letter){
int letter_mapped = get_mapped_num_from_char(input_letter);
int key_mapped = get_mapped_num_from_char(key_letter);
int subbed = (letter_mapped - key_mapped);
if(subbed < 0){
subbed += LETTER_OPTIONS;
}
return get_mapped_char_from_num(subbed);
}

View File

@@ -0,0 +1,142 @@
#!/bin/bash
# FYI, this command removes file abc if it is empty: [ -s abc ] || rm -f abc
usage="usage: $0 encryptionport decryptionport"
#use the standard version of echo
echo=/bin/echo
#Make sure we have the right number of arguments
if test $# -gt 2 -o $# -lt 2
then
${echo} $usage 1>&2
exit 1
fi
#Clean up any previous runs
${echo} '#Initializing - Cleaning up - ignore Operation Not Permitted errors'
killall -q -u $USER otp_*
rm -f ciphertext*
rm -f plaintext*_*
rm -f key20
rm -f key70000
#Record the ports passed in
encport=$1
decport=$2
#Run the daemons
otp_enc_d $encport &
otp_dec_d $decport &
sleep 5
${echo}
${echo} '#-----------------------------------------'
${echo} '#START OF GRADING SCRIPT'
${echo} '#keygen 20 > key20'
keygen 20 > key20
${echo} "#5 POINTS: key20 must exist"
[ -s key20 ] || rm -f key20
if [ -f key20 ]; then ${echo} 'key20 exists!'; else ${echo} 'key20 DOES NOT EXIST'; fi
${echo}
${echo} "#-----------------------------------------"
${echo} "#5 POINTS: Number of characters in key20, should be 21:"
wc -m key20
${echo}
${echo} "#-----------------------------------------"
${echo} '#keygen 70000 > key70000'
keygen 70000 > key70000
${echo} "#5 POINTS: Number of characters in key70000, should be 70001:"
[ -s key70000 ] || rm -f key70000
wc -m key70000
${echo}
${echo} "#-----------------------------------------"
${echo} '#otp_enc plaintext1 key20 $encport'
${echo} "#10 POINTS: Should return error about too-short key"
otp_enc plaintext1 key20 $encport
${echo}
${echo} "#-----------------------------------------"
${echo} '#otp_enc plaintext1 key70000 $encport'
${echo} "#20 POINTS: Should return encrypted version of plaintext1"
otp_enc plaintext1 key70000 $encport
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_enc plaintext1 key70000 $encport > ciphertext1'
otp_enc plaintext1 key70000 $encport > ciphertext1
${echo} "#10 POINTS: ciphertext1 must exist"
[ -s ciphertext1 ] || rm -f ciphertext1
if [ -f ciphertext1 ]; then ${echo} 'ciphertext1 exists!'; else ${echo} 'ciphertext1 DOES NOT EXIST'; fi
${echo}
${echo} '#-----------------------------------------'
${echo} '#10 POINTS: ciphertext1 must be same number of chars as source'
${echo} '#wc -m plaintext1'
wc -m plaintext1
${echo} '#Should be same: wc -m ciphertext1'
wc -m ciphertext1
${echo}
${echo} '#-----------------------------------------'
${echo} '#5 POINTS: ciphertext1 should look encrypted'
cat ciphertext1
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_dec ciphertext1 key70000 $encport'
${echo} '#5 POINTS: Should fail giving error that otp_dec cannot use otp_enc_d'
otp_dec ciphertext1 key70000 $encport
${echo}
${echo} '#-----------------------------------------'
${echo} '#20 POINTS: should return decrypted ciphertext1 that matches source'
${echo} '#cat plaintext1'
cat plaintext1
${echo} '#otp_dec ciphertext1 key70000 $decport'
otp_dec ciphertext1 key70000 $decport
${echo}
${echo} '#-----------------------------------------'
${echo} '#otp_dec ciphertext1 key70000 $decport > plaintext1_a'
otp_dec ciphertext1 key70000 $decport > plaintext1_a
${echo} "#10 POINTS: plaintext1_a must exist"
[ -s plaintext1_a ] || rm -f plaintext1_a
if [ -f plaintext1_a ]; then ${echo} 'plaintext1_a exists!'; else ${echo} 'plaintext1_a DOES NOT EXIST'; fi
${echo}
${echo} '#-----------------------------------------'
${echo} '#cmp plaintext1 plaintext1_a'
${echo} '#5 POINTS: plaintext1 must be the same as plaintext1_a:'
cmp plaintext1 plaintext1_a
${echo} '#echo $? should be == 0, which means the cmp succeeded!'
echo $?
${echo}
${echo} '#-----------------------------------------'
${echo} '#20 POINTS: concurrent test of encryption - look for 4 properly-sized ciphertext# files, or 5 where the 5th is 0 bytes'
${echo} '#5 POINTS: Should be only one error about plaintext5 being bad'
rm -f ciphertext*
rm -f plaintext*_*
otp_enc plaintext1 key70000 $encport > ciphertext1 &
otp_enc plaintext2 key70000 $encport > ciphertext2 &
otp_enc plaintext3 key70000 $encport > ciphertext3 &
otp_enc plaintext4 key70000 $encport > ciphertext4 &
otp_enc plaintext5 key70000 $encport > ciphertext5 &
${echo} 'Ten second sleep, your program must complete in this time'
sleep 10
ls -pla
${echo}
${echo} '#-----------------------------------------'
${echo} '#15 POINTS: concurrent test of decryption - look for 4 plaintext#_a files that match the plaintext# files'
otp_dec ciphertext1 key70000 $decport > plaintext1_a &
otp_dec ciphertext2 key70000 $decport > plaintext2_a &
otp_dec ciphertext3 key70000 $decport > plaintext3_a &
otp_dec ciphertext4 key70000 $decport > plaintext4_a &
${echo} '#Ten second sleep, your program must complete in this time'
sleep 10
ls -pla
#Clean up
${echo}
${echo} '#-----------------------------------------'
${echo} '#Cleaning up - ignore Operation Not Permitted errors'
killall -q -u $USER otp_*
rm -f ciphertext*
rm -f plaintext*_*
rm -f key20
rm -f key70000
${echo}
${echo} '#SCRIPT COMPLETE'

View File

@@ -0,0 +1 @@
THE RED GOOSE FLIES AT MIDNIGHT STOP

View File

@@ -0,0 +1 @@
CAVERNA POWER GRID SPACE CADETS STARSHIP TROOPERS DIXIT DOMINION ARKHAM HORROR MAGIC FALLING BANE ECLIPSE ACQUIRE CORE WORLDS REVOLUTION LORDS OF WATERDEEP MICE AND MYSTICS PATHFINDER ACG MUNCHKIN SMASHUP TWILIGHT STRUGGLE PUERTO RICO SMALL WORLD PANDEMIC SEVEN WONDERS ROBORALLY DIPLOMACY DEADWOOD KILL DOCTOR LUCKY

View File

@@ -0,0 +1 @@
IN THE BEGINNING

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
$*!(#*djs8301these-are-all-bad-characters

View File

@@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg) { perror(msg); exit(0); } // Error function used for reporting issues
int main(int argc, char *argv[])
{
int socketFD, portNumber, charsWritten, charsRead;
struct sockaddr_in serverAddress;
struct hostent* serverHostInfo;
char buffer[256];
if (argc < 3) { fprintf(stderr,"USAGE: %s hostname port\n", argv[0]); exit(0); } // Check usage & args
// Set up the server address struct
memset((char*)&serverAddress, '\0', sizeof(serverAddress)); // Clear out the address struct
portNumber = atoi(argv[2]); // Get the port number, convert to an integer from a string
serverAddress.sin_family = AF_INET; // Create a network-capable socket
serverAddress.sin_port = htons(portNumber); // Store the port number
serverHostInfo = gethostbyname(argv[1]); // Convert the machine name into a special form of address
if (serverHostInfo == NULL) { fprintf(stderr, "CLIENT: ERROR, no such host\n"); exit(0); }
memcpy((char*)&serverAddress.sin_addr.s_addr, (char*)serverHostInfo->h_addr, serverHostInfo->h_length); // Copy in the address
// Set up the socket
socketFD = socket(AF_INET, SOCK_STREAM, 0); // Create the socket
if (socketFD < 0) error("CLIENT: ERROR opening socket");
// Connect to server
if (connect(socketFD, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) // Connect socket to address
error("CLIENT: ERROR connecting");
// Get input message from user
printf("CLIENT: Enter text to send to the server, and then hit enter: ");
memset(buffer, '\0', sizeof(buffer)); // Clear out the buffer array
fgets(buffer, sizeof(buffer) - 1, stdin); // Get input from the user, trunc to buffer - 1 chars, leaving \0
buffer[strcspn(buffer, "\n")] = '\0'; // Remove the trailing \n that fgets adds
// Send message to server
charsWritten = send(socketFD, buffer, strlen(buffer), 0); // Write to the server
if (charsWritten < 0) error("CLIENT: ERROR writing to socket");
if (charsWritten < strlen(buffer)) printf("CLIENT: WARNING: Not all data written to socket!\n");
// Get return message from server
memset(buffer, '\0', sizeof(buffer)); // Clear out the buffer again for reuse
charsRead = recv(socketFD, buffer, sizeof(buffer) - 1, 0); // Read data from the socket, leaving \0 at end
if (charsRead < 0) error("CLIENT: ERROR reading from socket");
printf("CLIENT: I received this from the server: \"%s\"\n", buffer);
close(socketFD); // Close the socket
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg) { perror(msg); exit(1); } // Error function used for reporting issues
int main(int argc, char *argv[])
{
int listenSocketFD, establishedConnectionFD, portNumber, charsRead;
socklen_t sizeOfClientInfo;
char buffer[256];
struct sockaddr_in serverAddress, clientAddress;
if (argc < 2) { fprintf(stderr,"USAGE: %s port\n", argv[0]); exit(1); } // Check usage & args
// Set up the address struct for this process (the server)
memset((char *)&serverAddress, '\0', sizeof(serverAddress)); // Clear out the address struct
portNumber = atoi(argv[1]); // Get the port number, convert to an integer from a string
serverAddress.sin_family = AF_INET; // Create a network-capable socket
serverAddress.sin_port = htons(portNumber); // Store the port number
serverAddress.sin_addr.s_addr = INADDR_ANY; // Any address is allowed for connection to this process
// Set up the socket
listenSocketFD = socket(AF_INET, SOCK_STREAM, 0); // Create the socket
if (listenSocketFD < 0) error("ERROR opening socket");
// Enable the socket to begin listening
if (bind(listenSocketFD, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) // Connect socket to port
error("ERROR on binding");
listen(listenSocketFD, 5); // Flip the socket on - it can now receive up to 5 connections
// Accept a connection, blocking if one is not available until one connects
sizeOfClientInfo = sizeof(clientAddress); // Get the size of the address for the client that will connect
establishedConnectionFD = accept(listenSocketFD, (struct sockaddr *)&clientAddress, &sizeOfClientInfo); // Accept
if (establishedConnectionFD < 0) error("ERROR on accept");
// Get the message from the client and display it
memset(buffer, '\0', 256);
charsRead = recv(establishedConnectionFD, buffer, 255, 0); // Read the client's message from the socket
if (charsRead < 0) error("ERROR reading from socket");
printf("SERVER: I received this from the client: \"%s\"\n", buffer);
// Send a Success message back to the client
charsRead = send(establishedConnectionFD, "I am the server, and I got your message", 39, 0); // Send success back
if (charsRead < 0) error("ERROR writing to socket");
close(establishedConnectionFD); // Close the existing socket which is connected to the client
close(listenSocketFD); // Close the listening socket
return 0;
}