From 19f80ba163b0452d2f29d652cf2675ccde18a32b Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Wed, 3 Sep 2025 14:34:19 +0200 Subject: [PATCH] Added TLS ncrypt I/O Signed-off-by: Toni Uhlig --- nDPId.c | 71 ++++++++++++++++++++++++++++++++------------------------ ncrypt.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ ncrypt.h | 8 ++++++- 3 files changed, 104 insertions(+), 31 deletions(-) diff --git a/nDPId.c b/nDPId.c index d2ab994df..fbfc380ac 100644 --- a/nDPId.c +++ b/nDPId.c @@ -2522,7 +2522,7 @@ static int connect_to_collector(struct nDPId_reader_thread * const reader_thread close(reader_thread->collector_sockfd); } - int sock_type = (nDPId_options.parsed_collector_address.raw.sa_family == AF_UNIX ? SOCK_STREAM : SOCK_DGRAM); + int sock_type = SOCK_STREAM; reader_thread->collector_sockfd = socket(nDPId_options.parsed_collector_address.raw.sa_family, sock_type, 0); if (reader_thread->collector_sockfd < 0 || set_fd_cloexec(reader_thread->collector_sockfd) < 0) { @@ -2549,12 +2549,6 @@ static int connect_to_collector(struct nDPId_reader_thread * const reader_thread return 1; } - if (shutdown(reader_thread->collector_sockfd, SHUT_RD) != 0) - { - reader_thread->collector_sock_last_errno = errno; - return 1; - } - reader_thread->collector_sock_last_errno = 0; return 0; @@ -2602,15 +2596,12 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread, if (connect_to_collector(reader_thread) == 0) { - if (nDPId_options.parsed_collector_address.raw.sa_family == AF_UNIX) - { - logger(1, - "[%8llu, %zu] Reconnected to nDPIsrvd Collector at %s", - workflow->packets_captured, - reader_thread->array_index, - GET_CMDARG_STR(nDPId_options.collector_address)); - jsonize_daemon(reader_thread, DAEMON_EVENT_RECONNECT); - } + logger(1, + "[%8llu, %zu] Reconnected to nDPIsrvd Collector at %s", + workflow->packets_captured, + reader_thread->array_index, + GET_CMDARG_STR(nDPId_options.collector_address)); + jsonize_daemon(reader_thread, DAEMON_EVENT_RECONNECT); } else { @@ -2653,9 +2644,24 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread, #endif errno = 0; + if (reader_thread->collector_sock_last_errno != 0) + { + return; + } + ssize_t written; - if (reader_thread->collector_sock_last_errno == 0 && - (written = write(reader_thread->collector_sockfd, newline_json_msg, s_ret)) != s_ret) +#ifdef ENABLE_CRYPTO + if (IS_CMDARG_SET(nDPId_options.server_ca_pem_file) != 0) + { + written = ncrypt_write(&workflow->ncrypt_entity, newline_json_msg, s_ret); + } + else +#endif + { + written = write(reader_thread->collector_sockfd, newline_json_msg, s_ret); + } + + if (written != s_ret) { saved_errno = errno; if (saved_errno == EPIPE || written == 0) @@ -2667,24 +2673,29 @@ static void send_to_collector(struct nDPId_reader_thread * const reader_thread, } if (saved_errno != EAGAIN) { - if (saved_errno == ECONNREFUSED) - { - logger(1, - "[%8llu, %zu] %s to %s refused by endpoint", - workflow->packets_captured, - reader_thread->array_index, - (nDPId_options.parsed_collector_address.raw.sa_family == AF_UNIX ? "Connection" : "Datagram"), - GET_CMDARG_STR(nDPId_options.collector_address)); - } reader_thread->collector_sock_last_errno = saved_errno; } - else if (nDPId_options.parsed_collector_address.raw.sa_family == AF_UNIX) + else { size_t pos = (written < 0 ? 0 : written); set_collector_block(reader_thread); - while ((size_t)(written = write(reader_thread->collector_sockfd, newline_json_msg + pos, s_ret - pos)) != - s_ret - pos) + while (1) { +#ifdef ENABLE_CRYPTO + if (IS_CMDARG_SET(nDPId_options.server_ca_pem_file) != 0) + { + written = ncrypt_write(&workflow->ncrypt_entity, newline_json_msg + pos, s_ret - pos); + } + else +#endif + { + written = write(reader_thread->collector_sockfd, newline_json_msg + pos, s_ret - pos); + } + if ((size_t)written == s_ret - pos) + { + break; + } + saved_errno = errno; if (saved_errno == EPIPE || written == 0) { diff --git a/ncrypt.c b/ncrypt.c index e05fad28c..484c18864 100644 --- a/ncrypt.c +++ b/ncrypt.c @@ -112,7 +112,9 @@ int ncrypt_on_connect(struct ncrypt_ctx * const ctx, int connect_fd, struct ncry int rv = SSL_do_handshake(ent->ssl); if (rv != 1) + { return SSL_get_error(ent->ssl, rv); + } return NCRYPT_SUCCESS; } @@ -132,11 +134,65 @@ int ncrypt_on_accept(struct ncrypt_ctx * const ctx, int accept_fd, struct ncrypt int rv = SSL_accept(ent->ssl); if (rv != 1) + { return SSL_get_error(ent->ssl, rv); + } return NCRYPT_SUCCESS; } +ssize_t ncrypt_read(struct ncrypt_entity * const ent, char * const json_msg, size_t json_msg_len) +{ + if (ent->ssl == NULL) + { + errno = EPROTO; + return -1; + } + + int rv = SSL_read(ent->ssl, json_msg, json_msg_len); + if (rv <= 0) + { + int err = SSL_get_error(ent->ssl, rv); + if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) + { + errno = EAGAIN; + } + else if (err != SSL_ERROR_SYSCALL) + { + errno = EPROTO; + } + return -1; + } + + return rv; +} + +ssize_t ncrypt_write(struct ncrypt_entity * const ent, char const * const json_msg, size_t json_msg_len) +{ + if (ent->ssl == NULL) + { + errno = EPROTO; + return -1; + } + + int rv = SSL_write(ent->ssl, json_msg, json_msg_len); + if (rv <= 0) + { + int err = SSL_get_error(ent->ssl, rv); + if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) + { + errno = EAGAIN; + } + else if (err != SSL_ERROR_SYSCALL) + { + errno = EPROTO; + } + return -1; + } + + return rv; +} + void ncrypt_free_entity(struct ncrypt_entity * const ent) { SSL_free(ent->ssl); diff --git a/ncrypt.h b/ncrypt.h index 8ef8f459b..628513912 100644 --- a/ncrypt.h +++ b/ncrypt.h @@ -1,6 +1,8 @@ #ifndef NCRYPT_H #define NCRYPT_H 1 +#include + #define ncrypt_ctx(x) \ do \ { \ @@ -30,7 +32,7 @@ enum NCRYPT_NOT_INITIALIZED = -1, NCRYPT_ALREADY_INITIALIZED = -2, NCRYPT_NULL_PTR = -3, - NCRYPT_PEM_LOAD_FAILED = -4, + NCRYPT_PEM_LOAD_FAILED = -4 }; struct ncrypt_ctx @@ -60,6 +62,10 @@ int ncrypt_on_connect(struct ncrypt_ctx * const ctx, int connect_fd, struct ncry int ncrypt_on_accept(struct ncrypt_ctx * const ctx, int accept_fd, struct ncrypt_entity * const ent); +ssize_t ncrypt_read(struct ncrypt_entity * const ent, char * const json_msg, size_t json_msg_len); + +ssize_t ncrypt_write(struct ncrypt_entity * const ent, char const * const json_msg, size_t json_msg_len); + void ncrypt_free_entity(struct ncrypt_entity * const ent); void ncrypt_free_ctx(struct ncrypt_ctx * const ctx);