feat: Add some improvments

This commit is contained in:
2025-04-23 18:26:51 +10:00
parent 49592ed4c0
commit 80abb9e4dd
2 changed files with 80 additions and 24 deletions

View File

@@ -13,6 +13,8 @@
#include <openssl/sha.h> // For SHA256 and SHA512 functions
#include <sys/stat.h> // For mkdir
#include <sys/types.h> // For mkdir
#include <dirent.h> // For directory operations
#include <limits.h> // For PATH_MAX
#include <errno.h> // For errno and EEXIST
#define CA_CERT_FILE "ca/ca_cert.pem"
@@ -103,8 +105,6 @@ static int get_tlsa_records(const char* hostname, tlsa_record** records, int* re
char dns_query[256];
sprintf(dns_query, "_443._tcp.%s", hostname);
printf("Looking up TLSA records for %s\n", dns_query);
// Initialize the record count and records array
*record_count = 0;
*records = NULL;
@@ -114,12 +114,12 @@ static int get_tlsa_records(const char* hostname, tlsa_record** records, int* re
int raw_record_count = 0;
if (query_tlsa_records_doh(hostname, &raw_records, &raw_record_count) != 0 || raw_record_count == 0) {
// If no records found, return that DANE is not available
printf("No TLSA records found for %s\n", hostname);
// If no records found, return silently
return 0;
}
printf("Found %d real TLSA records\n", raw_record_count);
// Only log if TLSA records are found
printf("Found %d TLSA records for %s\n", raw_record_count, hostname);
// Allocate memory for TLSA records
*records = malloc(raw_record_count * sizeof(tlsa_record));
@@ -347,7 +347,7 @@ static int domain_matches_pattern(const char* domain, const char* pattern) {
}
// Validate that a certificate is valid for a given domain
static int validate_cert_domain(X509* cert, const char* hostname) {
static int validate_cert_domain(X509* cert, const char* hostname, int verbose) {
int valid = 0;
// First check the Common Name
@@ -357,9 +357,11 @@ static int validate_cert_domain(X509* cert, const char* hostname) {
X509_NAME_get_text_by_NID(subject_name, NID_commonName, common_name, sizeof(common_name));
if (domain_matches_pattern(hostname, common_name)) {
if (verbose) {
printf("Domain matches certificate Common Name: %s\n", common_name);
}
valid = 1;
} else {
} else if (verbose) {
printf("Domain does not match certificate Common Name: %s\n", common_name);
}
}
@@ -368,7 +370,9 @@ static int validate_cert_domain(X509* cert, const char* hostname) {
STACK_OF(GENERAL_NAME)* san_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
if (san_names) {
int san_count = sk_GENERAL_NAME_num(san_names);
if (verbose) {
printf("Certificate has %d Subject Alternative Names\n", san_count);
}
for (int i = 0; i < san_count; i++) {
const GENERAL_NAME* current_name = sk_GENERAL_NAME_value(san_names, i);
@@ -377,17 +381,19 @@ static int validate_cert_domain(X509* cert, const char* hostname) {
const char* dns_name = (const char*)ASN1_STRING_get0_data(current_name->d.dNSName);
if (domain_matches_pattern(hostname, dns_name)) {
if (verbose) {
printf("Domain matches SAN: %s\n", dns_name);
}
valid = 1;
break;
} else {
} else if (verbose) {
printf("Domain does not match SAN: %s\n", dns_name);
}
}
}
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
} else {
} else if (verbose) {
printf("Certificate has no Subject Alternative Names\n");
}
@@ -406,23 +412,30 @@ int verify_cert_against_dane(const char* hostname, X509* cert) {
return -1;
}
// Verify the certificate domain
domain_verified = validate_cert_domain(cert, hostname);
// Get TLSA records first to determine if we should do verbose logging
int has_tlsa = get_tlsa_records(hostname, &records, &record_count);
if (!has_tlsa || record_count == 0) {
// No TLSA records, return silently
return 0;
}
// Now that we know the domain has TLSA records, do verbose domain validation
domain_verified = validate_cert_domain(cert, hostname, 1);
if (!domain_verified) {
fprintf(stderr, "Certificate is not valid for domain: %s\n", hostname);
// Clean up records
for (int i = 0; i < record_count; i++) {
if (records[i].data) {
free(records[i].data);
}
}
free(records);
return 0;
}
printf("Certificate domain validation successful for: %s\n", hostname);
if (!get_tlsa_records(hostname, &records, &record_count)) {
return -1;
}
if (record_count == 0) {
return 0;
}
// Print records that will be used for verification
printf("\n=== Starting DANE verification for %s ===\n", hostname);
for (int i = 0; i < record_count; i++) {
@@ -528,6 +541,7 @@ static int generate_ca_cert() {
// Check if CA certificate already exists
if (access(CA_CERT_FILE, F_OK) == 0 && access(CA_KEY_FILE, F_OK) == 0) {
printf("CA certificate already exists\n");
// Load the existing CA certificate and key
FILE* ca_cert_file = fopen(CA_CERT_FILE, "r");
if (!ca_cert_file) {
@@ -620,8 +634,8 @@ static int generate_ca_cert() {
// Set certificate information
X509_NAME* name = X509_get_subject_name(ca_cert);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*)"FireProxy", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char*)"Woodburn", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*)"FireProxy CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char*)"FireProxy", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char*)"AU", -1, -1, 0);
// Self-sign the certificate
@@ -825,12 +839,50 @@ int generate_trusted_cert(const char* hostname, const char* cert_path, const cha
return 1;
}
// Function to delete all generated certificates (but not the CA certs)
static void delete_all_generated_certs() {
DIR* dir;
struct dirent* entry;
char path[PATH_MAX];
// Open the certificates directory
dir = opendir(CERT_DIR);
if (!dir) {
perror("Failed to open certificates directory for cleanup");
return;
}
// Read directory entries
while ((entry = readdir(dir)) != NULL) {
// Skip "." and ".." directories
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
// Create full path
snprintf(path, PATH_MAX, "%s/%s", CERT_DIR, entry->d_name);
// Delete the file and log the action
if (unlink(path) == 0) {
printf("Deleted temporary certificate: %s\n", path);
} else {
perror("Failed to delete certificate");
}
}
closedir(dir);
printf("Cleaned up all generated certificates\n");
}
int dane_init() {
init_openssl();
return setup_local_ca();
}
void dane_cleanup() {
// Delete all generated certificates first
delete_all_generated_certs();
// Then clean up CA resources
if (ca_cert) {
X509_free(ca_cert);
ca_cert = NULL;

View File

@@ -710,7 +710,11 @@ void proxy_cleanup() {
void handle_signal(int sig) {
if (sig == SIGINT) {
printf("\nShutting down proxy server...\n");
printf("Cleaning up temporary certificates...\n");
// Clean up DANE resources (which will delete all generated certificates)
proxy_cleanup();
exit(0);
}
}