Compare commits

...

5 Commits

2 changed files with 188 additions and 15 deletions

View File

@@ -5,7 +5,6 @@
## Some of the processing seems similar, so maybe code could be more compact.
## Command line otp -e should go to default pad, and then comment after the fact that it used the default pad.
## There is the problem of the location of the pad revealing metadata about how many messages have been sent in the past, or at least the size of the messsages.
@@ -17,8 +16,10 @@ Or, better yet, assume the offset is a very large size, and use the pad itself t
## We have three different decrypt file functions
## Preferences directory and files look off. Should probably have ~/.otp as the default directory, and then in there we can have otp.conf, pads/
## Setup for multiple USB drives
## Change back in pad menu to exit

198
otp.c
View File

@@ -244,13 +244,68 @@ int command_line_mode(int argc, char* argv[]) {
return generate_pad_with_entropy(size, 1, 0); // No keyboard entropy for command line
}
else if (strcmp(argv[1], "encrypt") == 0 || strcmp(argv[1], "-e") == 0) {
if (argc < 3 || argc > 4) {
printf("Usage: %s encrypt|-e <pad_chksum_or_prefix> [text_to_encrypt]\n", argv[0]);
if (argc < 2 || argc > 4) {
printf("Usage: %s encrypt|-e [pad_chksum_or_prefix] [text_to_encrypt]\n", argv[0]);
return 1;
}
// Pass text if provided, otherwise NULL for interactive mode
const char* text = (argc == 4) ? argv[3] : NULL;
return encrypt_text(argv[2], text);
// Check if pad was specified or use default
const char* pad_identifier = NULL;
const char* text = NULL;
if (argc == 2) {
// Just -e, use default pad, no text (interactive)
pad_identifier = NULL;
text = NULL;
} else if (argc == 3) {
// Could be -e <pad> or -e <text> (using default pad)
// Check if default pad is available to determine interpretation
char* default_pad = get_default_pad_path();
if (default_pad) {
// Default pad available, treat argument as text
pad_identifier = NULL;
text = argv[2];
free(default_pad);
} else {
// No default pad, treat as pad identifier
pad_identifier = argv[2];
text = NULL;
}
} else {
// argc == 4: -e <pad> <text>
pad_identifier = argv[2];
text = argv[3];
}
// If pad_identifier is NULL, we need to use default pad
if (pad_identifier == NULL) {
char* default_pad = get_default_pad_path();
if (default_pad) {
// Extract checksum from default pad path
char* filename = strrchr(default_pad, '/');
if (!filename) filename = default_pad;
else filename++; // Skip the '/'
// Extract checksum (remove .pad extension)
if (strlen(filename) >= 68 && strstr(filename, ".pad")) {
static char default_checksum[65];
strncpy(default_checksum, filename, 64);
default_checksum[64] = '\0';
pad_identifier = default_checksum;
}
free(default_pad);
// Call encrypt_text and then comment about using default pad
int result = encrypt_text(pad_identifier, text);
return result;
} else {
printf("Error: No default pad configured. Specify pad explicitly or configure default pad.\n");
return 1;
}
} else {
// Explicit pad specified, normal operation
return encrypt_text(pad_identifier, text);
}
}
else if (strcmp(argv[1], "decrypt") == 0 || strcmp(argv[1], "-d") == 0) {
if (argc == 2) {
@@ -2668,8 +2723,33 @@ int load_preferences(void) {
while ((entry = readdir(dir)) != NULL && !found_pad) {
if (strstr(entry->d_name, ".pad") && strlen(entry->d_name) == 68) {
// Found a pad file - construct full path
snprintf(first_pad_path, sizeof(first_pad_path), "%s/%s", current_pads_dir, entry->d_name);
// Found a pad file - construct full absolute path
char absolute_path[1024];
if (current_pads_dir[0] == '/') {
// Already absolute path
int ret = snprintf(first_pad_path, sizeof(first_pad_path), "%s/%s", current_pads_dir, entry->d_name);
if (ret >= (int)sizeof(first_pad_path)) {
// Path was truncated, skip this entry
continue;
}
} else {
// Relative path - make it absolute
char current_dir[512];
if (getcwd(current_dir, sizeof(current_dir))) {
int ret = snprintf(first_pad_path, sizeof(first_pad_path), "%s/%s/%s", current_dir, current_pads_dir, entry->d_name);
if (ret >= (int)sizeof(first_pad_path)) {
// Path was truncated, skip this entry
continue;
}
} else {
// Fallback to relative path
int ret = snprintf(first_pad_path, sizeof(first_pad_path), "%s/%s", current_pads_dir, entry->d_name);
if (ret >= (int)sizeof(first_pad_path)) {
// Path was truncated, skip this entry
continue;
}
}
}
strncpy(default_pad_path, first_pad_path, sizeof(default_pad_path) - 1);
default_pad_path[sizeof(default_pad_path) - 1] = '\0';
found_pad = 1;
@@ -2783,7 +2863,29 @@ char* get_default_pad_path(void) {
}
int set_default_pad_path(const char* pad_path) {
return set_preference("default_pad", pad_path);
if (!pad_path) {
return set_preference("default_pad", NULL);
}
// Ensure we store the full absolute path
char absolute_path[1024];
if (pad_path[0] == '/') {
// Already absolute path
strncpy(absolute_path, pad_path, sizeof(absolute_path) - 1);
absolute_path[sizeof(absolute_path) - 1] = '\0';
} else {
// Relative path - make it absolute
char current_dir[512];
if (getcwd(current_dir, sizeof(current_dir))) {
snprintf(absolute_path, sizeof(absolute_path), "%s/%s", current_dir, pad_path);
} else {
// Fallback to using the path as-is if getcwd fails
strncpy(absolute_path, pad_path, sizeof(absolute_path) - 1);
absolute_path[sizeof(absolute_path) - 1] = '\0';
}
}
return set_preference("default_pad", absolute_path);
}
// OTP thumb drive detection function implementation
@@ -3509,7 +3611,7 @@ int handle_pads_menu(void) {
printf("No pads found.\n");
printf("\nOptions:\n");
printf(" \033[4mG\033[0menerate new pad\n");
printf(" \033[4mB\033[0mack to main menu\n");
printf(" E\033[4mx\033[0mit\n");
printf("\nSelect option: ");
char input[10];
@@ -3602,7 +3704,8 @@ int handle_pads_menu(void) {
printf("\nActions:\n");
printf(" \033[4mG\033[0menerate new pad\n");
printf(" \033[4mB\033[0mack to main menu\n");
printf(" \033[4mS\033[0met default pad\n");
printf(" E\033[4mx\033[0mit\n");
printf("\nSelect pad (by prefix) or action: ");
char input[MAX_HASH_LENGTH];
@@ -3620,8 +3723,77 @@ int handle_pads_menu(void) {
return handle_pads_menu();
}
return result;
} else if (toupper(input[0]) == 'B') {
return 0; // Back to main menu
} else if (toupper(input[0]) == 'S') {
// Set default pad
printf("\nSelect pad to set as default (by prefix): ");
char pad_input[MAX_HASH_LENGTH];
if (!fgets(pad_input, sizeof(pad_input), stdin)) {
printf("Error: Failed to read input\n");
return 1;
}
pad_input[strcspn(pad_input, "\n")] = 0;
// Find matching pad by prefix using the same logic as pad selection
int matched_pad = -1;
int match_count = 0;
for (int i = 0; i < pad_count; i++) {
if (strncmp(pad_input, pads[i].chksum, strlen(pad_input)) == 0) {
matched_pad = i;
match_count++;
}
}
if (match_count == 0) {
printf("No pad found matching prefix '%s'\n", pad_input);
return handle_pads_menu();
} else if (match_count > 1) {
printf("Ambiguous prefix. Multiple matches found.\n");
return handle_pads_menu();
}
// Construct the full absolute pad path and set as default
char new_default_path[1024];
if (current_pads_dir[0] == '/') {
// Already absolute path
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
if (ret >= (int)sizeof(new_default_path)) {
printf("Error: Path too long for default pad setting\n");
return handle_pads_menu();
}
} else {
// Relative path - make it absolute
char current_dir[512];
if (getcwd(current_dir, sizeof(current_dir))) {
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s/%s.pad", current_dir, current_pads_dir, pads[matched_pad].chksum);
if (ret >= (int)sizeof(new_default_path)) {
// Path was truncated, fall back to relative path
int ret2 = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
if (ret2 >= (int)sizeof(new_default_path)) {
printf("Error: Path too long for default pad setting\n");
return handle_pads_menu();
}
}
} else {
// Fallback to relative path
int ret = snprintf(new_default_path, sizeof(new_default_path), "%s/%s.pad", current_pads_dir, pads[matched_pad].chksum);
if (ret >= (int)sizeof(new_default_path)) {
printf("Error: Path too long for default pad setting\n");
return handle_pads_menu();
}
}
}
if (set_default_pad_path(new_default_path) == 0) {
printf("Default pad set to: %.16s...\n", pads[matched_pad].chksum);
printf("Full path: %s\n", new_default_path);
} else {
printf("Error: Failed to update default pad preference\n");
}
return handle_pads_menu();
} else if (toupper(input[0]) == 'X') {
return 0; // Exit to main menu
}
// Find matching pad by prefix
@@ -3804,7 +3976,7 @@ void print_usage(const char* program_name) {
printf("Usage:\n");
printf(" %s - Interactive mode\n", program_name);
printf(" %s generate|-g <size> - Generate new pad\n", program_name);
printf(" %s encrypt|-e <pad_checksum_prefix> [text] - Encrypt text\n", program_name);
printf(" %s encrypt|-e [pad_checksum_prefix] [text] - Encrypt text\n", program_name);
printf(" %s decrypt|-d [encrypted_message] - Decrypt message\n", program_name);
printf(" %s -f <file> <pad_prefix> [-a] [-o <out>] - Encrypt file\n", program_name);
printf(" %s list|-l - List available pads\n", program_name);