fix: Ignore cert for mismatched TLSA
This commit is contained in:
92
src/proxy.c
92
src/proxy.c
@@ -152,34 +152,10 @@ void handle_https_tunnel(int client_sock, int server_sock, const char* hostname,
|
||||
if (has_dane) {
|
||||
printf("DANE records found for %s, will verify certificate\n", hostname);
|
||||
|
||||
char cert_path[256];
|
||||
char key_path[256];
|
||||
|
||||
snprintf(cert_path, sizeof(cert_path), "certs/%s.crt", hostname);
|
||||
snprintf(key_path, sizeof(key_path), "certs/%s.key", hostname);
|
||||
|
||||
// Generate a trusted certificate for this domain
|
||||
if (!generate_trusted_cert(hostname, cert_path, key_path)) {
|
||||
fprintf(stderr, "Failed to generate trusted certificate for %s\n", hostname);
|
||||
// Fall back to regular tunneling
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize SSL context with our certificate
|
||||
ssl_context_t* client_ctx = init_ssl_context(cert_path, key_path);
|
||||
if (!client_ctx) {
|
||||
fprintf(stderr, "Failed to initialize SSL context\n");
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Connect to the server with SSL to verify DANE
|
||||
// First, establish a connection to the server to get its certificate
|
||||
SSL_CTX* server_ctx = SSL_CTX_new(TLS_client_method());
|
||||
if (!server_ctx) {
|
||||
fprintf(stderr, "Failed to create server SSL context\n");
|
||||
SSL_CTX_free(client_ctx->ctx);
|
||||
free(client_ctx);
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
@@ -195,8 +171,6 @@ void handle_https_tunnel(int client_sock, int server_sock, const char* hostname,
|
||||
fprintf(stderr, "SSL connection to server failed\n");
|
||||
SSL_free(server_ssl);
|
||||
SSL_CTX_free(server_ctx);
|
||||
SSL_CTX_free(client_ctx->ctx);
|
||||
free(client_ctx);
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
@@ -207,26 +181,78 @@ void handle_https_tunnel(int client_sock, int server_sock, const char* hostname,
|
||||
fprintf(stderr, "Failed to get server certificate\n");
|
||||
SSL_free(server_ssl);
|
||||
SSL_CTX_free(server_ctx);
|
||||
SSL_CTX_free(client_ctx->ctx);
|
||||
free(client_ctx);
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify the certificate against DANE
|
||||
int dane_verified = verify_cert_against_dane(hostname, server_cert);
|
||||
|
||||
// If DANE verification fails, don't generate our own certificate
|
||||
if (dane_verified <= 0) {
|
||||
fprintf(stderr, "DANE verification failed for %s\n", hostname);
|
||||
fprintf(stderr, "DANE verification failed for %s - using direct tunneling\n", hostname);
|
||||
X509_free(server_cert);
|
||||
SSL_free(server_ssl);
|
||||
SSL_CTX_free(server_ctx);
|
||||
|
||||
// Clean up and reconnect without interception
|
||||
close(server_sock);
|
||||
|
||||
// Create a new socket connection to the server
|
||||
int new_server_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (new_server_sock < 0) {
|
||||
perror("Cannot create new socket to server");
|
||||
close(client_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in server_addr;
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = inet_addr(ip_addr);
|
||||
server_addr.sin_port = htons(443);
|
||||
|
||||
if (connect(new_server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
|
||||
perror("Cannot reconnect to server");
|
||||
close(new_server_sock);
|
||||
close(client_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use regular tunneling without interception
|
||||
handle_regular_https_tunnel(client_sock, new_server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("DANE verification successful for %s - generating trusted certificate\n", hostname);
|
||||
|
||||
// Now we can generate a trusted certificate for this domain
|
||||
char cert_path[256];
|
||||
char key_path[256];
|
||||
|
||||
snprintf(cert_path, sizeof(cert_path), "certs/%s.crt", hostname);
|
||||
snprintf(key_path, sizeof(key_path), "certs/%s.key", hostname);
|
||||
|
||||
// Generate a trusted certificate for this domain
|
||||
if (!generate_trusted_cert(hostname, cert_path, key_path)) {
|
||||
fprintf(stderr, "Failed to generate trusted certificate for %s\n", hostname);
|
||||
X509_free(server_cert);
|
||||
SSL_free(server_ssl);
|
||||
SSL_CTX_free(server_ctx);
|
||||
SSL_CTX_free(client_ctx->ctx);
|
||||
free(client_ctx);
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("DANE verification successful for %s\n", hostname);
|
||||
// Initialize SSL context with our certificate
|
||||
ssl_context_t* client_ctx = init_ssl_context(cert_path, key_path);
|
||||
if (!client_ctx) {
|
||||
fprintf(stderr, "Failed to initialize SSL context\n");
|
||||
X509_free(server_cert);
|
||||
SSL_free(server_ssl);
|
||||
SSL_CTX_free(server_ctx);
|
||||
handle_regular_https_tunnel(client_sock, server_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send 200 Connection Established to the client
|
||||
const char* success_response = "HTTP/1.1 200 Connection Established\r\n\r\n";
|
||||
|
||||
Reference in New Issue
Block a user