Compare commits

..

29 Commits

Author SHA1 Message Date
83e9f761e8 Updated priavcy and added commands (getpass, delpass). 2025-02-28 20:49:33 +00:00
f8a47b5683 Merge branch 'ClientConnect', Added more privacy. 2025-02-28 20:16:18 +00:00
6cff81c1d3 Updated version control. 2025-02-28 20:15:28 +00:00
022c2fb956 Added some privacy when showing all passowords. 2025-02-28 20:14:44 +00:00
9a9f53967c Small update on the binary. 2025-02-28 19:48:53 +00:00
64d4c825d4 Update 0.3 - Better encryption. working server side connections! 2025-02-28 19:46:10 +00:00
4c16c8b953 Finnaly, a working version, optimised! 2025-02-28 19:40:42 +00:00
dfd25f897c Debuging the server responce. 2025-02-28 19:28:30 +00:00
0262a9fdd7 Better encryption method. 2025-02-28 19:08:55 +00:00
0c235ca1d1 Updated executable. 2025-02-27 23:28:46 +00:00
ccb1aa7548 Possible optimisation by requesting how many passwords exist instead of brute forcing all passwords. 2025-02-27 23:26:45 +00:00
2a743c971b Updated to finnaly show existing passwords. 2025-02-27 20:56:00 +00:00
ad2ff3304a Fixed show all passwords. 2025-02-27 20:41:12 +00:00
fafc45b720 Fix error where level wasnt define before request. 2025-02-27 20:27:33 +00:00
79b420fca3 Fixed issue with double free. 2025-02-27 19:56:31 +00:00
1e662ee4ba Major Error in client. 2025-02-27 13:22:09 +00:00
a183733cb0 User can now see retrieved passwords. 2025-02-27 13:04:08 +00:00
142c958fed Client can now create passwords that are stored in the server. 2025-02-27 12:59:18 +00:00
85cb820d03 Made key be a fixed side. 2025-02-27 12:54:28 +00:00
52cf8521bc Fixed issue when calling function. 2025-02-27 12:27:55 +00:00
9195618bb9 Added new method to create password to the server. 2025-02-27 12:20:47 +00:00
30e8a5c292 Updated "prompPassword" to include custom message. 2025-02-27 12:20:27 +00:00
b28be36e42 Implemented way to create a new password and send it to the server. 2025-02-27 12:12:06 +00:00
74e47ea1bf Added the first server request. 2025-02-27 11:59:45 +00:00
a17f7baf0a Created Request in the client side with listen call 2025-02-27 11:24:58 +00:00
d6f9760c54 Added server connection! 2025-02-26 22:50:07 +00:00
58ad5426f5 Fixed to not include the CMAKE stuff 2025-02-26 22:40:41 +00:00
054ca41089 Fixed to not include the CMAKE stuff 2025-02-26 22:36:42 +00:00
1d9af2e13b Fixed to not include the CMAKE stuff 2025-02-26 22:36:05 +00:00
9 changed files with 349 additions and 279 deletions

View File

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

Binary file not shown.

BIN
bin/KeyMaster Executable file

Binary file not shown.

View File

@ -1,7 +1,13 @@
# Description: Build script for KeyMaster
if [ -z "$1" ]; then
echo "Error: Invalid Argument"
echo "Usage: $0 <executable_name>"
exit 1
fi
cd ./build
cmake ..
make
cp "$1" ../bin
cp "KeyMaster_server" ../bin
# DEBUGGING
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 removePTR(ptr, index) ptr[index] = 0 //@param ptr Pointer to remove the value @param index Index of the value to remove
#define remove(ptr, index) ptr[index] = 0 //@param ptr Pointer to remove the value @param index Index of the value to remove
#ifdef __INTELLISENSE__
#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 "dynmem.h"
int prompPassword(char *password)
int prompPassword(char *password, const char *msg)
{
struct termios oldt, newt;
printf("Please enter your unique password:");
printf("%s", msg);
try
{
// Disable echo

View File

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

336
src/main.c Normal file
View File

@ -0,0 +1,336 @@
#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;
}

View File

@ -1,272 +0,0 @@
#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;
}