+ /* If the -u option is used and we don't know this hostname's server
+ * certificate then just pass through the connection and let the client
+ * verify the server certificate. */
+ if (global_passthrough_unknown) {
+ char path[TLSPROXY_MAX_PATH_LENGTH];
+ FILE *file = NULL;
+
+ if (-2 == server_certificate_file(&file, host, path, sizeof(path))) {
+ /* We've established a connection, tell the client. */
+ fprintf(client_fd, "HTTP/1.0 200 Connection established\r\n");
+ fprintf(client_fd, "\r\n");
+ fflush(client_fd);
+
+ LOG(LOG_DEBUG, "transferring data");
+
+ /* Proxy data between client and server until one side is done
+ * (EOF or error). */
+ transfer_data(client_socket, server_socket);
+
+ LOG(LOG_DEBUG, "finished transferring data");
+
+ goto out;
+ }
+ /* server_certificate_file() may have opened the file, close it. */
+ if (NULL != file) {
+ fclose(file);
+ }
+ }
+
+ /* Initialize TLS client credentials to talk to the server. */
+ result = initialize_tls_session_server(server_socket, &server_session,
+ &server_x509_cred);
+ if (0 != result) {
+ LOG(LOG_WARNING, "initialize_tls_session_server() failed");
+ send_forwarding_failure(client_fd);
+ goto out;
+ }
+ server_session_init = 1;
+
+ LOG(LOG_DEBUG, "starting server TLS handshake");
+
+ /* Try to establish TLS handshake between us and server. */
+ result = gnutls_handshake(server_session);
+ if (GNUTLS_E_SUCCESS != result) {
+ LOG(LOG_WARNING, "server TLS handshake failed: %s",
+ gnutls_strerror(result));
+ send_forwarding_failure(client_fd);
+ goto out;
+ }
+ server_session_started = 1;
+
+ LOG(LOG_DEBUG, "server TLS handshake finished");
+
+ /* Make sure the server certificate is valid and known. */
+ if (0 != verify_tls_connection(server_session, host)) {
+ LOG(LOG_ERROR, "server certificate validation failed!");
+ /* We send the error message over our TLS connection to the client,
+ * but with an invalid certificate. No data is transfered from/to the
+ * target server. */
+ validation_failed = 1;
+ }