*
*********************************************************************/
+#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "errlog.h"
#include "jcc.h"
#include "ssl.h"
+#include "encode.h"
/*
}
+/*********************************************************************
+ *
+ * Function : ssl_send_data_delayed
+ *
+ * Description : Sends the contents of buf (for n bytes) to given SSL
+ * connection, optionally delaying the operation.
+ *
+ * Parameters :
+ * 1 : ssl = SSL context to send data to
+ * 2 : buf = Pointer to data to be sent
+ * 3 : len = Length of data to be sent to the SSL context
+ * 4 : delay = Delay in milliseconds.
+ *
+ * Returns : 0 on success (entire buffer sent).
+ * nonzero on error.
+ *
+ *********************************************************************/
+extern int ssl_send_data_delayed(mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len,
+ unsigned int delay)
+{
+ size_t i = 0;
+
+ if (delay == 0)
+ {
+ if (ssl_send_data(ssl, buf, len) < 0)
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ while (i < len)
+ {
+ size_t write_length;
+ enum { MAX_WRITE_LENGTH = 10 };
+
+ if ((i + MAX_WRITE_LENGTH) > len)
+ {
+ write_length = len - i;
+ }
+ else
+ {
+ write_length = MAX_WRITE_LENGTH;
+ }
+
+ privoxy_millisleep(delay);
+
+ if (ssl_send_data(ssl, buf + i, write_length) < 0)
+ {
+ return -1;
+ }
+ i += write_length;
+ }
+
+ return 0;
+
+}
+
+
/*********************************************************************
*
* Function : ssl_recv_data
{
/*
* We can't use function mbedtls_net_free, because this function
- * inter alia close TCP connection on setted fd. Instead of this
+ * inter alia close TCP connection on set fd. Instead of this
* function, we change fd to -1, which is the same what does
* rest of mbedtls_net_free function.
*/
{
/*
* We can't use function mbedtls_net_free, because this function
- * inter alia close TCP connection on setted fd. Instead of this
+ * inter alia close TCP connection on set fd. Instead of this
* function, we change fd to -1, which is the same what does
* rest of mbedtls_net_free function.
*/
size_t buffer_size)
{
struct tm valid_date;
+ struct tm *timeptr;
size_t ret;
-#ifndef HAVE_GMTIME_R
-#error HTTP inspection currently requires gmtime_r() which seems to be missing
-#endif
- if (NULL == gmtime_r(&time_spec, &valid_date))
+ timeptr = privoxy_gmtime_r(&time_spec, &valid_date);
+ if (NULL == timeptr)
{
return 1;
}
- ret = strftime(buffer, buffer_size, "%Y%m%d%H%M%S", &valid_date);
+ ret = strftime(buffer, buffer_size, "%Y%m%d%H%M%S", timeptr);
if (ret != 14)
{
return 1;
}
+
+/*********************************************************************
+ *
+ * Function : host_is_ip_address
+ *
+ * Description : Checks whether or not a host is specified by
+ * IP address. Does not actually validate the
+ * address.
+ *
+ * Parameters :
+ * 1 : host = The host name to check
+ *
+ * Returns : 1 => Yes
+ * 0 => No
+ *
+ *********************************************************************/
+static int host_is_ip_address(const char *host)
+{
+ const char *p;
+
+ if (NULL != strstr(host, ":"))
+ {
+ /* Assume an IPv6 address. */
+ return 1;
+ }
+
+ for (p = host; *p; p++)
+ {
+ if (*p != '.')
+ {
+ if (!privoxy_isdigit(*p))
+ {
+ /* Not a dot or digit so it can't be an IPv4 address. */
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * Host only consists of dots and digits so
+ * assume that is an IPv4 address.
+ */
+ return 1;
+
+}
+
+
/*********************************************************************
*
* Function : generate_webpage_certificate
}
#endif /* MBEDTLS_SHA1_C */
- if (set_subject_alternative_name(&cert, csp->http->host))
+ if (!host_is_ip_address(csp->http->host) &&
+ set_subject_alternative_name(&cert, csp->http->host))
{
/* Errors are already logged by set_subject_alternative_name() */
ret = -1;
int ret = 0;
struct certs_chain *cert = NULL;
- /* Header of message with certificate informations */
+ /* Header of message with certificate information */
const char message_begin[] =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n\r\n"
- "<html><body><h1>Server certificate verification failed</h1><p>Reason: ";
+ "<!DOCTYPE html>\n"
+ "<html><head><title>Server certificate verification failed</title></head>\n"
+ "<body><h1>Server certificate verification failed</h1>\n"
+ "<p><a href=\"https://" CGI_SITE_2_HOST "/\">Privoxy</a> was unable "
+ "to securely connnect to the destination server.</p>"
+ "<p>Reason: ";
const char message_end[] = "</body></html>\r\n\r\n";
char reason[INVALID_CERT_INFO_BUF_SIZE];
memset(reason, 0, sizeof(reason));
{
size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
- message_len += strlen(cert->text_buf) + strlen("<pre></pre>\n")
+ message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
+ base64_len + strlen("<a href=\"data:application"
"/x-x509-ca-cert;base64,\">Download certificate</a>");
cert = cert->next;
}
strlcat(message, "<pre>", message_len);
- strlcat(message, cert->text_buf, message_len);
+ strlcat(message, cert->info_buf, message_len);
strlcat(message, "</pre>\n", message_len);
if (ret == 0)
*/
last->next = malloc_or_die(sizeof(struct certs_chain));
last->next->next = NULL;
- memset(last->next->text_buf, 0, sizeof(last->next->text_buf));
+ memset(last->next->info_buf, 0, sizeof(last->next->info_buf));
memset(last->next->file_buf, 0, sizeof(last->next->file_buf));
/*
/*
* Saving certificate information into buffer
*/
- mbedtls_x509_crt_info(last->text_buf, sizeof(last->text_buf) - 1,
- CERT_INFO_PREFIX, crt);
+ {
+ char buf[CERT_INFO_BUF_SIZE];
+ char *encoded_text;
+
+ mbedtls_x509_crt_info(buf, sizeof(buf), CERT_INFO_PREFIX, crt);
+ encoded_text = html_encode(buf);
+ strlcpy(last->info_buf, encoded_text, sizeof(last->info_buf));
+ freez(encoded_text);
+ }
return 0;
}
* Function : free_certificate_chain
*
* Description : Frees certificates linked list. This linked list is
- * used to save informations about certificates in
+ * used to save information about certificates in
* trusted chain.
*
* Parameters :
struct certs_chain *cert = csp->server_certs_chain.next;
/* Cleaning buffers */
- memset(csp->server_certs_chain.text_buf, 0,
- sizeof(csp->server_certs_chain.text_buf));
+ memset(csp->server_certs_chain.info_buf, 0,
+ sizeof(csp->server_certs_chain.info_buf));
memset(csp->server_certs_chain.file_buf, 0,
sizeof(csp->server_certs_chain.file_buf));
csp->server_certs_chain.next = NULL;
* Function : tunnel_established_successfully
*
* Description : Check if parent proxy server response contains
- * informations about successfully created connection with
+ * information about successfully created connection with
* destination server. (HTTP/... 2xx ...)
*
* Parameters :