Compare commits

..

39 Commits

Author SHA1 Message Date
e319dc6750 Fixed error. undeclared variable. 2025-02-28 22:03:23 +00:00
5dc71aaa04 Implemented threads for multiple clients. 2025-02-28 22:00:43 +00:00
d7b8f14bbc Improved Privacy and handled better the clients. 2025-02-28 21:35:31 +00:00
b39c012a37 Debuging. 2025-02-28 19:31:45 +00:00
7007bed607 New encryption method on the server side. 2025-02-28 19:11:06 +00:00
eae02d5bf6 Added protocol 3 has a possible request to receive the list of all indeces available. 2025-02-27 23:36:16 +00:00
45e690c24c Optimised by switching to a "switch...case" 2025-02-27 23:31:05 +00:00
a0347a7ca4 Implemented feature that allows users to delete passwords if needed. 2025-02-27 21:10:50 +00:00
e282ff5f7f Another fix. 2025-02-27 20:44:48 +00:00
b69bb44d7e Debuging. 2025-02-27 20:20:03 +00:00
94ab68aeb9 Trying to fix the issue where the server doesnt return the key. 2025-02-27 20:12:36 +00:00
e19555be6c Fixed issue when copying key. 2025-02-27 19:57:56 +00:00
c2bad2ddea Mismach Operations. 2025-02-27 13:19:18 +00:00
7b1875c2b6 Forgot the error handling "throw". 2025-02-27 13:17:43 +00:00
a566c264aa Updated Server to decrypt message before sending. 2025-02-27 13:15:16 +00:00
a66dff2402 Fixed potencial issue. 2025-02-27 13:08:46 +00:00
22353ed869 Trying to fix password issues. 2025-02-27 13:06:33 +00:00
3b1d210a9c Server now returns if it finds a password like the user requested. 2025-02-27 13:01:48 +00:00
a6a4fbf7ac Removing key has a pointer to be a fixed size. 2025-02-27 12:52:17 +00:00
e9983c77c2 FINNALY FOUND THE ISSUE, "key" needs to be initialized before writing (lol). 2025-02-27 12:48:39 +00:00
14c34f503d Yet another try in fixing the segmentation fault. 2025-02-27 12:42:49 +00:00
09a02b66de More debugging. 2025-02-27 12:39:24 +00:00
b8602107b0 Debugging. 2025-02-27 12:36:35 +00:00
328ad3e832 Another attempt at fixing the segmentation fault previously created. 2025-02-27 12:34:27 +00:00
f5740ec35f Fix segmentation fault do to sprintf problems. 2025-02-27 12:31:08 +00:00
4b618b0be9 Fixed memory leak and error while encrypting. 2025-02-27 12:26:01 +00:00
ec3082c527 Fixed typo. (whopps) 2025-02-27 12:24:06 +00:00
e5b8ef71f8 Implemented method to create passwordFile. 2025-02-27 12:23:19 +00:00
a75b7ca352 Small fix to the size of the pathfile. 2025-02-27 12:06:44 +00:00
707cef94a4 Final connection with client. 2025-02-27 12:02:30 +00:00
7e212a99e6 Added response back to client. 2025-02-27 11:53:03 +00:00
3c4243ddcf Added server requests for clients 2025-02-27 11:19:53 +00:00
33fda52f2d Added server request handeling 2025-02-26 22:55:20 +00:00
2321f67457 Added server address for test 2025-02-26 22:45:20 +00:00
cf8e024528 Fixed to not include the CMAKE stuff 2025-02-26 22:39:34 +00:00
438fae4038 Fixed to not include the CMAKE stuff 2025-02-26 22:35:02 +00:00
e8bb3db8bf Created socket to connect 2025-02-26 22:26:25 +00:00
e0663bc38b Created socket to connect 2025-02-26 22:25:15 +00:00
9f41258198 Created the server side 2025-02-26 22:19:44 +00:00
9 changed files with 279 additions and 349 deletions

View File

@ -17,7 +17,7 @@ set(CMAKE_C_STANDARD 17)
# Include header files from the include directory # Include header files from the include directory
include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(${APP_NAME} ${SOURCE}/main.c) add_executable(${APP_NAME}_server ${SOURCE}/server.c)
# Display a message when compiling # Display a message when compiling
message(STATUS "Compiling ${APP_NAME}...") message(STATUS "Compiling ${APP_NAME}...")

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,7 @@
if [ -z "$1" ]; then # Description: Build script for KeyMaster
echo "Error: Invalid Argument"
echo "Usage: $0 <executable_name>"
exit 1
fi
cd ./build cd ./build
cmake .. cmake ..
make make
cp "$1" ../bin
# DEBUGGING cp "KeyMaster_server" ../bin
mv "$1" ../

