Fix misc issues with autossl

And various improvements
pull/48/head
Soner Tari 4 years ago
parent a0e475b473
commit 9ad477e0a7

@ -31,8 +31,6 @@
#include "prototcp.h" #include "prototcp.h"
#include "protossl.h" #include "protossl.h"
#include "pxysslshut.h"
#include <string.h> #include <string.h>
#include <sys/param.h> #include <sys/param.h>
#include <event2/bufferevent_ssl.h> #include <event2/bufferevent_ssl.h>
@ -178,25 +176,30 @@ protoautossl_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
struct evbuffer *inbuf = bufferevent_get_input(bev); struct evbuffer *inbuf = bufferevent_get_input(bev);
struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev); struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev);
size_t packet_size = evbuffer_get_length(inbuf); // @todo Validate proto?
// +2 is for \r\n
unsigned char *packet = pxy_malloc_packet(packet_size + ctx->sslproxy_header_len + 2, ctx);
if (!packet) {
return;
}
evbuffer_remove(inbuf, packet, packet_size); if (!ctx->sent_sslproxy_header) {
size_t packet_size = evbuffer_get_length(inbuf);
// +2 for \r\n
unsigned char *packet = pxy_malloc_packet(packet_size + ctx->sslproxy_header_len + 2, ctx);
if (!packet) {
return;
}
log_finest_va("ORIG packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet); evbuffer_remove(inbuf, packet, packet_size);
log_finest_va("ORIG packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet);
if (!ctx->sent_sslproxy_header) {
pxy_insert_sslproxy_header(ctx, packet, &packet_size); pxy_insert_sslproxy_header(ctx, packet, &packet_size);
} evbuffer_add(outbuf, packet, packet_size);
evbuffer_add(outbuf, packet, packet_size);
log_finest_va("NEW packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet); log_finest_va("NEW packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet);
free(packet); free(packet);
}
else {
evbuffer_add_buffer(outbuf, inbuf);
}
pxy_try_set_watermark(bev, ctx, ctx->dst.bev); pxy_try_set_watermark(bev, ctx, ctx->dst.bev);
} }
@ -228,14 +231,15 @@ protoautossl_bev_readcb_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
} }
} }
struct evbuffer *inbuf = bufferevent_get_input(bev); if (ctx->src.closed) {
size_t inbuf_size = evbuffer_get_length(inbuf); pxy_discard_inbuf(bev);
return;
log_finer_va("clienthello_search Discarding packet, size=%zu", inbuf_size); }
// Discard packets to client while searching for clienthello in autossl mode, because child conn passes them along already struct evbuffer *inbuf = bufferevent_get_input(bev);
// Otherwise client would receive the same packet twice struct evbuffer *outbuf = bufferevent_get_output(ctx->src.bev);
evbuffer_drain(inbuf, inbuf_size); evbuffer_add_buffer(outbuf, inbuf);
pxy_try_set_watermark(bev, ctx, ctx->src.bev);
} }
static void NONNULL(1,2) static void NONNULL(1,2)
@ -272,13 +276,16 @@ protoautossl_enable_src(pxy_conn_ctx_t *ctx)
if (protossl_setup_src_new_bev_ssl_accepting(ctx) == -1) { if (protossl_setup_src_new_bev_ssl_accepting(ctx) == -1) {
return -1; return -1;
} }
bufferevent_openssl_set_allow_dirty_shutdown(ctx->src.bev, 1);
} }
bufferevent_setcb(ctx->src.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx); bufferevent_setcb(ctx->src.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
// srvdst is xferred to the first child conn, so save the srvdst ssl info for logging // srvdst is xferred to the first child conn, so save the srvdst ssl info for logging
if (ctx->srvdst.bev && !autossl_ctx->clienthello_search && ctx->srvdst.ssl) { if (ctx->srvdst.bev && !autossl_ctx->clienthello_search && ctx->srvdst.ssl) {
ctx->sslctx->srvdst_ssl_version = strdup(SSL_get_version(ctx->srvdst.ssl)); if (!ctx->sslctx->srvdst_ssl_version && !ctx->sslctx->srvdst_ssl_cipher) {
ctx->sslctx->srvdst_ssl_cipher = strdup(SSL_get_cipher(ctx->srvdst.ssl)); ctx->sslctx->srvdst_ssl_version = strdup(SSL_get_version(ctx->srvdst.ssl));
ctx->sslctx->srvdst_ssl_cipher = strdup(SSL_get_cipher(ctx->srvdst.ssl));
}
} }
// Skip child listener setup if completing autossl upgrade, after finding clienthello // Skip child listener setup if completing autossl upgrade, after finding clienthello
@ -316,12 +323,15 @@ protoautossl_enable_conn_src_child(pxy_conn_child_ctx_t *ctx)
if (protossl_setup_src_new_bev_ssl_accepting(ctx->conn) == -1) { if (protossl_setup_src_new_bev_ssl_accepting(ctx->conn) == -1) {
return -1; return -1;
} }
bufferevent_openssl_set_allow_dirty_shutdown(ctx->conn->src.bev, 1);
bufferevent_setcb(ctx->conn->src.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx->conn); bufferevent_setcb(ctx->conn->src.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx->conn);
// srvdst is xferred to the first child conn, so save the ssl info for logging // srvdst is xferred to the first child conn, so save the ssl info for logging
if (ctx->dst.bev && !autossl_ctx->clienthello_search && ctx->dst.ssl) { if (ctx->dst.bev && !autossl_ctx->clienthello_search && ctx->dst.ssl) {
ctx->conn->sslctx->srvdst_ssl_version = strdup(SSL_get_version(ctx->dst.ssl)); if (!ctx->conn->sslctx->srvdst_ssl_version && !ctx->conn->sslctx->srvdst_ssl_cipher) {
ctx->conn->sslctx->srvdst_ssl_cipher = strdup(SSL_get_cipher(ctx->dst.ssl)); ctx->conn->sslctx->srvdst_ssl_version = strdup(SSL_get_version(ctx->dst.ssl));
ctx->conn->sslctx->srvdst_ssl_cipher = strdup(SSL_get_cipher(ctx->dst.ssl));
}
} }
log_finer_va("Enabling src, %s", ctx->conn->sslproxy_header); log_finer_va("Enabling src, %s", ctx->conn->sslproxy_header);
@ -366,6 +376,7 @@ protoautossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_co
return; return;
} }
bufferevent_setcb(ctx->dst.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx); bufferevent_setcb(ctx->dst.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
bufferevent_enable(ctx->dst.bev, EV_READ|EV_WRITE);
if (bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *)&ctx->spec->conn_dst_addr, if (bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *)&ctx->spec->conn_dst_addr,
ctx->spec->conn_dst_addrlen) == -1) { ctx->spec->conn_dst_addrlen) == -1) {
log_fine("FAILED bufferevent_socket_connect for dst"); log_fine("FAILED bufferevent_socket_connect for dst");

@ -290,7 +290,7 @@ prototcp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
if (!ctx->sent_sslproxy_header) { if (!ctx->sent_sslproxy_header) {
size_t packet_size = evbuffer_get_length(inbuf); size_t packet_size = evbuffer_get_length(inbuf);
// +2 is for \r\n // +2 for \r\n
unsigned char *packet = pxy_malloc_packet(packet_size + ctx->sslproxy_header_len + 2, ctx); unsigned char *packet = pxy_malloc_packet(packet_size + ctx->sslproxy_header_len + 2, ctx);
if (!packet) { if (!packet) {
return; return;
@ -298,12 +298,12 @@ prototcp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
evbuffer_remove(inbuf, packet, packet_size); evbuffer_remove(inbuf, packet, packet_size);
log_finest_va("ORIG packet, size=%zu, fd=%d:\n%.*s", packet_size, ctx->fd, (int)packet_size, packet); log_finest_va("ORIG packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet);
pxy_insert_sslproxy_header(ctx, packet, &packet_size); pxy_insert_sslproxy_header(ctx, packet, &packet_size);
evbuffer_add(outbuf, packet, packet_size); evbuffer_add(outbuf, packet, packet_size);
log_finest_va("NEW packet, size=%zu, fd=%d:\n%.*s", packet_size, ctx->fd, (int)packet_size, packet); log_finest_va("NEW packet, size=%zu:\n%.*s", packet_size, (int)packet_size, packet);
free(packet); free(packet);
} }

Loading…
Cancel
Save