aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c349
1 files changed, 175 insertions, 174 deletions
diff --git a/main.c b/main.c
index e1c35e2..9c91520 100644
--- a/main.c
+++ b/main.c
@@ -1,197 +1,198 @@
-// TODO: Fix not specifying password length
-// TODO: Fix not specifying password options for which characters/digits/lowercase or uppercase letters
-// TODO: Fix generated encryption key must not be put in directly by user
-// TODO: Use PBKDF2 for generating keys,
-// 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: 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/aes.h>
+#include "main.h"
-#define MAX_PASSWORD_LENGTH 128
-#define AES_KEY_SIZE 256 / 8
-
-struct Password {
- char website[128];
- char username[128];
- char password[MAX_PASSWORD_LENGTH];
- char notes[256];
-};
+struct Password passwords[MAX_PASSWORDS];
+int numPasswords = 0;
void generate_password(char *password, int length) {
- // Generate a random password of the specified length
- // using a combination of upper and lowercase letters, digits, and special characters
- char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}\\|;:'\",.<>/?";
- int charset_size = strlen(charset);
-
- for (int i = 0; i < length; i++) {
- int index = rand() % charset_size;
- password[i] = charset[index];
- }
-
- password[length] = '\0';
-}
-
-void encrypt_password(struct Password *password, unsigned char *key) {
- AES_KEY aes_key;
- unsigned char iv[AES_BLOCK_SIZE];
- unsigned char encrypted_password[MAX_PASSWORD_LENGTH];
-
-
- // Generate a random initialization vector
- RAND_bytes(iv, AES_BLOCK_SIZE);
+ // Define the character set for the password
+ char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456"
+ "789!@#$%^&*-_=+{}[]|;:',.<>/?";
+ int charset_size = strlen(charset);
- // Initialize the encryption key
- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
- EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+ // Seed the random number generator
+ srand(time(NULL));
- // Encrypt the password using AES-256 encryption
- int outlen, tmplen;
- EVP_EncryptUpdate(ctx, encrypted_password, &outlen, (unsigned char*)password->password, MAX_PASSWORD_LENGTH);
- EVP_EncryptFinal_ex(ctx, encrypted_password + outlen, &tmplen);
+ for (int i = 0; i < length; i++) {
+ int index = rand() % charset_size;
+ password[i] = charset[index];
+ }
- // Copy the encrypted password and IV back into the password struct
- memcpy(password->password, encrypted_password, AES_BLOCK_SIZE);
- memcpy(password->notes, iv, AES_BLOCK_SIZE);
-
- // Clean up
- EVP_CIPHER_CTX_free(ctx);
+ password[length] = '\0'; // Null-terminate the password
+ printf("Generated Password: %s\n", password);
}
-void decrypt_password(struct Password *password, unsigned char *key) {
- EVP_CIPHER_CTX *ctx;
- unsigned char iv[AES_BLOCK_SIZE];
- unsigned char decrypted_password[MAX_PASSWORD_LENGTH]; // change the buffer size to match the size of the password field in the struct
-
- // Read the initialization vector from the password struct
- memcpy(iv, password->notes, AES_BLOCK_SIZE);
-
- // Initialize the decryption context
- ctx = EVP_CIPHER_CTX_new();
- EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
-
- // Decrypt the password using AES-256 decryption
- int outlen, tmplen;
- EVP_DecryptUpdate(ctx, decrypted_password, &outlen, (unsigned char*)password->password, AES_BLOCK_SIZE);
- EVP_DecryptFinal_ex(ctx, decrypted_password + outlen, &tmplen);
-
- // Copy the decrypted password back into the password struct
- memcpy(password->password, decrypted_password, MAX_PASSWORD_LENGTH);
-
- // Clean up
- EVP_CIPHER_CTX_free(ctx);
+void save_password(struct Password *password, const char *dir) {
+ // Save the password information to a file
+ FILE *fp;
+ char filename[256];
+ snprintf(filename, sizeof(filename), "%s/%s.dat", dir, password->website);
+ fp = fopen(filename, "wb");
+ if (fp == NULL) {
+ printf("Error: could not open file %s for writing.\n", filename);
+ return;
+ }
+
+ // Write the password to the file
+ fwrite(password, sizeof(struct Password), 1, fp);
+
+ fclose(fp);
}
-void save_password(struct Password *password, char *filename, unsigned char *key) {
- // Save the password information to a file in an encrypted format using AES-256 encryption
- FILE *fp = fopen(filename, "wb");
- if (fp == NULL) {
- printf("Error: could not open file %s for writing.\n", filename);
- return;
+void load_passwords(const char *dir) {
+ printf("Available Passwords:\n");
+ DIR *d;
+ struct dirent *dir_entry;
+ d = opendir(dir);
+ if (d) {
+ int count = 0;
+ while ((dir_entry = readdir(d)) != NULL) {
+ if (dir_entry->d_type == DT_REG) { // If it's a regular file
+ char filename[256];
+ snprintf(filename, sizeof(filename), "%s/%s", dir, dir_entry->d_name);
+ FILE *file = fopen(filename, "rb");
+ if (file != NULL) {
+ struct Password password;
+ fread(&password, sizeof(struct Password), 1, file);
+
+ // Null-terminate the strings
+ password.website[MAX_WEBSITE_LENGTH - 1] = '\0';
+ password.username[MAX_USERNAME_LENGTH - 1] = '\0';
+ password.password[MAX_PASSWORD_LENGTH - 1] = '\0';
+
+ passwords[count++] = password;
+ printf("%d. Website: %s, Username: %s\n", count, password.website,
+ password.username);
+ fclose(file);
+ }
+ }
}
-
- // Encrypt the password information
- encrypt_password(password, key);
-
- // Write the encrypted password information to the file
- fwrite(password, sizeof(struct Password), 1, fp);
-
- fclose(fp);
-}
-
-void load_password(struct Password *password, char *filename, unsigned char *key) {
- // Load the password information from a file and decrypt it using AES-256 decryption
- // Open the file for reading
- FILE *file = fopen(filename, "rb");
- if (file == NULL) {
- printf("Error: Could not open file %s\n", filename);
- return;
+ numPasswords = count;
+ closedir(d);
+ if (count == 0) {
+ printf("No passwords found.\n");
}
+ }
+}
- // Read the encrypted password information from the file
- unsigned char iv[AES_BLOCK_SIZE];
- fread(iv, 1, AES_BLOCK_SIZE, file);
- unsigned char encrypted[sizeof(struct Password)];
- fread(encrypted, 1, sizeof(struct Password), file);
-
- // Decrypt the password information
- AES_KEY aes_key;
- EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
- EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
- int outlen, finallen;
- EVP_DecryptUpdate(ctx, (unsigned char*)password, &outlen, encrypted, sizeof(struct Password));
- EVP_DecryptFinal_ex(ctx, ((unsigned char*)password) + outlen, &finallen);
- EVP_CIPHER_CTX_free(ctx);
-
- // Close the file
- fclose(file);
+void copy_to_clipboard(char *text) {
+ // Use xclip command to copy text to clipboard
+ FILE *pipe = popen("xclip -selection clipboard", "w");
+ if (pipe != NULL) {
+ fprintf(pipe, "%s", text);
+ pclose(pipe);
+ printf("Copied to clipboard: %s\n", text);
+ } else {
+ printf("Error: Could not copy to clipboard.\n");
+ }
}
int main() {
- int choice;
- char filename[256];
- struct Password password;
- unsigned char key[AES_BLOCK_SIZE];
-
- // Get the encryption key from the user
- printf("Enter the encryption key: ");
- char key_str[AES_BLOCK_SIZE];
- printf("Enter the encryption key: ");
- fgets(key_str, AES_BLOCK_SIZE, stdin);
- for (int i = 0; i < AES_BLOCK_SIZE; i++) {
- key[i] = (unsigned char) key_str[i];
+ const char *dir = "tmp"; // Directory to store password files
+ mkdir(dir, 0700); // Create directory if it doesn't exist
+
+ char user_password[MAX_PASSWORD_LENGTH];
+
+ FILE *key_file = fopen("master.key", "rb");
+ if (key_file == NULL) {
+ printf("Enter your new master password: ");
+ fgets(user_password, sizeof(user_password), stdin);
+ user_password[strcspn(user_password, "\n")] = 0; // Remove newline character
+
+ // Save master password to file
+ key_file = fopen("master.key", "wb");
+ if (key_file == NULL) {
+ printf("Error: Could not create master password file.\n");
+ return 1;
}
-
- // Loop until the user chooses to exit the program
- do {
- // Display the menu of options to the user
- printf("\n1. Generate new password\n");
- printf("2. Save password information to file\n");
- printf("3. Load password information from file\n");
- printf("4. Exit program\n\n");
- printf("Enter your choice: ");
- scanf("%d", &choice);
-
- switch (choice) {
- case 1:
- // Generate a new password and display it to the user
- generate_password(password.password, MAX_PASSWORD_LENGTH);
- printf("New password: %s\n", password.password);
- break;
- case 2:
- // Get the filename from the user and save the password information to a file
- printf("Enter the filename to save to: ");
- scanf("%s", filename);
- save_password(&password, filename, key);
- printf("Password information saved to %s\n", filename);
- break;
- case 3:
- // Get the filename from the user and load the password information from a file
- printf("Enter the filename to load from:");
- scanf("%s", filename);
- load_password(&password, filename, key);
- printf("Password information loaded from %s\n", filename);
- // Display the password information to the user
- printf("Website: %s\n", password.website);
- printf("Username: %s\n", password.username);
- printf("Password: %s\n", password.password);
- printf("Notes: %s\n", password.notes);
- break;
- case 4:
- // Exit the program
- printf("Exiting program...\n");
- break;
- default:
- // Invalid choice
- printf("Invalid choice. Please enter a number between 1 and 4.\n");
- break;
+ fwrite(user_password, sizeof(user_password), 1, key_file);
+ fclose(key_file);
+ } else {
+ // If master key exists, ask for the password
+ printf("Enter your master password: ");
+ fgets(user_password, sizeof(user_password), stdin);
+ user_password[strcspn(user_password, "\n")] = 0; // Remove newline character
+
+ // Check if the entered password matches the stored master password
+ char stored_password[MAX_PASSWORD_LENGTH];
+ fread(stored_password, sizeof(stored_password), 1, key_file);
+ fclose(key_file);
+ if (strcmp(user_password, stored_password) != 0) {
+ printf("Invalid master password. Exiting...\n");
+ return 1;
+ }
+ }
+
+ int choice;
+ while (1) {
+ printf("\n1. Create New Password\n");
+ printf("2. Show Passwords\n");
+ printf("3. Exit\n");
+ printf("Enter your choice: ");
+ scanf("%d", &choice);
+
+ 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);
+ generate_password(password.password, length);
+ printf("Enter website: ");
+ scanf("%s", password.website);
+ printf("Enter username: ");
+ scanf("%s", password.username);
+ save_password(&password, dir);
+ printf("Password information saved to %s\n", password.website);
+ passwords[numPasswords++] = password;
+ break;
+ }
+ case 2: {
+ load_passwords(dir);
+ printf("Enter the number of the password to copy (0 to cancel): ");
+ int selection;
+ scanf("%d", &selection);
+ if (selection > 0 && selection <= numPasswords) {
+ struct Password selected_password = passwords[selection - 1];
+ printf("Selected Password:\n");
+ printf("- Website: %s\n", selected_password.website);
+ printf("- Username: %s\n", selected_password.username);
+ printf("- Password: %s\n", selected_password.password);
+ printf("Copy to clipboard? (1 for Password, 2 for Username, 0 to "
+ "cancel): ");
+ int copy_choice;
+ scanf("%d", &copy_choice);
+ switch (copy_choice) {
+ case 1:
+ copy_to_clipboard(selected_password.password);
+ break;
+ case 2:
+ copy_to_clipboard(selected_password.username);
+ break;
+ default:
+ printf("Canceled.\n");
}
- } while (choice != 4);
+ } else if (selection != 0) {
+ printf("Invalid selection.\n");
+ }
+ break;
+ }
+ case 3:
+ printf("Exiting program...\n");
+ return 0;
+ default:
+ printf("Invalid choice. Please enter 1, 2, or 3.\n");
+ }
+ }
- return 0;
+ return 0;
}