View File

@ -42,7 +42,7 @@
*/ */
#define add(ptr, index, value) ptr[index] = value //@param ptr Pointer to add the value @param index Index of the value to add @param value Value to add #define add(ptr, index, value) ptr[index] = value //@param ptr Pointer to add the value @param index Index of the value to add @param value Value to add
#define remove(ptr, index) ptr[index] = 0 //@param ptr Pointer to remove the value @param index Index of the value to remove #define removePTR(ptr, index) ptr[index] = 0 //@param ptr Pointer to remove the value @param index Index of the value to remove
#ifdef __INTELLISENSE__ #ifdef __INTELLISENSE__
#define create(type) ((type *)malloc(sizeof(type))) //@param type Type of the vector @example int *vector = create(int); #define create(type) ((type *)malloc(sizeof(type))) //@param type Type of the vector @example int *vector = create(int);

View File

@ -2,11 +2,11 @@
#include "herror.h" #include "herror.h"
#include "dynmem.h" #include "dynmem.h"
int prompPassword(char *password, const char *msg) int prompPassword(char *password)
{ {
struct termios oldt, newt; struct termios oldt, newt;
printf("%s", msg); printf("Please enter your unique password:");
try try
{ {
// Disable echo // Disable echo

View File

@ -8,7 +8,7 @@
#include "ui.c" #include "ui.c"
int prompPassword(char *password, const char *msg); int pomrpPassword(char *password);
char *prompNormalRequest(char *message); char *prompNormalRequest(char *message);
#endif // !UI_H #endif // !UI_H

View File

@ -1,336 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "herror.h"
#include "dynmem.h"
#include "ui/ui.h"
#define PASS_FILE "./files/KEYS.bin"
#define SERVER_IP "192.168.1.120"
#define SERRER_PORT 8080
typedef struct Request
{
unsigned char type;
char key[256];
int ID;
int level;
} Request;
void clear_input_buffer(void)
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}
int main(void)
{
char *password = create(char);
password = size(password, 256);
if (password == NULL)
{
fprintf(stderr, "Memory allocation failure\n");
return 1;
}
int fP = readl(PASS_FILE, password, strlen(password));
if (fP == -1)
{
printf("Couldnt find the password file\nWould you like to create a new one? (y/n): ");
char c;
scanf("%c", &c);
clear_input_buffer();
if (c == 'y' || c == 'Y')
{
if (prompPassword(password, "Please enter your unique password: ") == -1)
{
return 1;
}
printf("\n");
int *buffer = create(int);
buffer = size(buffer, 256);
encryptText(buffer, password);
writel(PASS_FILE, buffer, 256);
free(buffer);
}
else
{
return 0;
}
}
printf("KeyMaster\nVersion: 0.3.1\n\n");
try
{
int *key = create(int);
key = size(key, 256);
if (key == NULL)
{
throw(MEMORY_ALLOC_FAILURE);
}
readl(PASS_FILE, key, 256) == -1 ? throw(FILE_NOT_FOUND) : 0;
decryptText(password, key);
char *askedPass = create(char);
askedPass = size(askedPass, 256);
if (askedPass == NULL)
{
throw(MEMORY_ALLOC_FAILURE);
}
for (size_t i = 0; i < 4; i++)
{
prompPassword(askedPass, "Please enter your unique password: ");
if (strcmp(password, askedPass) != 0)
{
printf("Invalid password, tries left: %zu\n", 2 - i);
}
else
{
break;
}
if (i == 2)
{
printf("Too many tries, exiting...\n");
return 1;
}
}
printf("Welcome to KeyMaster\n");
free(askedPass);
free(key);
}
catch (MEMORY_ALLOC_FAILURE)
{
fprintf(stderr, "Memory allocation failure\n");
return 1;
}
catch (FILE_NOT_FOUND)
{
fprintf(stderr, "Couldnt find the password file or its empty\n");
return 1;
}
end_try;
char *choice = NULL;
try
{
choice = create(char);
choice = size(choice, 256);
if (choice == NULL)
{
throw(MEMORY_ALLOC_FAILURE);
}
}
catch (MEMORY_ALLOC_FAILURE)
{
fprintf(stderr, "Memory allocation failure\n");
return 1;
}
end_try;
// Connect to the server
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
fprintf(stderr, "Socket creation failed\n");
return 1;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERRER_PORT);
servaddr.sin_addr.s_addr = inet_addr(SERVER_IP);
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
{
fprintf(stderr, "Connection to the server failed\n");
return 1;
}
// Menu loop
while (1)
{
printf("\nList of existing passwords:\n<------->\n");
Request req;
// send request with type 3 to get IDs for all passwords
// level == how many keys are being sent
// key == the list of levels that have keys
req.type = 3;
memset(&req.key, 0, sizeof(req.key));
req.ID = 1;
req.level = 0;
send(sockfd, &req, sizeof(req), 0);
recv(sockfd, &req, sizeof(req), 0);
if (req.level == -1)
{
printf("No passwords found\n");
}
else
{
// Debug the response
for (size_t i = 0; i < req.level; i++)
{
Request req1;
req1.type = 0;
memset(&req1.key, 0, sizeof(req1.key));
req1.ID = 1;
req1.level = req.key[i];
send(sockfd, &req1, sizeof(req1), 0);
recv(sockfd, &req1, sizeof(req1), 0);
if (req1.level != -1 && strlen(req1.key) > 0)
{
char hidden_key[256] = {0};
strncpy(hidden_key, req1.key, 6);
if (strlen(req1.key) > 6)
{
hidden_key[5] = '<';
for (size_t i = 6; i < strlen(req1.key); i++)
{
hidden_key[i] = '.';
}
hidden_key[strlen(req1.key) - 1] = '>';
}
printf("Level: %d\tKey: %s\n", req1.level, hidden_key);
}
}
}
printf("<------->\n\n");
choice = prompNormalRequest(">> ");
if (strcmp(choice, "exit") == 0 || strcmp(choice, "quit") == 0 || strcmp(choice, "q") == 0)
{
break;
}
else if (strcmp(choice, "addpass") == 0)
{
char *aux = create(char);
aux = size(aux, 256);
prompPassword(aux, "Please enter your new password: ");
printf("\n");
char *aux2 = create(char);
aux2 = size(aux2, 256);
prompPassword(aux2, "Confirm new password: ");
printf("\n");
if (strcmp(aux, aux2) != 0)
{
printf("Passwords do not match\nStopping...\n");
free(aux);
free(aux2);
continue;
}
printf("Please enter the level of security for the password (1-255) (higher = more complexity): ");
int level;
scanf("%d", &level);
clear_input_buffer();
if (level < 0 && level > 255)
{
printf("Invalid level of security\nStopping...\n");
free(aux);
free(aux2);
continue;
}
// send request with TYPE = 1
req.type = 1;
for (size_t i = 0; i < 256; i++)
{
req.key[i] = aux[i];
}
req.key[sizeof(req.key) - 1] = '\0'; // Ensure null-termination
req.ID = 1;
req.level = level;
send(sockfd, &req, sizeof(req), 0);
free(aux);
free(aux2);
}
else if (strcmp(choice, "delpass") == 0)
{
printf("Please enter the level of security for the password to delete (1-255): ");
int level;
scanf("%d", &level);
clear_input_buffer();
if (level < 0 && level > 255)
{
printf("Invalid level of security\nStopping...\n");
continue;
}
// send request with TYPE = 2
req.type = 2;
memset(&req.key, 0, sizeof(req.key));
req.ID = 1;
req.level = level;
send(sockfd, &req, sizeof(req), 0);
}
else if (strcmp(choice, "getpass") == 0)
{
printf("Please enter the level of security for the password to get (1-255): ");
int level;
scanf("%d", &level);
clear_input_buffer();
if (level < 0 && level > 255)
{
printf("Invalid level of security\nStopping...\n");
continue;
}
// send request with TYPE = 0
req.type = 0;
memset(&req.key, 0, sizeof(req.key));
req.ID = 1;
req.level = level;
send(sockfd, &req, sizeof(req), 0);
recv(sockfd, &req, sizeof(req), 0);
if (req.level != -1 && strlen(req.key) > 0)
{
printf("Password: %s\n", req.key);
}
else
{
printf("\nPassword not found\n");
}
}
else
{
printf("Invalid command (%s)\n\"Q\" or \"quit\" or \"exit\" to close the program\n", choice);
}
}
// Close the socket
close(sockfd);
free(choice);
free(password);
return 0;
}

272
src/server.c Normal file
View File

@ -0,0 +1,272 @@
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include "herror.h"
#include "dynmem.h"
#include "ui/ui.h"
#define SERVER_IP "192.168.1.120"
#define PASSWORDS "./files/USER_PASSWORDS_L"
int sockfd;
typedef struct Request
{
unsigned char type;
char key[256];
int ID;
int level;
} Request;
void *handle_client(void *arg)
{
int connfd = *(int *)arg;
free(arg);
Request req;
while (1)
{
int n = recv(connfd, &req, sizeof(req), 0);
if (n <= 0)
{
fprintf(stderr, "Client disconnected\n");
close(connfd);
pthread_exit(NULL);
}
// debug
printf("Received request\n");
switch (req.type)
{
case 0:
{
// debug
Request aux;
printf("Received request type 0\n");
char *filepath = create(char);
filepath = size(filepath, 256);
sprintf(filepath, "%s%d.bin", PASSWORDS, req.level);
printf("Reading key from file: %s\n", filepath);
int *buffer = NULL;
try
{
buffer = create(int);
buffer = size(buffer, 256);
}
catch (MEMORY_ALLOC_FAILURE)
{
fprintf(stderr, "Memory allocation failed\n");
close(sockfd);
return NULL;
}
end_try;
int i = readl(filepath, buffer, 256);
if (i == -1)
{
aux.ID = req.ID;
memset(&req, 0, sizeof(req));
aux.type = req.type;
aux.level = -1;
send(connfd, &aux, sizeof(aux), 0);
}
// debug
printf("Sending key: [%x]\n", buffer[0]);
char sendKEY[256];
decryptText(sendKEY, buffer);
aux.ID = req.ID;
for (size_t i = 0; i < 256; i++)
{
aux.key[i] = sendKEY[i];
}
aux.level = req.level;
aux.type = req.type;
send(connfd, &aux, sizeof(aux), 0);
free(filepath);
break;
}
case 1:
{
// debug
printf("Received request type 1\n");
char filepath[256];
printf("Received key: [%x]\n", req.key[0]);
printf("Received level: %d\n", req.level);
sprintf(filepath, "%s%d.bin", PASSWORDS, req.level);
printf("Writing key to file: %s\n", filepath);
int key2[256];
encryptText(key2, req.key);
writel(filepath, key2, 256);
break;
}
case 2:
{
// debug
printf("Received request type 2\n");
char filepath[256];
printf("Received key: [%x]\n", req.key[0]);
printf("Received level: %d\n", req.level);
sprintf(filepath, "%s%d.bin", PASSWORDS, req.level);
printf("Deleting key from file: %s\n", filepath);
if (remove(filepath) != 0)
{
fprintf(stderr, "Error deleting file\n");
}
break;
}
case 3:
{
// Return the client with
// level == how many keys are being sent
// key == the list of levels that have keys
// debug
printf("Received request type 3\n");
Request aux;
aux.ID = req.ID;
aux.type = req.type;
FILE *file;
int levelCount = 0;
char levels[256] = {0};
for (int i = 0; i < 256; i++)
{
char filepath[256];
sprintf(filepath, "%s%d.bin", PASSWORDS, i);
file = fopen(filepath, "r");
if (file != NULL)
{
levels[levelCount] = i;
levelCount++;
fclose(file);
}
}
aux.level = levelCount;
memcpy(aux.key, levels, 256);
// debug
printf("Sending response\n");
printf("Level: %d\tKey: [%x]\n", aux.level, aux.key[0]);
send(connfd, &aux, sizeof(aux), 0);
break;
}
default:
fprintf(stderr, "Invalid request type\n");
break;
}
}
return NULL;
}
int main(void)
{
// Connect and bind to a port (8080) on the server
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
fprintf(stderr, "Socket creation failed\n");
return 1;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8080);
servaddr.sin_addr.s_addr = inet_addr(SERVER_IP);
if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
{
fprintf(stderr, "Socket bind failed\n");
close(sockfd);
return 1;
}
if (listen(sockfd, 5) != 0)
{
fprintf(stderr, "Listen failed\n");
close(sockfd);
return 1;
}
printf("Server listening on %s:8080\n", SERVER_IP);
struct sockaddr_in cli;
u_int32_t len = sizeof(cli);
Request req;
memset(&req, 0, sizeof(req));
req.ID = 0;
req.level = 0;
req.type = 0;
u_int8_t isConnected = 0;
int connfd;
/*
* WE NEED TO IMPLEMENT A WAY TO HANDLE MULTIPLE CLIENTS
* AND MAKE IT SABLE (RIGHT NOW IT CRASHES EVERY TIME A CLIENT DISCONNECTS)
*
* ALSO MAKE A BETTER WAY OF STOPPING THE SERVER
*
* TODO:
* -1 Fix the chashing issues --DONE
* -2 Implement a way to stop the server
* -3 Implement a way to handle multiple clients --TESTING
*/
// Listen to the client requests
while (1)
{
int *connfd = malloc(sizeof(int));
*connfd = accept(sockfd, (struct sockaddr *)&cli, &len);
if (*connfd < 0)
{
fprintf(stderr, "Server accept failed\n");
free(connfd);
continue;
}
printf("Client connected\n");
pthread_t tid;
pthread_create(&tid, NULL, handle_client, connfd);
pthread_detach(tid);
}
// Close the socket
close(connfd);
close(sockfd);
return 0;
}