"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/ec_sslwrap.c" between
ettercap-0.8.3.tar.gz and ettercap-0.8.3.1.tar.gz

About: ettercap is a multipurpose sniffer/interceptor/logger for switched LAN.

ec_sslwrap.c  (ettercap-0.8.3):ec_sslwrap.c  (ettercap-0.8.3.1)
skipping to change at line 56 skipping to change at line 56
#include <pthread.h> #include <pthread.h>
// XXX - check if we have poll.h // XXX - check if we have poll.h
#ifdef HAVE_SYS_POLL_H #ifdef HAVE_SYS_POLL_H
#include <sys/poll.h> #include <sys/poll.h>
#endif #endif
/* don't include kerberos. RH sux !! */ /* don't include kerberos. RH sux !! */
#define OPENSSL_NO_KRB5 1 #define OPENSSL_NO_KRB5 1
#include <openssl/ssl.h> #include <openssl/ssl.h>
#ifdef DEBUG
#include <openssl/err.h>
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
#endif #endif
#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
#define HAVE_OPENSSL_1_0_2
#endif
#if (OPENSSL_VERSION_NUMBER <= 0x100020700L)
/* prior 1.0.2g TLS_client_method macro wasn't available */
#define TLS_client_method SSLv23_client_method
#define TLS_server_method SSLv23_server_method
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#define HAVE_OPENSSL_1_1_0
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
#define HAVE_OPENSSL_1_1_1
#endif
#define BREAK_ON_ERROR(x,y,z) do { \ #define BREAK_ON_ERROR(x,y,z) do { \
if (x == -E_INVALID) { \ if (x == -E_INVALID) { \
SAFE_FREE(z.DATA.disp_data); \ SAFE_FREE(z.DATA.disp_data); \
sslw_initialize_po(&z, z.DATA.data); \ sslw_initialize_po(&z, z.DATA.data); \
z.len = 64; \ z.len = 64; \
z.L4.flags = TH_RST; \ z.L4.flags = TH_RST; \
packet_disp_data(&z, z.DATA.data, z.DATA.len); \ packet_disp_data(&z, z.DATA.data, z.DATA.len); \
sslw_parse_packet(y, SSL_SERVER, &z); \ sslw_parse_packet(y, SSL_SERVER, &z); \
sslw_wipe_connection(y); \ sslw_wipe_connection(y); \
SAFE_FREE(z.DATA.data); \ SAFE_FREE(z.DATA.data); \
skipping to change at line 97 skipping to change at line 118
LIST_ENTRY (listen_entry) next; LIST_ENTRY (listen_entry) next;
}; };
struct accepted_entry { struct accepted_entry {
int32 fd[2]; /* 0->Client, 1->Server */ int32 fd[2]; /* 0->Client, 1->Server */
u_int16 port[2]; u_int16 port[2];
struct ip_addr ip[2]; struct ip_addr ip[2];
SSL *ssl[2]; SSL *ssl[2];
u_char status; u_char status;
X509 *cert; X509 *cert;
#ifdef HAVE_OPENSSL_1_1_1
unsigned int tls_handshake_state;
#define SSL_CLIENTHELLO_INTERCEPTED 1
char *hostname;
#endif
#define SSL_CLIENT 0 #define SSL_CLIENT 0
#define SSL_SERVER 1 #define SSL_SERVER 1
}; };
/* Session identifier /* Session identifier
* It has to be of even length for session hash matching */ * It has to be of even length for session hash matching */
struct sslw_ident { struct sslw_ident {
u_int32 magic; u_int32 magic;
#define SSLW_MAGIC 0x0501e77e #define SSLW_MAGIC 0x0501e77e
struct ip_addr L3_src; struct ip_addr L3_src;
u_int16 L4_src; u_int16 L4_src;
u_int16 L4_dst; u_int16 L4_dst;
}; };
#define SSLW_IDENT_LEN sizeof(struct sslw_ident) #define SSLW_IDENT_LEN sizeof(struct sslw_ident)
#define SSLW_RETRY 500 #define SSLW_RETRY 500
#define SSLW_WAIT 10 /* 10 milliseconds */ #define SSLW_WAIT 10 /* 10 milliseconds */
#define TSLEEP (50*1000) /* 50 milliseconds */ #define TSLEEP (50*1000) /* 50 milliseconds */
#ifdef HAVE_OPENSSL_1_1_0
static SSL_CONF_CTX *ssl_conf_client, *ssl_conf_server;
#endif
static SSL_CTX *ssl_ctx_client, *ssl_ctx_server; static SSL_CTX *ssl_ctx_client, *ssl_ctx_server;
static EVP_PKEY *global_pk; static EVP_PKEY *global_pk;
static u_int16 number_of_services; static u_int16 number_of_services;
static struct pollfd *poll_fd = NULL; static struct pollfd *poll_fd = NULL;
static EC_THREAD_FUNC(sslw_child); static EC_THREAD_FUNC(sslw_child);
static int sslw_is_ssl(struct packet_object *po); static int sslw_is_ssl(struct packet_object *po);
static int sslw_connect_server(struct accepted_entry *ae); static int sslw_connect_server(struct accepted_entry *ae);
static int sslw_sync_conn(struct accepted_entry *ae); static int sslw_sync_conn(struct accepted_entry *ae);
static int sslw_get_peer(struct accepted_entry *ae); static int sslw_get_peer(struct accepted_entry *ae);
skipping to change at line 142 skipping to change at line 171
static void sslw_initialize_po(struct packet_object *po, u_char *p_data); static void sslw_initialize_po(struct packet_object *po, u_char *p_data);
static int sslw_match(void *id_sess, void *id_curr); static int sslw_match(void *id_sess, void *id_curr);
static void sslw_create_session(struct ec_session **s, struct packet_object *po) ; static void sslw_create_session(struct ec_session **s, struct packet_object *po) ;
static size_t sslw_create_ident(void **i, struct packet_object *po); static size_t sslw_create_ident(void **i, struct packet_object *po);
static void sslw_hook_handled(struct packet_object *po); static void sslw_hook_handled(struct packet_object *po);
static X509 *sslw_create_selfsigned(X509 *serv_cert); static X509 *sslw_create_selfsigned(X509 *serv_cert);
static void ssl_wrap_fini(void); static void ssl_wrap_fini(void);
static int sslw_ssl_connect(SSL *ssl_sk); static int sslw_ssl_connect(SSL *ssl_sk);
static int sslw_ssl_accept(SSL *ssl_sk); static int sslw_ssl_accept(SSL *ssl_sk);
static int sslw_remove_sts(struct packet_object *po); static int sslw_remove_sts(struct packet_object *po);
#ifdef HAVE_OPENSSL_1_1_1
static int sslw_clienthello_cb(SSL *ssl_sk, int *alert, void *arg);
static char* sslw_get_clienthello_sni(SSL *ssl);
#endif
/*******************************************/ /*******************************************/
/* /*
* Register a new ssl wrapper * Register a new ssl wrapper
*/ */
void sslw_dissect_add(char *name, u_int32 port, FUNC_DECODER_PTR(decoder), u_cha r status) void sslw_dissect_add(char *name, u_int32 port, FUNC_DECODER_PTR(decoder), u_cha r status)
{ {
struct listen_entry *le; struct listen_entry *le;
skipping to change at line 242 skipping to change at line 275
close(le->fd); close(le->fd);
#ifdef WITH_IPV6 #ifdef WITH_IPV6
close(le->fd6); close(le->fd6);
#endif #endif
LIST_REMOVE(le, next); LIST_REMOVE(le, next);
SAFE_FREE(le); SAFE_FREE(le);
} }
SSL_CTX_free(ssl_ctx_server); SSL_CTX_free(ssl_ctx_server);
SSL_CTX_free(ssl_ctx_client); SSL_CTX_free(ssl_ctx_client);
#ifdef HAVE_OPENSSL_1_1_0
SSL_CONF_CTX_free(ssl_conf_client);
SSL_CONF_CTX_free(ssl_conf_server);
#endif
/* remove redirects */ /* remove redirects */
ec_redirect_cleanup(); ec_redirect_cleanup();
} }
/* /*
* SSL thread main function. * SSL thread main function.
*/ */
EC_THREAD_FUNC(sslw_start) EC_THREAD_FUNC(sslw_start)
skipping to change at line 383 skipping to change at line 420
(po->L4.flags & TH_SYN) && (po->L4.flags & TH_SYN) &&
!(po->L4.flags & TH_ACK) ) { !(po->L4.flags & TH_ACK) ) {
sslw_create_session(&s, PACKET); sslw_create_session(&s, PACKET);
#ifndef OS_LINUX #ifndef OS_LINUX
/* Remember the real destination IP */ /* Remember the real destination IP */
memcpy(s->data, &po->L3.dst, sizeof(struct ip_addr)); memcpy(s->data, &po->L3.dst, sizeof(struct ip_addr));
session_put(s); session_put(s);
#else #else
SAFE_FREE(s); /* Just get rid of it */ SAFE_FREE(s); /* Just get rid of it */
#endif #endif
} else /* Pass only the SYN for conntrack */ } else /* Pass only the SYN for conntrack */
po->flags |= PO_IGNORE; po->flags |= PO_IGNORE;
} }
/* /*
* Check if this packet is for ssl wrappers * Check if this packet is for ssl wrappers
*/ */
static int sslw_is_ssl(struct packet_object *po) static int sslw_is_ssl(struct packet_object *po)
{ {
struct listen_entry *le;
/* If it's already coming from ssl wrapper /* If it's already coming from ssl wrapper
* or the connection is not TCP */ * or the connection is not TCP */
if (po->flags & PO_FROMSSL || po->L4.proto != NL_TYPE_TCP) if (po->flags & PO_FROMSSL || po->L4.proto != NL_TYPE_TCP)
return 0; return 0;
LIST_FOREACH(le, &listen_ports, next) { /* check if packet matches one of the registered redirects */
if (ntohs(po->L4.dst) == le->sslw_port || if (ec_redirect_lookup(po) == E_SUCCESS)
ntohs(po->L4.src) == le->sslw_port) return 1;
return 1;
}
return 0; return 0;
} }
/* /*
* Bind all registered wrappers to free ports * Bind all registered wrappers to free ports
* and isnert redirects. * and isnert redirects.
*/ */
static void sslw_bind_wrapper(void) static void sslw_bind_wrapper(void)
{ {
u_int16 bind_port = EC_MAGIC_16; u_int16 bind_port = EC_MAGIC_16;
skipping to change at line 471 skipping to change at line 505
bind_port, strerror(errno)); bind_port, strerror(errno));
if(listen(le->fd6, 100) == -1) if(listen(le->fd6, 100) == -1)
FATAL_ERROR("Unable to accept connections for IPv6 socket"); FATAL_ERROR("Unable to accept connections for IPv6 socket");
#else #else
/* properly init fd even if unused - necessary for select call */ /* properly init fd even if unused - necessary for select call */
le->fd6 = 0; le->fd6 = 0;
#endif #endif
if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name, if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name,
EC_REDIR_PROTO_IPV4, NULL, NULL, EC_REDIR_PROTO_IPV4, NULL,
le->sslw_port, le->redir_port) != E_SUCCESS) le->sslw_port, le->redir_port) != E_SUCCESS)
FATAL_ERROR("Can't insert firewall redirects"); FATAL_ERROR("Can't insert firewall redirects");
#ifdef WITH_IPV6 #ifdef WITH_IPV6
if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name, if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name,
EC_REDIR_PROTO_IPV6, NULL, NULL, EC_REDIR_PROTO_IPV6, NULL,
le->sslw_port, le->redir_port) != E_SUCCESS) le->sslw_port, le->redir_port) != E_SUCCESS)
FATAL_ERROR("Can't insert firewall redirects"); FATAL_ERROR("Can't insert firewall redirects");
#endif #endif
} }
} }
/* /*
* Create TCP a connection to the real SSL server * Create TCP a connection to the real SSL server
*/ */
skipping to change at line 531 skipping to change at line 565
return -E_INVALID; return -E_INVALID;
/* sleep a quirk of time... */ /* sleep a quirk of time... */
ec_usleep(TSLEEP); ec_usleep(TSLEEP);
} while(loops--); } while(loops--);
return -E_INVALID; return -E_INVALID;
} }
/* /*
* ClientHello Callback to intercept SSL handshake after ClientHello
*/
#ifdef HAVE_OPENSSL_1_1_1
static int sslw_clienthello_cb(SSL *ssl, int *alert, void *arg)
{
(void) alert;
struct accepted_entry *ae;
ae = (struct accepted_entry *)arg;
/* extract hostname value from SNI extension */
ae->hostname = sslw_get_clienthello_sni(ssl);
if (ae->tls_handshake_state != SSL_CLIENTHELLO_INTERCEPTED) {
ae->tls_handshake_state = SSL_CLIENTHELLO_INTERCEPTED;
/* suspend client side TLS handshake */
return SSL_CLIENT_HELLO_RETRY;
}
return SSL_CLIENT_HELLO_SUCCESS;
}
static char* sslw_get_clienthello_sni(SSL *ssl)
{
const unsigned char* sni;
size_t len;
uint8_t sni_type;
uint16_t val_len;
// uint16_t sni_len;
if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &sni, &len)) {
if (len > 5) {
// sni_len = sni[0] << 8 | sni[1];
sni_type = sni[2];
val_len = sni[3] << 8 | sni[4];
if (sni_type == TLSEXT_NAMETYPE_host_name)
return strndup(sni+5, val_len);
}
}
return NULL;
}
#endif
/*
* Perform a blocking SSL_accept with a * Perform a blocking SSL_accept with a
* configurable timeout on a non-blocing socket * configurable timeout on a non-blocing socket
*/ */
static int sslw_ssl_accept(SSL *ssl_sk) static int sslw_ssl_accept(SSL *ssl_sk)
{ {
int loops = (EC_GBL_CONF->connect_timeout * 10e5) / TSLEEP; int loops = (EC_GBL_CONF->connect_timeout * 10e5) / TSLEEP;
int ret, ssl_err; int ret, ssl_err;
do { do {
/* accept the ssl connection */ /* accept the ssl connection */
if ( (ret = SSL_accept(ssl_sk)) == 1) if ( (ret = SSL_accept(ssl_sk)) == 1)
return E_SUCCESS; return E_SUCCESS;
ssl_err = SSL_get_error(ssl_sk, ret); ssl_err = SSL_get_error(ssl_sk, ret);
/* there was an error... */ #ifdef HAVE_OPENSSL_1_1_1
if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) /* return successfully if handshake has been suspended by callback */
if (ssl_err == SSL_ERROR_WANT_CLIENT_HELLO_CB)
return E_SUCCESS;
#endif
/* there was an error... but only if it's not just pending further progre
ss */
if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) {
#ifdef DEBUG
char error_msg[256], *error;
error = ERR_error_string(ERR_get_error(), error_msg);
DEBUG_MSG("sslw_ssl_accept(): SSL_accept() failed with '%s'", error);
#endif
return -E_INVALID; return -E_INVALID;
}
/* sleep a quirk of time... */ /* sleep a quirk of time... */
ec_usleep(TSLEEP); ec_usleep(TSLEEP);
} while(loops--); } while(loops--);
return -E_INVALID; return -E_INVALID;
} }
/* /*
* Create an SSL connection to the real server. * Create an SSL connection to the real server.
* Grab server certificate and create a fake one * Grab server certificate and create a fake one
* for the poor client. * for the poor client.
* Then accept the SSL connection from the client. * Then accept the SSL connection from the client.
*/ */
static int sslw_sync_ssl(struct accepted_entry *ae) static int sslw_sync_ssl(struct accepted_entry *ae)
{ {
X509 *server_cert; X509 *server_cert;
#ifdef HAVE_OPENSSL_1_1_1
/* Set a Callback for the SSL client context to pause the Client Handshake */
SSL_CTX_set_client_hello_cb(ssl_ctx_client, sslw_clienthello_cb, (void*)ae);
#endif
ae->ssl[SSL_SERVER] = SSL_new(ssl_ctx_server); ae->ssl[SSL_SERVER] = SSL_new(ssl_ctx_server);
SSL_set_connect_state(ae->ssl[SSL_SERVER]); SSL_set_connect_state(ae->ssl[SSL_SERVER]);
SSL_set_fd(ae->ssl[SSL_SERVER], ae->fd[SSL_SERVER]); SSL_set_fd(ae->ssl[SSL_SERVER], ae->fd[SSL_SERVER]);
ae->ssl[SSL_CLIENT] = SSL_new(ssl_ctx_client); ae->ssl[SSL_CLIENT] = SSL_new(ssl_ctx_client);
SSL_set_fd(ae->ssl[SSL_CLIENT], ae->fd[SSL_CLIENT]); SSL_set_fd(ae->ssl[SSL_CLIENT], ae->fd[SSL_CLIENT]);
#ifdef HAVE_OPENSSL_1_1_1
/* Begin SSL handshake to extract SNI - then suspend by callback */
if (sslw_ssl_accept(ae->ssl[SSL_CLIENT]) != E_SUCCESS)
return -E_INVALID;
if (ae->hostname)
/* set SNI for server-side connection */
SSL_set_tlsext_host_name(ae->ssl[SSL_SERVER], ae->hostname);
#endif
/* Connect to actual SSL server */
if (sslw_ssl_connect(ae->ssl[SSL_SERVER]) != E_SUCCESS) if (sslw_ssl_connect(ae->ssl[SSL_SERVER]) != E_SUCCESS)
return -E_INVALID; return -E_INVALID;
/* Extract certificate from actual SSL server */
/* XXX - NULL cypher can give no certificate */ /* XXX - NULL cypher can give no certificate */
if ( (server_cert = SSL_get_peer_certificate(ae->ssl[SSL_SERVER])) == NULL) { if ( (server_cert = SSL_get_peer_certificate(ae->ssl[SSL_SERVER])) == NULL) {
DEBUG_MSG("Can't get peer certificate"); DEBUG_MSG("Can't get peer certificate");
return -E_INVALID; return -E_INVALID;
} }
if (!EC_GBL_OPTIONS->ssl_cert) { if (!EC_GBL_OPTIONS->ssl_cert) {
/* Create the fake certificate */ /* Create the fake certificate based on actual certificate */
ae->cert = sslw_create_selfsigned(server_cert); ae->cert = sslw_create_selfsigned(server_cert);
X509_free(server_cert); X509_free(server_cert);
if (ae->cert == NULL) if (ae->cert == NULL)
return -E_INVALID; return -E_INVALID;
SSL_use_certificate(ae->ssl[SSL_CLIENT], ae->cert); /* use faked certificate for further SSL client connection */
SSL_use_certificate(ae->ssl[SSL_CLIENT], ae->cert);
} }
/* continue SSL handshake with SSL client */
if (sslw_ssl_accept(ae->ssl[SSL_CLIENT]) != E_SUCCESS) if (sslw_ssl_accept(ae->ssl[SSL_CLIENT]) != E_SUCCESS)
return -E_INVALID; return -E_INVALID;
#ifdef HAVE_OPENSSL_1_1_1
/* TLS handshake done - SNI hostname not longer required: free */
SAFE_FREE(ae->hostname);
#endif
return E_SUCCESS; return E_SUCCESS;
} }
/* /*
* Take the IP address of the server * Take the IP address of the server
* that the client wants to talk to. * that the client wants to talk to.
*/ */
static int sslw_get_peer(struct accepted_entry *ae) static int sslw_get_peer(struct accepted_entry *ae)
{ {
skipping to change at line 897 skipping to change at line 1014
/* /*
* Allocate the data buffer and initialize * Allocate the data buffer and initialize
* fake headers. Headers len is set to 0. * fake headers. Headers len is set to 0.
* XXX - Be sure to not modify these len. * XXX - Be sure to not modify these len.
*/ */
memset(po, 0, sizeof(struct packet_object)); memset(po, 0, sizeof(struct packet_object));
if (p_data == NULL) { if (p_data == NULL) {
SAFE_CALLOC(po->DATA.data, 1, UINT16_MAX); SAFE_CALLOC(po->DATA.data, 1, UINT16_MAX);
} else { } else {
if (po->DATA.data != p_data) { if (po->DATA.data != p_data) {
SAFE_FREE(po->DATA.data); SAFE_FREE(po->DATA.data);
po->DATA.data = p_data; po->DATA.data = p_data;
} }
} }
po->L2.header = po->DATA.data; po->L2.header = po->DATA.data;
po->L3.header = po->DATA.data; po->L3.header = po->DATA.data;
po->L3.options = po->DATA.data; po->L3.options = po->DATA.data;
po->L4.header = po->DATA.data; po->L4.header = po->DATA.data;
po->L4.options = po->DATA.data; po->L4.options = po->DATA.data;
po->fwd_packet = po->DATA.data; po->fwd_packet = po->DATA.data;
po->packet = po->DATA.data; po->packet = po->DATA.data;
skipping to change at line 922 skipping to change at line 1039
po->L4.proto = NL_TYPE_TCP; po->L4.proto = NL_TYPE_TCP;
} }
/* /*
* Create a self-signed certificate * Create a self-signed certificate
*/ */
static X509 *sslw_create_selfsigned(X509 *server_cert) static X509 *sslw_create_selfsigned(X509 *server_cert)
{ {
X509 *out_cert; X509 *out_cert;
X509_EXTENSION *ext; X509_EXTENSION *ext;
const EVP_MD *md;
int index = 0; int index = 0;
if ((out_cert = X509_new()) == NULL) if ((out_cert = X509_new()) == NULL)
return NULL; return NULL;
/* Set out public key, real server name... */ /* Set out public key, real server name... */
X509_set_version(out_cert, X509_get_version(server_cert)); X509_set_version(out_cert, X509_get_version(server_cert));
ASN1_INTEGER_set(X509_get_serialNumber(out_cert), EC_MAGIC_32); ASN1_INTEGER_set(X509_get_serialNumber(out_cert), EC_MAGIC_32);
X509_set_notBefore(out_cert, X509_get_notBefore(server_cert)); X509_set_notBefore(out_cert, X509_get_notBefore(server_cert));
X509_set_notAfter(out_cert, X509_get_notAfter(server_cert)); X509_set_notAfter(out_cert, X509_get_notAfter(server_cert));
skipping to change at line 959 skipping to change at line 1077
os->data[8] = 0x7e; os->data[8] = 0x7e;
X509_EXTENSION_set_data (ext, os); X509_EXTENSION_set_data (ext, os);
#else #else
ext->value->data[7] = 0xe7; ext->value->data[7] = 0xe7;
ext->value->data[8] = 0x7e; ext->value->data[8] = 0x7e;
#endif #endif
X509_add_ext(out_cert, ext, -1); X509_add_ext(out_cert, ext, -1);
} }
} }
/* take over SAN extension from peer certificate */
index = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, index);
if (index >= 0) {
X509_add_ext(out_cert, X509_get_ext(server_cert, index), -1);
}
/* grab digest algorithm from peer certificate */
md = EVP_get_digestbynid(X509_get_signature_nid(server_cert));
if (md == NULL) {
DEBUG_MSG("Error determining message digest algorithm for signing.");
/* Falling back to SHA256 signing algorithm which is the default in TLS1.3
*/
md = EVP_sha256();
}
/* Self-sign our certificate */ /* Self-sign our certificate */
if (!X509_sign(out_cert, global_pk, EVP_sha1())) { if (!X509_sign(out_cert, global_pk, md)) {
X509_free(out_cert); X509_free(out_cert);
DEBUG_MSG("Error self-signing X509"); DEBUG_MSG("Error self-signing X509");
return NULL; return NULL;
} }
return out_cert; return out_cert;
} }
/* /*
* Initialize SSL stuff * Initialize SSL stuff
*/ */
static void sslw_init(void) static void sslw_init(void)
{ {
SSL *dummy_ssl=NULL; SSL *dummy_ssl=NULL;
#ifndef HAVE_OPENSSL_1_1_0
SSL_library_init(); SSL_library_init();
#endif
/* Create the two global CTX */ /* Create the two global CTX */
ssl_ctx_client = SSL_CTX_new(SSLv23_server_method()); ssl_ctx_client = SSL_CTX_new(TLS_server_method());
ssl_ctx_server = SSL_CTX_new(SSLv23_client_method()); ssl_ctx_server = SSL_CTX_new(TLS_client_method());
ON_ERROR(ssl_ctx_client, NULL, "Could not create client SSL CTX"); ON_ERROR(ssl_ctx_client, NULL, "Could not create client SSL CTX");
ON_ERROR(ssl_ctx_server, NULL, "Could not create server SSL CTX"); ON_ERROR(ssl_ctx_server, NULL, "Could not create server SSL CTX");
#ifdef HAVE_OPENSSL_1_0_2
SSL_CTX_set_ecdh_auto(ssl_ctx_client, 1);
SSL_CTX_set_ecdh_auto(ssl_ctx_server, 1);
#endif
#ifdef HAVE_OPENSSL_1_1_0
ssl_conf_client = SSL_CONF_CTX_new();
ssl_conf_server = SSL_CONF_CTX_new();
SSL_CONF_CTX_set_flags(ssl_conf_client, SSL_CONF_FLAG_FILE);
SSL_CONF_CTX_set_flags(ssl_conf_server, SSL_CONF_FLAG_FILE);
SSL_CONF_CTX_set_ssl_ctx(ssl_conf_client, ssl_ctx_client);
SSL_CONF_CTX_set_ssl_ctx(ssl_conf_server, ssl_ctx_server);
/* Backward compatibility for older TLS versions and ciphers */
SSL_CONF_cmd(ssl_conf_client, "MinProtocol", "TLSv1");
SSL_CONF_cmd(ssl_conf_server, "MinProtocol", "TLSv1");
SSL_CONF_cmd(ssl_conf_client, "CipherString", "DEFAULT");
SSL_CONF_cmd(ssl_conf_server, "CipherString", "DEFAULT");
#endif
if(EC_GBL_OPTIONS->ssl_pkey) { if(EC_GBL_OPTIONS->ssl_pkey) {
/* Get our private key from the file specified from cmd-line */ /* Get our private key from the file specified from cmd-line */
DEBUG_MSG("Using custom private key %s", EC_GBL_OPTIONS->ssl_pkey); DEBUG_MSG("Using custom private key %s", EC_GBL_OPTIONS->ssl_pkey);
if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, EC_GBL_OPTIONS->ssl_pkey, if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client,
SSL_FILETYPE_PEM) == 0) { EC_GBL_OPTIONS->ssl_pkey, SSL_FILETYPE_PEM) == 0) {
FATAL_ERROR("Can't open \"%s\" file : %s", EC_GBL_OPTIONS->ssl_pk FATAL_ERROR("Can't open \"%s\" file : %s",
ey, strerror(errno)); EC_GBL_OPTIONS->ssl_pkey, strerror(errno));
} }
if (EC_GBL_OPTIONS->ssl_cert) { if (EC_GBL_OPTIONS->ssl_cert) {
if (SSL_CTX_use_certificate_file(ssl_ctx_client, EC_GBL_OPTIONS-> if (SSL_CTX_use_certificate_file(ssl_ctx_client,
ssl_cert, SSL_FILETYPE_PEM) == 0) { EC_GBL_OPTIONS->ssl_cert, SSL_FILETYPE_PEM) == 0) {
FATAL_ERROR("Can't open \"%s\" file : %s", EC_GBL_OPTIONS FATAL_ERROR("Can't open \"%s\" file : %s",
->ssl_cert, strerror(errno)); EC_GBL_OPTIONS->ssl_cert, strerror(errno));
} }
if (!SSL_CTX_check_private_key(ssl_ctx_client)) { if (!SSL_CTX_check_private_key(ssl_ctx_client)) {
FATAL_ERROR("Certificate \"%s\" does not match private ke FATAL_ERROR("Certificate \"%s\" does not match private key \"%s\"",
y \"%s\"", EC_GBL_OPTIONS->ssl_cert, EC_GBL_OPTIONS->ssl_pkey); EC_GBL_OPTIONS->ssl_cert, EC_GBL_OPTIONS->ssl_pkey);
} }
} }
} else { } else {
/* Get our private key from our cert file */ /* Get our private key from our cert file */
if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, INSTALL_DATADIR "/" PROGR if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client,
AM "/" CERT_FILE, SSL_FILETYPE_PEM) == 0) { INSTALL_DATADIR"/"PROGRAM"/"CERT_FILE, SSL_FILETYPE_PEM) == 0) {
DEBUG_MSG("sslw -- SSL_CTX_use_PrivateKey_file -- trying ./share/ DEBUG_MSG("sslw -- SSL_CTX_use_PrivateKey_file -- trying ./share/%s"
%s", CERT_FILE); ,
CERT_FILE);
if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, "./share/" CERT_F
ILE, SSL_FILETYPE_PEM) == 0) if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client,
FATAL_ERROR("Can't open \"./share/%s\" file : %s", CERT_F "./share/" CERT_FILE, SSL_FILETYPE_PEM) == 0)
ILE, strerror(errno)); FATAL_ERROR("Can't open \"./share/%s\" file : %s",
} CERT_FILE, strerror(errno));
}
} }
dummy_ssl = SSL_new(ssl_ctx_client); dummy_ssl = SSL_new(ssl_ctx_client);
if ( (global_pk = SSL_get_privatekey(dummy_ssl)) == NULL ) if ( (global_pk = SSL_get_privatekey(dummy_ssl)) == NULL )
FATAL_ERROR("Can't get private key from file"); FATAL_ERROR("Can't get private key from file");
SSL_free(dummy_ssl); SSL_free(dummy_ssl);
} }
/* /*
skipping to change at line 1099 skipping to change at line 1263
/* Should we poll both fd's instead of guessing and sleeping? */ /* Should we poll both fd's instead of guessing and sleeping? */
if (!data_read) if (!data_read)
ec_usleep(3000); // 3ms ec_usleep(3000); // 3ms
} }
return NULL; return NULL;
} }
static int sslw_remove_sts(struct packet_object *po) static int sslw_remove_sts(struct packet_object *po)
{ {
u_char *ptr; u_char *ptr;
u_char *end; u_char *end;
u_char *h_end; u_char *h_end;
size_t len = po->DATA.len; size_t len = po->DATA.len;
size_t slen = strlen("\r\nStrict-Transport-Security:"); size_t slen = strlen("\r\nStrict-Transport-Security:");
if (!memmem(po->DATA.data, po->DATA.len, "\r\nStrict-Transport-Security:" if (!memmem(po->DATA.data, po->DATA.len, "\r\nStrict-Transport-Security:", sl
, slen)) { en)) {
return -E_NOTFOUND; return -E_NOTFOUND;
} }
ptr = po->DATA.data; ptr = po->DATA.data;
end = ptr + po->DATA.len; end = ptr + po->DATA.len;
len = end - ptr; len = end - ptr;
ptr = (u_char*)memmem(ptr, len, "\r\nStrict-Transport-Security:", slen); ptr = (u_char*)memmem(ptr, len, "\r\nStrict-Transport-Security:", slen);
ptr += 2; ptr += 2;
h_end = (u_char*)memmem(ptr, len, "\r\n", 2); h_end = (u_char*)memmem(ptr, len, "\r\n", 2);
h_end += 2; h_end += 2;
size_t before_header = ptr - po->DATA.data; size_t before_header = ptr - po->DATA.data;
size_t header_length = h_end - ptr; size_t header_length = h_end - ptr;
size_t new_len = 0; size_t new_len = 0;
u_char *new_html; u_char *new_html;
SAFE_CALLOC(new_html, len, sizeof(u_char)); SAFE_CALLOC(new_html, len, sizeof(u_char));
BUG_IF(new_html == NULL); BUG_IF(new_html == NULL);
memcpy(new_html, po->DATA.data, before_header); memcpy(new_html, po->DATA.data, before_header);
new_len += before_header; new_len += before_header;
memcpy(new_html+new_len, h_end, (len - header_length) - before_header); memcpy(new_html+new_len, h_end, (len - header_length) - before_header);
new_len += (len - header_length) - before_header; new_len += (len - header_length) - before_header;
memset(po->DATA.data, '\0', po->DATA.len); memset(po->DATA.data, '\0', po->DATA.len);
memcpy(po->DATA.data, new_html, new_len); memcpy(po->DATA.data, new_html, new_len);
po->DATA.len = new_len; po->DATA.len = new_len;
po->flags |= PO_MODIFIED; po->flags |= PO_MODIFIED;
return E_SUCCESS; return E_SUCCESS;
} }
/*******************************************/ /*******************************************/
/* Sessions' stuff for ssl packets */ /* Sessions' stuff for ssl packets */
static size_t sslw_create_ident(void **i, struct packet_object *po) static size_t sslw_create_ident(void **i, struct packet_object *po)
{ {
struct sslw_ident *ident; struct sslw_ident *ident;
 End of changes. 47 change blocks. 
85 lines changed or deleted 243 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)