Skip to content

Commit

Permalink
tls: added alpn support for server sessions
Browse files Browse the repository at this point in the history
Signed-off-by: Leonardo Alminana <leonardo.alminana@chronosphere.io>
  • Loading branch information
leonardo-albertovich authored and edsiper committed Mar 14, 2024
1 parent a2eacc8 commit 1feb741
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
6 changes: 6 additions & 0 deletions include/fluent-bit/tls/flb_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ struct flb_tls_backend {
/* destroy backend context */
void (*context_destroy) (void *);

/* Additional settings */
int (*context_alpn_set) (void *, const char *);

/* Session management */
void *(*session_create) (struct flb_tls *, int);
int (*session_destroy) (void *);
Expand Down Expand Up @@ -106,6 +109,9 @@ struct flb_tls *flb_tls_create(int mode,
const char *key_file, const char *key_passwd);

int flb_tls_destroy(struct flb_tls *tls);

int flb_tls_set_alpn(struct flb_tls *tls, const char *alpn);

int flb_tls_load_system_certificates(struct flb_tls *tls);

struct mk_list *flb_tls_get_config_map(struct flb_config *config);
Expand Down
10 changes: 10 additions & 0 deletions src/tls/flb_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ int flb_tls_destroy(struct flb_tls *tls)
return 0;
}

int flb_tls_set_alpn(struct flb_tls *tls, const char *alpn)
{
if (tls->ctx) {
return tls->api->context_alpn_set(tls->ctx, alpn);
}

return 0;
}


int flb_tls_net_read(struct flb_tls_session *session, void *buf, size_t len)
{
time_t timeout_timestamp;
Expand Down
115 changes: 114 additions & 1 deletion src/tls/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct tls_context {
int debug_level;
SSL_CTX *ctx;
int mode;
char *alpn;
pthread_mutex_t mutex;
};

Expand Down Expand Up @@ -122,11 +123,113 @@ static void tls_context_destroy(void *ctx_backend)

pthread_mutex_lock(&ctx->mutex);
SSL_CTX_free(ctx->ctx);
if (ctx->alpn != NULL) {
flb_free(ctx->alpn);
}
pthread_mutex_unlock(&ctx->mutex);

flb_free(ctx);
}

int tls_context_alpn_set(void *ctx_backend, const char *alpn)
{
size_t wire_format_alpn_index;
char *alpn_token_context;
char *alpn_working_copy;
char *wire_format_alpn;
char *alpn_token;
int result;
struct tls_context *ctx;

ctx = (struct tls_context *) ctx_backend;

result = 0;

if (alpn != NULL) {
wire_format_alpn = flb_calloc(strlen(alpn),
sizeof(char) + 1);

if (wire_format_alpn == NULL) {
return -1;
}

alpn_working_copy = strdup(alpn);

if (alpn_working_copy == NULL) {
flb_free(wire_format_alpn);

return -1;
}

wire_format_alpn_index = 1;
alpn_token_context = NULL;

alpn_token = strtok_r(alpn_working_copy,
",",
&alpn_token_context);

while (alpn_token != NULL) {
wire_format_alpn[wire_format_alpn_index] = \
(char) strlen(alpn_token);

strcpy(&wire_format_alpn[wire_format_alpn_index + 1],
alpn_token);

wire_format_alpn_index += strlen(alpn_token) + 1;

alpn_token = strtok_r(NULL,
",",
&alpn_token_context);
}

if (wire_format_alpn_index > 1) {
wire_format_alpn[0] = (char) wire_format_alpn_index - 1;
ctx->alpn = wire_format_alpn;
}

free(alpn_working_copy);
}

if (result != 0) {
result = -1;
}

return result;
}

static int tls_context_server_alpn_select_callback(SSL *ssl,
unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
unsigned int inlen,
void *arg)
{
int result;
struct tls_context *ctx;

ctx = (struct tls_context *) arg;

result = SSL_TLSEXT_ERR_NOACK;

if (ctx->alpn != NULL) {
result = SSL_select_next_proto(out,
outlen,
&ctx->alpn[1],
(unsigned int) ctx->alpn[0],
in,
inlen);

if (result == OPENSSL_NPN_NEGOTIATED) {
result = SSL_TLSEXT_ERR_OK;
}
else if (result == OPENSSL_NPN_NO_OVERLAP) {
result = SSL_TLSEXT_ERR_ALERT_FATAL;
}
}

return result;
}

#ifdef _MSC_VER
static int windows_load_system_certificates(struct tls_context *ctx)
{
Expand Down Expand Up @@ -196,7 +299,7 @@ static int load_system_certificates(struct tls_context *ctx)
}
return 0;
}

static void *tls_context_create(int verify,
int debug,
int mode,
Expand Down Expand Up @@ -242,6 +345,7 @@ static void *tls_context_create(int verify,
ssl_ctx = SSL_CTX_new(TLS_client_method());
}
#endif

if (!ssl_ctx) {
flb_error("[openssl] could not create context");
return NULL;
Expand All @@ -254,9 +358,16 @@ static void *tls_context_create(int verify,
}
ctx->ctx = ssl_ctx;
ctx->mode = mode;
ctx->alpn = NULL;
ctx->debug_level = debug;
pthread_mutex_init(&ctx->mutex, NULL);

if (mode == FLB_TLS_SERVER_MODE) {
SSL_CTX_set_alpn_select_cb(ssl_ctx,
tls_context_server_alpn_select_callback,
ctx);
}

/* Verify peer: by default OpenSSL always verify peer */
if (verify == FLB_FALSE) {
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
Expand Down Expand Up @@ -388,6 +499,7 @@ static int tls_session_destroy(void *session)
if (flb_socket_error(ptr->fd) == 0) {
SSL_shutdown(ptr->ssl);
}

SSL_free(ptr->ssl);
flb_free(ptr);

Expand Down Expand Up @@ -608,6 +720,7 @@ static struct flb_tls_backend tls_openssl = {
.name = "openssl",
.context_create = tls_context_create,
.context_destroy = tls_context_destroy,
.context_alpn_set = tls_context_alpn_set,
.session_create = tls_session_create,
.session_destroy = tls_session_destroy,
.net_read = tls_net_read,
Expand Down

0 comments on commit 1feb741

Please sign in to comment.