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) {
|
if (has_dane) {
|
||||||
printf("DANE records found for %s, will verify certificate\n", hostname);
|
printf("DANE records found for %s, will verify certificate\n", hostname);
|
||||||
|
|
||||||
char cert_path[256];
|
// First, establish a connection to the server to get its certificate
|
||||||
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
|
|
||||||
SSL_CTX* server_ctx = SSL_CTX_new(TLS_client_method());
|
SSL_CTX* server_ctx = SSL_CTX_new(TLS_client_method());
|
||||||
if (!server_ctx) {
|
if (!server_ctx) {
|
||||||
fprintf(stderr, "Failed to create server SSL context\n");
|
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);
|
handle_regular_https_tunnel(client_sock, server_sock);
|
||||||
return;
|
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");
|
fprintf(stderr, "SSL connection to server failed\n");
|
||||||
SSL_free(server_ssl);
|
SSL_free(server_ssl);
|
||||||
SSL_CTX_free(server_ctx);
|
SSL_CTX_free(server_ctx);
|
||||||
SSL_CTX_free(client_ctx->ctx);
|
|
||||||
free(client_ctx);
|
|
||||||
handle_regular_https_tunnel(client_sock, server_sock);
|
handle_regular_https_tunnel(client_sock, server_sock);
|
||||||
return;
|
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");
|
fprintf(stderr, "Failed to get server certificate\n");
|
||||||
SSL_free(server_ssl);
|
SSL_free(server_ssl);
|
||||||
SSL_CTX_free(server_ctx);
|
SSL_CTX_free(server_ctx);
|
||||||
SSL_CTX_free(client_ctx->ctx);
|
|
||||||
free(client_ctx);
|
|
||||||
handle_regular_https_tunnel(client_sock, server_sock);
|
handle_regular_https_tunnel(client_sock, server_sock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the certificate against DANE
|
// Verify the certificate against DANE
|
||||||
int dane_verified = verify_cert_against_dane(hostname, server_cert);
|
int dane_verified = verify_cert_against_dane(hostname, server_cert);
|
||||||
|
|
||||||
|
// If DANE verification fails, don't generate our own certificate
|
||||||
if (dane_verified <= 0) {
|
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);
|
X509_free(server_cert);
|
||||||
SSL_free(server_ssl);
|
SSL_free(server_ssl);
|
||||||
SSL_CTX_free(server_ctx);
|
SSL_CTX_free(server_ctx);
|
||||||
SSL_CTX_free(client_ctx->ctx);
|
|
||||||
free(client_ctx);
|
|
||||||
handle_regular_https_tunnel(client_sock, server_sock);
|
handle_regular_https_tunnel(client_sock, server_sock);
|
||||||
return;
|
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
|
// Send 200 Connection Established to the client
|
||||||
const char* success_response = "HTTP/1.1 200 Connection Established\r\n\r\n";
|
const char* success_response = "HTTP/1.1 200 Connection Established\r\n\r\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user