aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorsrdusr <trevorgray@srdusr.com>2024-03-02 23:01:54 +0200
committersrdusr <trevorgray@srdusr.com>2024-03-02 23:01:54 +0200
commit1bef1bce2517d04902b6ff227eaba8e4f8b483e2 (patch)
treee3df9f0cd553de0099af1558d56ab4ec3470bc4d /main.c
parentf949597968d53ecac62a1fda2738f75f952011c1 (diff)
downloadcerberus-1bef1bce2517d04902b6ff227eaba8e4f8b483e2.tar.gz
cerberus-1bef1bce2517d04902b6ff227eaba8e4f8b483e2.zip
Add log file and password policy
Diffstat (limited to 'main.c')
-rw-r--r--main.c144
1 files changed, 127 insertions, 17 deletions
diff --git a/main.c b/main.c
index c12f0af..aa840b4 100644
--- a/main.c
+++ b/main.c
@@ -1,29 +1,125 @@
// TODO: Secret stored in memory must be encrypted with a key derived from the
// user password or consider making password manager stateless (no passwords
// stored locally)
-// TODO: Replace CBC with GCM or CCM to prevent padding attacks
-// TODO: Have ascii art of a cerberus on start menu/page
#include "main.h"
struct Password passwords[MAX_PASSWORDS];
int numPasswords = 0;
+FILE *log_file;
+
+void log_message(const char *message) {
+ if (log_file == NULL) {
+ printf("Error: Log file not available.\n");
+ return;
+ }
+
+ time_t current_time;
+ struct tm *time_info;
+ char time_string[80];
+
+ time(&current_time);
+ time_info = localtime(&current_time);
+
+ strftime(time_string, sizeof(time_string), "[%Y-%m-%d %H:%M:%S] ", time_info);
+ fprintf(log_file, "%s %s\n", time_string,
+ message); // Print timestamp and message
+}
+
+void initialize_log() {
+ log_file = fopen("cerberus.log", "a");
+ if (log_file == NULL) {
+ printf("Error: Could not open log file.\n");
+ } else {
+ log_message("=== cerberus log ==="); // Initial log message
+ }
+}
+
+void close_log() {
+ if (log_file != NULL) {
+ fclose(log_file);
+ }
+}
+
+void error_exit(const char *error_message) {
+ log_message(error_message);
+ if (log_file != NULL) {
+ fclose(log_file);
+ }
+ exit(1);
+}
+
+void clear_input_buffer() {
+ int c;
+ while ((c = getchar()) != '\n' && c != EOF)
+ ;
+}
+
+void check_password_policy(const char *password) {
+ int length = strlen(password);
+ if (length < 8) {
+ error_exit("Password must be at least 8 characters long.");
+ }
+
+ bool has_upper = false, has_lower = false, has_digit = false,
+ has_special = false;
+ for (int i = 0; i < length; i++) {
+ if (isupper(password[i])) {
+ has_upper = true;
+ } else if (islower(password[i])) {
+ has_lower = true;
+ } else if (isdigit(password[i])) {
+ has_digit = true;
+ } else {
+ has_special = true;
+ }
+ }
+
+ if (!has_upper || !has_lower || !has_digit || !has_special) {
+ error_exit("Password must contain at least one uppercase letter, one "
+ "lowercase letter, one digit, and one special character.");
+ }
+}
+
void generate_password(char *password, int length) {
- // Define the character set for the password
+ if (length < 8 || length > MAX_PASSWORD_LENGTH - 1) {
+ printf("Invalid password length. Please enter a length between 8 and %d.\n",
+ MAX_PASSWORD_LENGTH - 1);
+ return;
+ }
+
char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456"
- "789!@#$%^&*-_=+{}[]|;:',.<>/?";
+ "789!@#$%^&*()-_=+[]{}|;:',.<>?";
int charset_size = strlen(charset);
- // Seed the random number generator
srand(time(NULL));
- for (int i = 0; i < length; i++) {
- int index = rand() % charset_size;
- password[i] = charset[index];
+ // Initialize flags to check if each required character type is included
+ bool has_upper = false, has_lower = false, has_digit = false,
+ has_special = false;
+
+ // Create password with at least one character from each required type
+ password[0] = charset[rand() % 26]; // at least one uppercase letter
+ password[1] = charset[26 + rand() % 26]; // at least one lowercase letter
+ password[2] = charset[52 + rand() % 10]; // at least one digit
+ password[3] = charset[62 + rand() % 14]; // at least one special character
+
+ // Fill the rest of the password randomly from the character set
+ for (int i = 4; i < length; i++) {
+ password[i] = charset[rand() % charset_size];
}
password[length] = '\0';
+
+ // Shuffle the password characters
+ for (int i = 0; i < length; i++) {
+ int j = rand() % length;
+ char temp = password[i];
+ password[i] = password[j];
+ password[j] = temp;
+ }
+
printf("Generated Password: %s\n", password);
}
@@ -221,6 +317,8 @@ void print_ascii_art(const char *filename) {
}
int main() {
+ initialize_log();
+
const char *dir = "tmp"; // Directory to store password files
mkdir(dir, 0700); // Create directory if it doesn't exist
@@ -266,25 +364,33 @@ int main() {
printf("3. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
+ clear_input_buffer(); // Clear input buffer after scanf
switch (choice) {
case 1: {
- if (numPasswords >= MAX_PASSWORDS) {
- printf("Maximum number of passwords reached.\n");
- break;
- }
struct Password password;
int length;
- printf("Enter password length: ");
- scanf("%d", &length);
+ do {
+ printf("Enter password length: ");
+ scanf("%d", &length);
+ clear_input_buffer();
+ if (length < 8 || length > MAX_PASSWORD_LENGTH - 1) {
+ printf("Invalid password length. Please enter a length between 8 and "
+ "%d.\n",
+ MAX_PASSWORD_LENGTH - 1);
+ }
+ } while (length < 8 || length > MAX_PASSWORD_LENGTH - 1);
generate_password(password.password, length);
printf("Enter website: ");
- scanf("%s", password.website);
+ fgets(password.website, sizeof(password.website), stdin);
+ password.website[strcspn(password.website, "\n")] =
+ 0; // Remove newline character
printf("Enter username: ");
- scanf("%s", password.username);
+ fgets(password.username, sizeof(password.username), stdin);
+ password.username[strcspn(password.username, "\n")] =
+ 0; // Remove newline character
save_password(&password, password.website, dir, user_password);
printf("Password information saved to %s\n", password.website);
- passwords[numPasswords++] = password;
break;
}
case 2: {
@@ -292,6 +398,7 @@ int main() {
printf("Enter the number of the password to copy (0 to cancel): ");
int selection;
scanf("%d", &selection);
+ clear_input_buffer();
if (selection > 0 && selection <= numPasswords) {
struct Password selected_password = passwords[selection - 1];
printf("Selected Password:\n");
@@ -302,6 +409,7 @@ int main() {
"cancel): ");
int copy_choice;
scanf("%d", &copy_choice);
+ clear_input_buffer();
switch (copy_choice) {
case 1:
copy_to_clipboard(selected_password.password);
@@ -319,11 +427,13 @@ int main() {
}
case 3:
printf("Exiting program...\n");
+ close_log();
return 0;
default:
printf("Invalid choice. Please enter 1, 2, or 3.\n");
}
}
+ close_log();
return 0;
}