diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d27e84e84..78864b07f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,7 +205,7 @@ if(ENABLE_CRYPTO) set(CRYPTO_SRCS ncrypt.c) endif() add_executable(nDPId nDPId.c ${NDPID_PFRING_SRCS} ${CRYPTO_SRCS} nio.c utils.c) -add_executable(nDPIsrvd nDPIsrvd.c nio.c utils.c) +add_executable(nDPIsrvd nDPIsrvd.c ${CRYPTO_SRCS} nio.c utils.c) add_executable(nDPId-test nDPId-test.c ${NDPID_PFRING_SRCS} ${CRYPTO_SRCS}) add_custom_target(umask_check) @@ -475,8 +475,9 @@ target_link_libraries(nDPId "${STATIC_LIBNDPI_LIB}" "${STATIC_PFRING_LIB}" "${pk "${GCRYPT_LIBRARY}" "${GCRYPT_ERROR_LIBRARY}" "${PCAP_LIBRARY}" "${LIBM_LIB}" "${PF_RING_LIB}" "${OSSL_LIBRARY}" "${DYNLDR}" "-pthread") -target_compile_definitions(nDPIsrvd PRIVATE -D_GNU_SOURCE=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\" ${NDPID_DEFS} ${EPOLL_DEFS}) +target_compile_definitions(nDPIsrvd PRIVATE -D_GNU_SOURCE=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\" ${NDPID_DEFS} ${EPOLL_DEFS} ${OSSL_DEFS}) target_include_directories(nDPIsrvd PRIVATE ${NDPID_DEPS_INC}) +target_link_libraries(nDPIsrvd "${OSSL_LIBRARY}") target_compile_options(nDPId-test PRIVATE "-Wno-unused-function" "-pthread") target_compile_definitions(nDPId-test PRIVATE -D_GNU_SOURCE=1 -DNO_MAIN=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\" diff --git a/nDPId.c b/nDPId.c index 2836b4a57d..c0541936d9 100644 --- a/nDPId.c +++ b/nDPId.c @@ -5560,7 +5560,7 @@ static void print_usage(char const * const arg0) "\t \tDefault: disabled\n" "\t-L\tLog all messages to a log file.\n" "\t \tDefault: disabled\n" - "\t-c\tPath to a UNIX socket (nDPIsrvd Collector) or a custom UDP endpoint.\n" + "\t-c\tPath to a UNIX socket (nDPIsrvd Collector) or a custom TCP endpoint.\n" "\t \tDefault: `%s'\n" #ifdef ENABLE_CRYPTO "\t-k\tPath to the client certificate file (PEM format)\n" @@ -6343,12 +6343,11 @@ int main(int argc, char ** argv) global_context = NULL; daemonize_shutdown(GET_CMDARG_STR(nDPId_options.pidfile)); - logger(0, "%s", "Bye."); - shutdown_logging(); - #ifdef ENABLE_CRYPTO ncrypt_free_ctx(&ncrypt_ctx); #endif + logger(0, "%s", "Bye."); + shutdown_logging(); return 0; } diff --git a/nDPIsrvd.c b/nDPIsrvd.c index 4324420278..dedf155f0a 100644 --- a/nDPIsrvd.c +++ b/nDPIsrvd.c @@ -8,9 +8,9 @@ #include #include #include +#include #include #include -#include #include #if !defined(__FreeBSD__) && !defined(__APPLE__) #include @@ -21,12 +21,16 @@ #include "config.h" #include "nDPIsrvd.h" +#ifdef ENABLE_CRYPTO +#include "ncrypt.h" +#endif #include "nio.h" #include "utils.h" enum sock_type { COLLECTOR_UN, + COLLECTOR_IN, DISTRIBUTOR_UN, DISTRIBUTOR_IN, }; @@ -55,6 +59,17 @@ struct remote_desc struct nDPIsrvd_json_buffer main_read_buffer; } event_collector_un; struct + { + struct sockaddr_in peer; + char peer_addr[INET_ADDRSTRLEN]; +#ifdef ENABLE_CRYPTO + struct ncrypt_entity ncrypt_entity; +#endif + + struct nDPIsrvd_json_buffer main_read_buffer; + UT_array * additional_write_buffers; + } event_collector_in; /* TCP/IP socket */ + struct { struct sockaddr_un peer; #if !defined(__FreeBSD__) && !defined(__APPLE__) @@ -85,11 +100,15 @@ static struct static int nDPIsrvd_main_thread_shutdown = 0; static int collector_un_sockfd = -1; +static int collector_in_sockfd = -1; static int distributor_un_sockfd = -1; static int distributor_in_sockfd = -1; static struct nDPIsrvd_address distributor_in_address = { .raw.sa_family = (sa_family_t)0xFFFF, }; +#ifdef ENABLE_CRYPTO +static struct ncrypt_ctx ncrypt_ctx; +#endif static struct { @@ -108,6 +127,11 @@ static struct #ifdef ENABLE_EPOLL struct cmdarg use_poll; #endif +#ifdef ENABLE_CRYPTO + struct cmdarg server_crt_pem_file; + struct cmdarg server_key_pem_file; + struct cmdarg server_ca_pem_file; +#endif } nDPIsrvd_options = {.config_file = CMDARG_STR(NULL), .pidfile = CMDARG_STR(nDPIsrvd_PIDFILE), .collector_un_sockpath = CMDARG_STR(COLLECTOR_UNIX_SOCKET), @@ -124,6 +148,12 @@ static struct , .use_poll = CMDARG_BOOL(0) #endif +#ifdef ENABLE_CRYPTO + , + .server_crt_pem_file = CMDARG_STR(NULL), + .server_key_pem_file = CMDARG_STR(NULL), + .server_ca_pem_file = CMDARG_STR(NULL) +#endif }; struct confopt config_map[] = {CONFOPT("pidfile", &nDPIsrvd_options.pidfile), CONFOPT("collector", &nDPIsrvd_options.collector_un_sockpath), @@ -140,6 +170,12 @@ struct confopt config_map[] = {CONFOPT("pidfile", &nDPIsrvd_options.pidfile), , CONFOPT("poll", &nDPIsrvd_options.use_poll) #endif +#ifdef ENABLE_CRYPTO + , + CONFOPT("cert", &nDPIsrvd_options.server_crt_pem_file), + CONFOPT("key", &nDPIsrvd_options.server_key_pem_file), + CONFOPT("ca", &nDPIsrvd_options.server_ca_pem_file) +#endif }; static void logger_nDPIsrvd(struct remote_desc const * const remote, @@ -214,6 +250,8 @@ static struct nDPIsrvd_json_buffer * get_read_buffer(struct remote_desc * const { case COLLECTOR_UN: return &remote->event_collector_un.main_read_buffer; + case COLLECTOR_IN: + return &remote->event_collector_in.main_read_buffer; case DISTRIBUTOR_UN: case DISTRIBUTOR_IN: @@ -229,6 +267,8 @@ static struct nDPIsrvd_write_buffer * get_write_buffer(struct remote_desc * cons { case COLLECTOR_UN: return NULL; + case COLLECTOR_IN: + return NULL; case DISTRIBUTOR_UN: return &remote->event_distributor_un.main_write_buffer; @@ -246,6 +286,8 @@ static UT_array * get_additional_write_buffers(struct remote_desc * const remote { case COLLECTOR_UN: return NULL; + case COLLECTOR_IN: + return NULL; case DISTRIBUTOR_UN: return remote->event_distributor_un.additional_write_buffers; @@ -341,6 +383,15 @@ static __attribute__((format(printf, 3, 4))) void logger_nDPIsrvd(struct remote_ logger(1, "%s %s", prefix, logbuf); #endif break; + case COLLECTOR_IN: + logger(1, + "%s %.*s:%u %s", + prefix, + (int)sizeof(remote->event_collector_in.peer_addr), + remote->event_collector_in.peer_addr, + ntohs(remote->event_collector_in.peer.sin_port), + logbuf); + break; } va_end(ap); @@ -692,6 +743,14 @@ static struct remote_desc * get_remote_descriptor(enum sock_type type, int remot return NULL; } break; + case COLLECTOR_IN: + if (nDPIsrvd_json_buffer_init(&remotes.desc[i].event_collector_in.main_read_buffer, + max_buffer_size) != 0) + { + logger(1, "Read/JSON buffer init failed, size: %zu bytes", max_buffer_size); + return NULL; + } + break; case DISTRIBUTOR_UN: write_buffer = &remotes.desc[i].event_distributor_un.main_write_buffer; additional_write_buffers = &remotes.desc[i].event_distributor_un.additional_write_buffers; @@ -751,6 +810,13 @@ static void free_remote(struct nio * const io, struct remote_desc * remote) } nDPIsrvd_json_buffer_free(&remote->event_collector_un.main_read_buffer); break; + case COLLECTOR_IN: + if (errno != 0) + { + logger_nDPIsrvd(remote, "Error closing collector connection", ": %s", strerror(errno)); + } + nDPIsrvd_json_buffer_free(&remote->event_collector_in.main_read_buffer); + break; case DISTRIBUTOR_UN: if (errno != 0) { @@ -830,7 +896,7 @@ static int nDPIsrvd_parse_options(int argc, char ** argv) { int opt; - while ((opt = getopt(argc, argv, "f:lL:c:dp:s:S:G:m:u:g:C:Dvh")) != -1) + while ((opt = getopt(argc, argv, "f:lL:c:k:K:F:dp:s:S:G:m:u:g:C:Dvh")) != -1) { switch (opt) { @@ -849,6 +915,33 @@ static int nDPIsrvd_parse_options(int argc, char ** argv) case 'c': set_cmdarg_string(&nDPIsrvd_options.collector_un_sockpath, optarg); break; + case 'k': +#ifdef ENABLE_CRYPTO + set_cmdarg_string(&nDPIsrvd_options.server_crt_pem_file, optarg); + break; +#else + logger(1, "Server cert PEM file: %s", + "nDPId was built w/o OpenSSL/Crypto support"); + return 1; +#endif + case 'K': +#ifdef ENABLE_CRYPTO + set_cmdarg_string(&nDPIsrvd_options.server_key_pem_file, optarg); + break; +#else + logger(1, "Server key PEM file: %s", + "nDPId was built w/o OpenSSL/Crypto support"); + return 1; +#endif + case 'F': +#ifdef ENABLE_CRYPTO + set_cmdarg_string(&nDPIsrvd_options.server_ca_pem_file, optarg); + break; +#else + logger(1, "Server CA PEM file: %s", + "nDPId was built w/o OpenSSL/Crypto support"); + return 1; +#endif case 'e': #ifdef ENABLE_EPOLL set_cmdarg_boolean(&nDPIsrvd_options.use_poll, 1); @@ -1044,6 +1137,7 @@ static int new_connection(struct nio * const io, int eventfd) union { struct sockaddr_un saddr_collector_un; + struct sockaddr_in saddr_collector_in; struct sockaddr_un saddr_distributor_un; struct sockaddr_in saddr_distributor_in; } sockaddr; @@ -1057,6 +1151,12 @@ static int new_connection(struct nio * const io, int eventfd) stype = COLLECTOR_UN; server_fd = collector_un_sockfd; } + else if (eventfd == collector_in_sockfd) + { + peer_addr_len = sizeof(sockaddr.saddr_collector_in); + stype = COLLECTOR_IN; + server_fd = collector_in_sockfd; + } else if (eventfd == distributor_un_sockfd) { peer_addr_len = sizeof(sockaddr.saddr_distributor_un); @@ -1105,6 +1205,19 @@ static int new_connection(struct nio * const io, int eventfd) current->event_collector_un.pid = ucred.pid; #endif + logger_nDPIsrvd(current, "New collector connection from", "%s", ""); + break; + case COLLECTOR_IN: + current->event_collector_in.peer = sockaddr.saddr_collector_in; + + if (inet_ntop(current->event_collector_in.peer.sin_family, + ¤t->event_collector_in.peer.sin_addr, + ¤t->event_collector_in.peer_addr[0], + sizeof(current->event_collector_in.peer_addr)) == NULL) + { + logger(1, "Error converting an internet address: %s", strerror(errno)); + return 1; + } logger_nDPIsrvd(current, "New collector connection from", "%s", ""); break; case DISTRIBUTOR_UN: @@ -1506,6 +1619,7 @@ static int mainloop(struct nio * const io) switch (current->sock_type) { case COLLECTOR_UN: + case COLLECTOR_IN: logger_nDPIsrvd(current, "Collector connection", "closed"); break; case DISTRIBUTOR_UN: @@ -1701,6 +1815,10 @@ int main(int argc, char ** argv) nio_init(&io); init_logging("nDPIsrvd"); +#ifdef ENABLE_CRYPTO + ncrypt_init(); + ncrypt_ctx(&ncrypt_ctx); +#endif if (nDPIsrvd_parse_options(argc, argv) != 0) { @@ -1732,6 +1850,17 @@ int main(int argc, char ** argv) return 1; } } +#ifdef ENABLE_CRYPTO + if (IS_CMDARG_SET(nDPIsrvd_options.server_ca_pem_file) != 0 && + ncrypt_init_client(&ncrypt_ctx, + GET_CMDARG_STR(nDPIsrvd_options.server_ca_pem_file), + GET_CMDARG_STR(nDPIsrvd_options.server_key_pem_file), + GET_CMDARG_STR(nDPIsrvd_options.server_crt_pem_file)) != NCRYPT_SUCCESS) + { + logger_early(1, "%s", "Could not initialize crypto."); + return 1; + } +#endif if (is_daemonize_enabled() != 0 && is_console_logger_enabled() != 0) { @@ -1928,6 +2057,9 @@ int main(int argc, char ** argv) close(distributor_in_sockfd); daemonize_shutdown(GET_CMDARG_STR(nDPIsrvd_options.pidfile)); +#ifdef ENABLE_CRYPTO + ncrypt_free_ctx(&ncrypt_ctx); +#endif logger(0, "Bye."); shutdown_logging();