Bump copyright
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 3101cbc..0ca5b5d 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -5,8 +5,8 @@
  * Purpose     :  Main file.  Contains main() method, main loop, and
  *                the main connection-handling function.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2018 the
- *                Privoxy team. http://www.privoxy.org/
+ * Copyright   :  Written by and Copyright (C) 2001-2020 the
+ *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and
@@ -194,11 +194,11 @@ privoxy_mutex_t log_init_mutex;
 privoxy_mutex_t connection_reuse_mutex;
 
 #ifdef LIMIT_MUTEX_NUMBER
-   privoxy_mutex_t certificates_mutexes[32];
+privoxy_mutex_t certificates_mutexes[32];
 #else
-   privoxy_mutex_t certificates_mutexes[65536];
+privoxy_mutex_t certificates_mutexes[65536];
 #endif /* LIMIT_MUTEX_NUMBER */
-   privoxy_mutex_t rng_mutex;
+privoxy_mutex_t rng_mutex;
 
 #ifdef FEATURE_EXTERNAL_FILTERS
 privoxy_mutex_t external_filter_mutex;
@@ -2015,6 +2015,59 @@ static int send_http_request(struct client_state *csp)
 
 
 #ifdef FEATURE_HTTPS_FILTERING
+/*********************************************************************
+ *
+ * Function    : receive_and_send_encrypted_post_data
+ *
+ * Description : Reads remaining POST data from the client and sends
+ *               it to the server.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 on success, anything else is an error.
+ *
+ *********************************************************************/
+static jb_err receive_and_send_encrypted_post_data(struct client_state *csp)
+{
+   unsigned char buf[BUFFER_SIZE];
+   int len;
+
+   while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl)))
+   {
+      len = ssl_recv_data(&(csp->mbedtls_client_attr.ssl), buf, sizeof(buf));
+      if (len == -1)
+      {
+         return 1;
+      }
+      if (len == 0)
+      {
+         /* XXX: Does this actually happen? */
+         break;
+      }
+      log_error(LOG_LEVEL_HEADER, "Forwarding %d bytes of encrypted POST data",
+         len);
+      len = ssl_send_data(&(csp->mbedtls_server_attr.ssl), buf, (size_t)len);
+      if (len == -1)
+      {
+         return 1;
+      }
+      if (csp->expected_client_content_length != 0)
+      {
+         if (csp->expected_client_content_length >= len)
+         {
+            csp->expected_client_content_length -= (unsigned)len;
+         }
+      }
+   }
+
+   log_error(LOG_LEVEL_HEADER, "Done forwarding encrypted POST data");
+
+   return 0;
+
+}
+
+
 /*********************************************************************
  *
  * Function    : send_https_request
@@ -2085,6 +2138,10 @@ static int send_https_request(struct client_state *csp)
                "Flushed %d bytes of request body while expecting %llu",
                flushed, csp->expected_client_content_length);
             csp->expected_client_content_length -= (unsigned)flushed;
+            if (receive_and_send_encrypted_post_data(csp))
+            {
+               return 1;
+            }
          }
       }
       else
@@ -3611,9 +3668,16 @@ static void chat(struct client_state *csp)
    build_request_line(csp, fwd, &csp->headers->first->str);
 
    /*
-    * We have a request. Check if one of the crunchers wants it.
+    * We have a request. Check if one of the crunchers wants it
+    * unless the client wants to use TLS/SSL in which case we
+    * haven't setup the TLS context yet and will send the crunch
+    * response later.
     */
-   if (crunch_response_triggered(csp, crunchers_all))
+   if (
+#ifdef FEATURE_HTTPS_FILTERING
+       !client_use_ssl(csp) &&
+#endif
+       crunch_response_triggered(csp, crunchers_all))
    {
       /*
        * Yes. The client got the crunch response and we're done here.
@@ -3848,7 +3912,7 @@ static void chat(struct client_state *csp)
 
             /*
             * If TLS/SSL connection wasn't created and invalid certificate
-            * wasn't detected, we can interrupt this fuction. Otherwise, we
+            * wasn't detected, we can interrupt this function. Otherwise, we
             * must inform the client about invalid server certificate.
             */
             if (ret != 0
@@ -3884,21 +3948,34 @@ static void chat(struct client_state *csp)
              * with destination server
              */
             int ret = create_server_ssl_connection(csp);
-            /*
-             * If TLS/SSL connection wasn't created and invalid certificate
-             * wasn't detected, we can interrupt this function. Otherwise, we
-             * must inform client about invalid server certificate.
-             */
-            if (ret != 0
-               && (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
-                  || csp->server_cert_verification_result == SSL_CERT_VALID))
+            if (ret != 0)
             {
-               rsp = error_response(csp, "connect-failed");
-               if (rsp)
+               if (csp->server_cert_verification_result != SSL_CERT_VALID &&
+                   csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED)
                {
-                  send_crunch_response(csp, rsp);
+                  /*
+                   * If the server certificate is invalid, we must inform
+                   * the client and then close connection to the client.
+                   */
+                  ssl_send_certificate_error(csp);
+                  close_client_and_server_ssl_connections(csp);
+                  return;
+               }
+               if (csp->server_cert_verification_result == SSL_CERT_NOT_VERIFIED
+                || csp->server_cert_verification_result == SSL_CERT_VALID)
+               {
+                  /*
+                   * The TLS/SSL connection wasn't created but an invalid
+                   * certificate wasn't detected. Report it as connection
+                   * failure.
+                   */
+                  rsp = error_response(csp, "connect-failed");
+                  if (rsp)
+                  {
+                     send_crunch_response(csp, rsp);
+                  }
+                  return;
                }
-               return;
             }
          }
       }/* -END- if (http->ssl) */
@@ -3974,7 +4051,7 @@ static void chat(struct client_state *csp)
             rsp = error_response(csp, "connect-failed");
             if (rsp)
             {
-               send_crunch_response(csp, rsp); /* XXX: use ssl*/
+               send_crunch_response(csp, rsp);
             }
             close_client_and_server_ssl_connections(csp);
             return;