*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
- * 2 : fwd = The forwarding spec used for the request
- * XXX: Should use http->fwd instead.
+ * 2 : fwd = The forwarding spec used for the request.
+ * Can be NULL.
* 3 : request_line = The old request line which will be replaced.
*
* Returns : Nothing. Terminates in case of memory problems.
*request_line = strdup(http->gpc);
string_append(request_line, " ");
- if (fwd->forward_host && fwd->type != FORWARD_WEBSERVER)
+ if (fwd != NULL && fwd->forward_host && fwd->type != FORWARD_WEBSERVER)
{
string_append(request_line, http->url);
}
}
+/*********************************************************************
+ *
+ * Function : change_encrypted_request_destination
+ *
+ * Description : Parse a (rewritten) request line from an encrypted
+ * request and regenerate the http request data.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns : Forwards the parse_http_request() return code.
+ * Terminates in case of memory problems.
+ *
+ *********************************************************************/
+static jb_err change_encrypted_request_destination(struct client_state *csp)
+{
+ jb_err err;
+ char *original_host = csp->http->host;
+
+ log_error(LOG_LEVEL_REDIRECTS, "Rewrite detected: %s",
+ csp->https_headers->first->str);
+ csp->http->host = NULL;
+ free_http_request(csp->http);
+ err = parse_http_request(csp->https_headers->first->str, csp->http);
+ if (JB_ERR_OK != err)
+ {
+ log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
+ jb_err_to_string(err));
+ return err;
+ }
+
+ if (csp->http->host == NULL)
+ {
+ /*
+ * The rewritten request line did not specify a host
+ * which means we can use the original host specified
+ * by the client.
+ */
+ csp->http->host = original_host;
+ log_error(LOG_LEVEL_REDIRECTS, "Keeping the original host: %s",
+ csp->http->host);
+ /*
+ * If the rewritten request line didn't contain a host
+ * it also didn't contain a port so we can reuse the host
+ * and set the port to 443.
+ */
+ freez(csp->http->hostport);
+ csp->http->hostport = strdup_or_die(csp->http->host);
+ csp->http->port = 443;
+ /*
+ * While the request line didn't mention it,
+ * we're https-inspecting and want to speak TLS
+ * with the server.
+ */
+ csp->http->server_ssl = 1;
+ csp->http->ssl = 1;
+ }
+ else
+ {
+ /* The rewrite filter added a host so we can ditch the original */
+ freez(original_host);
+ csp->http->server_ssl = csp->http->ssl;
+ }
+
+ csp->http->client_ssl = 1;
+
+ freez(csp->https_headers->first->str);
+ build_request_line(csp, NULL, &csp->https_headers->first->str);
+
+ if (!server_use_ssl(csp))
+ {
+ log_error(LOG_LEVEL_REDIRECTS,
+ "Rewritten request line results in downgrade to http");
+ /*
+ * Replace the unencryptd headers received with the
+ * CONNECT request with the ones we received securely.
+ */
+ destroy_list(csp->headers);
+ csp->headers->first = csp->https_headers->first;
+ csp->headers->last = csp->https_headers->last;
+ csp->https_headers->first = NULL;
+ csp->https_headers->last = NULL;
+ }
+
+ return JB_ERR_OK;
+
+}
+
+
/*********************************************************************
*
* Function : process_encrypted_request
return JB_ERR_PARSE;
}
+ if ((NULL == csp->https_headers->first->str)
+ || (strcmp(csp->http->cmd, csp->https_headers->first->str) &&
+ (JB_ERR_OK != change_encrypted_request_destination(csp))))
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Failed to get the request destination in the rewritten headers");
+ ssl_send_data_delayed(&(csp->ssl_client_attr),
+ (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
+ return JB_ERR_PARSE;
+ }
+
log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
log_applied_actions(csp->action);
log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport,