diff --git a/configure.ac b/configure.ac index 36fcc6d19..8b58d18cb 100644 --- a/configure.ac +++ b/configure.ac @@ -413,6 +413,7 @@ then test "$enable_fallback_scsv" = "" && enable_fallback_scsv=yes test "$enable_anon" = "" && enable_anon=yes test "$enable_mcast" = "" && enable_mcast=yes + test "$enable_network_introspection" = "" && enable_network_introspection=yes if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" then @@ -2501,6 +2502,20 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_STACK_LOG -finstrument-functions" fi + +# API for tracking network connection attributes +AC_ARG_ENABLE([network-introspection], + [AS_HELP_STRING([--enable-network-introspection],[Enable network connection attribute tracking and callbacks (default: disabled)])], + [ ENABLED_NETWORK_INTROSPECTION=$enableval ], + [ ENABLED_NETWORK_INTROSPECTION=no ] + ) + +if test "$ENABLED_NETWORK_INTROSPECTION" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NETWORK_INTROSPECTION" +fi + + if test "$ENABLED_QT" = "yes" then # Requires opensslextra and opensslall @@ -6567,8 +6582,8 @@ echo " * DSA: $ENABLED_DSA" echo " * DH: $ENABLED_DH" echo " * DH Default Parameters: $ENABLED_DHDEFAULTPARAMS" echo " * ECC: $ENABLED_ECC" -echo " * ECC Custom Curves $ENABLED_ECCCUSTCURVES" -echo " * ECC Minimum Bits $ENABLED_ECCMINSZ" +echo " * ECC Custom Curves: $ENABLED_ECCCUSTCURVES" +echo " * ECC Minimum Bits: $ENABLED_ECCMINSZ" echo " * CURVE25519: $ENABLED_CURVE25519" echo " * ED25519: $ENABLED_ED25519" echo " * CURVE448: $ENABLED_CURVE448" @@ -6582,6 +6597,7 @@ echo " * Anonymous cipher: $ENABLED_ANON" echo " * CODING: $ENABLED_CODING" echo " * MEMORY: $ENABLED_MEMORY" echo " * I/O POOL: $ENABLED_IOPOOL" +echo " * Connection tracking: $ENABLED_NETWORK_INTROSPECTION" echo " * LIGHTY: $ENABLED_LIGHTY" echo " * HAPROXY: $ENABLED_HAPROXY" echo " * STUNNEL: $ENABLED_STUNNEL" @@ -6589,8 +6605,8 @@ echo " * Apache httpd: $ENABLED_APACHE_HTTPD" echo " * NGINX: $ENABLED_NGINX" echo " * ASIO: $ENABLED_ASIO" echo " * LIBWEBSOCKETS: $ENABLED_LIBWEBSOCKETS" -echo " * Qt $ENABLED_QT" -echo " * Qt Unit Testing $ENABLED_QT_TEST" +echo " * Qt: $ENABLED_QT" +echo " * Qt Unit Testing: $ENABLED_QT_TEST" echo " * SIGNAL: $ENABLED_SIGNAL" echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS" echo " * DTLS: $ENABLED_DTLS" @@ -6631,12 +6647,12 @@ echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION" echo " * Fallback SCSV: $ENABLED_FALLBACK_SCSV" echo " * Keying Material Exporter: $ENABLED_KEYING_MATERIAL" echo " * All TLS Extensions: $ENABLED_TLSX" -echo " * PKCS#7 $ENABLED_PKCS7" -echo " * S/MIME $ENABLED_SMIME" -echo " * wolfSSH $ENABLED_WOLFSSH" -echo " * wolfTPM $ENABLED_WOLFTPM" -echo " * wolfSCEP $ENABLED_WOLFSCEP" -echo " * Secure Remote Password $ENABLED_SRP" +echo " * PKCS#7: $ENABLED_PKCS7" +echo " * S/MIME: $ENABLED_SMIME" +echo " * wolfSSH: $ENABLED_WOLFSSH" +echo " * wolfTPM: $ENABLED_WOLFTPM" +echo " * wolfSCEP: $ENABLED_WOLFSCEP" +echo " * Secure Remote Password: $ENABLED_SRP" echo " * Small Stack: $ENABLED_SMALL_STACK" echo " * Linux Kernel Module: $ENABLED_LINUXKM" echo " * valgrind unit tests: $ENABLED_VALGRIND" diff --git a/examples/server/server.c b/examples/server/server.c index 6a12e2cd2..214e96ad2 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2468,8 +2468,82 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) if (readySignal) { readySignal->srfName = serverReadyFile; } - tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, - dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen); + + { + SOCKADDR_IN_T client_addr; + socklen_t client_len = sizeof(client_addr); + + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, + dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen, + &client_addr, &client_len); + +#ifdef WOLFSSL_NETWORK_INTROSPECTION + + SOCKADDR_IN_T local_addr; + socklen_t local_len = sizeof(local_addr); + getsockname(clientfd, (struct sockaddr *)&local_addr, (socklen_t *)&local_len); + + if (((struct sockaddr *)&client_addr)->sa_family != ((struct sockaddr *)&local_addr)->sa_family) + err_sys_ex(catastrophic, "client_addr.sa_family != local_addr.sa_family"); + +#ifdef TEST_IPV6 + + if ((ret = wolfSSL_set_endpoints( + ssl, + 0 /* interface_id */, + client_addr.sin6_family, + IPPROTO_TCP, + sizeof(client_addr.sin6_addr), + (byte *)&client_addr.sin6_addr, + (byte *)&local_addr.sin6_addr, + client_addr.sin6_port, + local_addr.sin6_port) != WOLFSSL_SUCCESS)) { + printf("wolfSSL_set_endpoints(): %s\n", wolfSSL_ERR_error_string(ret, NULL)); + err_sys_ex(catastrophic, "error in wolfSSL_set_endpoints()"); + } + +#else /* !TEST_IPV6 */ + + if ((ret = wolfSSL_set_endpoints( + ssl, + 0 /* interface_id */, + client_addr.sin_family, + IPPROTO_TCP, + sizeof(struct in_addr), + (byte *)&client_addr.sin_addr, + (byte *)&local_addr.sin_addr, + client_addr.sin_port, + local_addr.sin_port) != WOLFSSL_SUCCESS)) { + printf("wolfSSL_set_endpoints(): %s\n", wolfSSL_ERR_error_string(ret, NULL)); + err_sys_ex(catastrophic, "error in wolfSSL_set_endpoints()"); + } + +#endif /* TEST_IPV6 */ + + { + const struct wolfSSL_network_connection *nc; + const void *remote_addr2; + const void *local_addr2; + char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN]; + + if ((ret = wolfSSL_get_endpoints(ssl, &nc, &remote_addr2, &local_addr2)) != WOLFSSL_SUCCESS) { + printf("wolfSSL_get_endpoints(): %s\n", wolfSSL_ERR_error_string(ret, NULL)); + err_sys_ex(catastrophic, "error in wolfSSL_get_endpoints()"); + } + + printf("stored: family=%d proto=%d rport=%d lport=%d raddr=%s laddr=%s interface=%d\n", + nc->family, + nc->proto, + nc->remote_port, + nc->local_port, + inet_ntop(nc->family, remote_addr2, inet_ntop_buf, sizeof inet_ntop_buf), + inet_ntop(nc->family, local_addr2, inet_ntop_buf2, sizeof inet_ntop_buf2), + nc->interface); + } + +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ + } + doListen = 0; /* Don't listen next time */ if (port == 0) { diff --git a/src/internal.c b/src/internal.c index a07ec266c..9337b90b6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5581,6 +5581,11 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif #endif +#ifdef WOLFSSL_NETWORK_INTROSPECTION + ssl->AcceptFilter = ctx->AcceptFilter; + ssl->AcceptFilter_arg = ctx->AcceptFilter_arg; +#endif + ssl->CBIORecv = ctx->CBIORecv; ssl->CBIOSend = ctx->CBIOSend; #ifdef OPENSSL_EXTRA @@ -6460,6 +6465,12 @@ void SSL_ResourceFree(WOLFSSL* ssl) FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); ssl->peerRsaKeyPresent = 0; #endif +#ifdef WOLFSSL_NETWORK_INTROSPECTION + if (WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(ssl->buffers.network_connection)) + XFREE(ssl->buffers.network_connection_addr_buffer_dynamic, ssl->heap, DYNAMIC_TYPE_SOCKADDR); + if (WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(ssl->buffers.network_connection_layer2)) + XFREE(ssl->buffers.network_connection_layer2_addr_buffer_dynamic, ssl->heap, DYNAMIC_TYPE_SOCKADDR); +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ #ifdef WOLFSSL_RENESAS_TSIP_TLS XFREE(ssl->peerTsipEncRsaKeyIndex, ssl->heap, DYNAMIC_TYPE_RSA); #endif diff --git a/src/ssl.c b/src/ssl.c index ffc1e2ca4..ee8d010c6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1013,6 +1013,234 @@ int wolfSSL_mutual_auth(WOLFSSL* ssl, int req) } #endif /* NO_CERTS */ +#ifdef WOLFSSL_NETWORK_INTROSPECTION + +/* all ints in host byte order, addresses in network order (big endian). */ +static WC_INLINE int wolfSSL_set_endpoints_1( + WOLFSSL* ssl, + struct wolfSSL_network_connection *nc, + byte **nc_addr_buffer_dynamic, + unsigned int interface_id, + unsigned int family, + unsigned int proto, + unsigned int remote_addr_len, + const byte *remote_addr, + unsigned int local_addr_len, + const byte *local_addr, + unsigned int remote_port, + unsigned int local_port) +{ + size_t current_dynamic_alloc, needed_dynamic_alloc; + + if ((ssl == NULL) || (nc == NULL) || (remote_addr_len == 0) || (local_addr_len == 0)) + return BAD_FUNC_ARG; + + if (WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(*nc)) + current_dynamic_alloc = nc->local_addr_len + nc->remote_addr_len; + else + current_dynamic_alloc = 0; + + if (local_addr_len + remote_addr_len > WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES) + needed_dynamic_alloc = local_addr_len + remote_addr_len; + else + needed_dynamic_alloc = 0; + + nc->local_addr_len = nc->remote_addr_len = 0; + + if (current_dynamic_alloc != needed_dynamic_alloc) { + if (current_dynamic_alloc > 0) + XFREE(*nc_addr_buffer_dynamic, ssl->heap, DYNAMIC_TYPE_SOCKADDR); + if (needed_dynamic_alloc > 0) { + *nc_addr_buffer_dynamic = (byte *)XMALLOC + (needed_dynamic_alloc, + ssl->heap, + DYNAMIC_TYPE_SOCKADDR); + if (*nc_addr_buffer_dynamic == NULL) + return MEMORY_E; + } + } + + nc->family = family; + nc->proto = proto; + nc->remote_addr_len = remote_addr_len; + nc->local_addr_len = local_addr_len; + nc->interface = interface_id; + nc->remote_port = remote_port; + nc->local_port = local_port; + + if (needed_dynamic_alloc == 0) { + XMEMCPY(nc->addr_buffer, remote_addr, remote_addr_len); + XMEMCPY(nc->addr_buffer + remote_addr_len, local_addr, local_addr_len); + } else { + XMEMCPY(*nc_addr_buffer_dynamic, remote_addr, remote_addr_len); + XMEMCPY((*nc_addr_buffer_dynamic) + remote_addr_len, local_addr, local_addr_len); + } + nc->remote_addr_len = remote_addr_len; + nc->local_addr_len = local_addr_len; + + return WOLFSSL_SUCCESS; +} + +int wolfSSL_set_endpoints( + WOLFSSL* ssl, + unsigned int interface_id, + unsigned int family, + unsigned int proto, + unsigned int addr_len, + const byte *remote_addr, + const byte *local_addr, + unsigned int remote_port, + unsigned int local_port) +{ + return wolfSSL_set_endpoints_1( + ssl, + &ssl->buffers.network_connection, + &ssl->buffers.network_connection_addr_buffer_dynamic, + interface_id, + family, + proto, + addr_len, + remote_addr, + addr_len, + local_addr, + remote_port, + local_port); +} + +int wolfSSL_set_endpoints_layer2( + WOLFSSL* ssl, + unsigned int interface_id, + unsigned int family, + unsigned int addr_len, + const byte *remote_addr, + const byte *local_addr) +{ + return wolfSSL_set_endpoints_1( + ssl, + &ssl->buffers.network_connection_layer2, + &ssl->buffers.network_connection_layer2_addr_buffer_dynamic, + interface_id, + family, + 0 /* proto */, + addr_len, + remote_addr, + addr_len, + local_addr, + 0 /* remote_port */, + 0 /* local_port */); +} + +static WC_INLINE int wolfSSL_get_endpoints_1( + const struct wolfSSL_network_connection *nc, + byte *nc_addr_buffer_dynamic, + const void **remote_addr, + const void **local_addr) +{ + if ((remote_addr == NULL) || (local_addr == NULL)) + return BAD_FUNC_ARG; + if (nc->remote_addr_len == 0) + return INCOMPLETE_DATA; + + if (WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(*nc)) { + *remote_addr = nc_addr_buffer_dynamic; + *local_addr = nc_addr_buffer_dynamic + nc->remote_addr_len; + } else { + *remote_addr = nc->addr_buffer; + *local_addr = nc->addr_buffer + nc->remote_addr_len; + } + + return WOLFSSL_SUCCESS; +} + +WOLFSSL_API int wolfSSL_get_endpoints( + WOLFSSL *ssl, + const struct wolfSSL_network_connection **nc, + const void **remote_addr, + const void **local_addr) +{ + *nc = &ssl->buffers.network_connection; + return wolfSSL_get_endpoints_1(*nc, ssl->buffers.network_connection_addr_buffer_dynamic, remote_addr, local_addr); +} + +WOLFSSL_API int wolfSSL_get_endpoints_layer2( + WOLFSSL *ssl, + const struct wolfSSL_network_connection **nc, + const void **remote_addr, + const void **local_addr) +{ + *nc = &ssl->buffers.network_connection_layer2; + return wolfSSL_get_endpoints_1(*nc, ssl->buffers.network_connection_layer2_addr_buffer_dynamic, remote_addr, local_addr); +} + +static WC_INLINE int wolfSSL_copy_endpoints_1( + struct wolfSSL_network_connection *nc_src, + byte *nc_addr_buffer_dynamic, + struct wolfSSL_network_connection *nc_dst, + size_t nc_dst_size, + const void **remote_addr, + const void **local_addr) +{ + size_t nc_bufsiz; + + if ((nc_dst == NULL) || (remote_addr == NULL) || (local_addr == NULL)) + return BAD_FUNC_ARG; + if (nc_src->remote_addr_len == 0) + return INCOMPLETE_DATA; + + nc_bufsiz = WOLFSSL_NETWORK_CONNECTION_BUFSIZ(nc_src->remote_addr_len, nc_src->local_addr_len); + if (nc_dst_size < nc_bufsiz) + return BUFFER_E; + XMEMCPY(nc_dst, nc_src, ((unsigned int)(unsigned long int)(&((struct wolfSSL_network_connection *)0)->addr_buffer[0]))); + if (WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(*nc_src)) + XMEMCPY(nc_dst->addr_buffer, nc_addr_buffer_dynamic, nc_src->remote_addr_len + nc_src->local_addr_len); + else + XMEMCPY(nc_dst->addr_buffer, nc_src->addr_buffer, nc_src->remote_addr_len + nc_src->local_addr_len); + *remote_addr = nc_dst->addr_buffer; + *local_addr = nc_dst->addr_buffer + nc_dst->remote_addr_len; + + return WOLFSSL_SUCCESS; +} + +WOLFSSL_API int wolfSSL_copy_endpoints( + WOLFSSL *ssl, + struct wolfSSL_network_connection *nc, + size_t nc_size, + const void **remote_addr, + const void **local_addr) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return wolfSSL_copy_endpoints_1(&ssl->buffers.network_connection, ssl->buffers.network_connection_addr_buffer_dynamic, nc, nc_size, remote_addr, local_addr); +} + +WOLFSSL_API int wolfSSL_copy_endpoints_layer2( + WOLFSSL *ssl, + struct wolfSSL_network_connection *nc, + size_t nc_size, + const void **remote_addr, + const void **local_addr) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return wolfSSL_copy_endpoints_1(&ssl->buffers.network_connection_layer2, ssl->buffers.network_connection_layer2_addr_buffer_dynamic, nc, nc_size, remote_addr, local_addr); +} + +WOLFSSL_API int wolfSSL_CTX_set_AcceptFilter(WOLFSSL_CTX *ctx, NetworkFilterCallback_t AcceptFilter, void *AcceptFilter_arg) { + ctx->AcceptFilter = AcceptFilter; + ctx->AcceptFilter_arg = AcceptFilter_arg; + return WOLFSSL_SUCCESS; +} + +WOLFSSL_API int wolfSSL_set_AcceptFilter(WOLFSSL *ssl, NetworkFilterCallback_t AcceptFilter, void *AcceptFilter_arg) { + ssl->AcceptFilter = AcceptFilter; + ssl->AcceptFilter_arg = AcceptFilter_arg; + return WOLFSSL_SUCCESS; +} + +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ + #ifndef WOLFSSL_LEANPSK int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) { @@ -12898,6 +13126,25 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */ +#ifdef WOLFSSL_NETWORK_INTROSPECTION + if (ssl->AcceptFilter && (ssl->buffers.network_connection.remote_addr_len > 0)) { + wolfSSL_netfilter_decision_t res; + if ((ssl->AcceptFilter(ssl, &ssl->buffers.network_connection, ssl->AcceptFilter_arg, &res) == WOLFSSL_SUCCESS) && + (res == WOLFSSL_NETFILTER_REJECT)) { + WOLFSSL_ERROR(ssl->error = SOCKET_ERROR_E); + return WOLFSSL_FATAL_ERROR; + } + } + if (ssl->AcceptFilter && (ssl->buffers.network_connection_layer2.remote_addr_len > 0)) { + wolfSSL_netfilter_decision_t res; + if ((ssl->AcceptFilter(ssl, &ssl->buffers.network_connection_layer2, ssl->AcceptFilter_arg, &res) == WOLFSSL_SUCCESS) && + (res == WOLFSSL_NETFILTER_REJECT)) { + WOLFSSL_ERROR(ssl->error = SOCKET_ERROR_E); + return WOLFSSL_FATAL_ERROR; + } + } +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ + #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13) return wolfSSL_accept_TLSv13(ssl); #else diff --git a/src/tls13.c b/src/tls13.c index 1097cf385..cbc891458 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8356,6 +8356,25 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } +#ifdef WOLFSSL_NETWORK_INTROSPECTION + if (ssl->AcceptFilter && (ssl->buffers.network_connection.remote_addr_len > 0)) { + wolfSSL_netfilter_decision_t res; + if ((ssl->AcceptFilter(ssl, &ssl->buffers.network_connection, ssl->AcceptFilter_arg, &res) == WOLFSSL_SUCCESS) && + (res == WOLFSSL_NETFILTER_REJECT)) { + WOLFSSL_ERROR(ssl->error = SOCKET_ERROR_E); + return WOLFSSL_FATAL_ERROR; + } + } + if (ssl->AcceptFilter && (ssl->buffers.network_connection_layer2.remote_addr_len > 0)) { + wolfSSL_netfilter_decision_t res; + if ((ssl->AcceptFilter(ssl, &ssl->buffers.network_connection_layer2, ssl->AcceptFilter_arg, &res) == WOLFSSL_SUCCESS) && + (res == WOLFSSL_NETFILTER_REJECT)) { + WOLFSSL_ERROR(ssl->error = SOCKET_ERROR_E); + return WOLFSSL_FATAL_ERROR; + } + } +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ + #ifndef NO_CERTS /* allow no private key if using PK callbacks and CB is set */ if (!havePSK) { diff --git a/tests/api.c b/tests/api.c index 8af9d0bb1..60bc08a53 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2777,7 +2777,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #endif /* do it here to detect failure */ - tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1); + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0); CloseSocket(sockfd); wolfSSL_CTX_set_verify(ctx, @@ -3072,7 +3072,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args) cbf->ssl_ready(ssl); } /* do it here to detect failure */ - tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1); + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0); CloseSocket(sockfd); if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) { /*err_sys("SSL_set_fd failed");*/ @@ -3641,14 +3641,14 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) socklen_t cliLen; cliLen = sizeof(cliAddr); - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0, 0, 0); idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK, (struct sockaddr*)&cliAddr, &cliLen); AssertIntGT(idx, 0); wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen); } else { - tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1); + tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0); CloseSocket(sfd); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d3ca6c584..6222c58e3 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2860,6 +2860,10 @@ struct WOLFSSL_CTX { CallbackInfoState* CBIS; /* used to get info about SSL state */ WOLFSSL_X509_VERIFY_PARAM* param; /* verification parameters*/ #endif +#ifdef WOLFSSL_NETWORK_INTROSPECTION + NetworkFilterCallback_t AcceptFilter; + void *AcceptFilter_arg; +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ CallbackIORecv CBIORecv; CallbackIOSend CBIOSend; #ifdef WOLFSSL_DTLS @@ -3445,6 +3449,23 @@ typedef struct Buffers { #ifdef WOLFSSL_SEND_HRR_COOKIE buffer tls13CookieSecret; /* HRR cookie secret */ #endif +#ifdef WOLFSSL_NETWORK_INTROSPECTION + struct { + struct wolfSSL_network_connection network_connection; + union { + byte network_connection_addr_buffer_static[WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES]; + byte *network_connection_addr_buffer_dynamic; + }; + }; + struct { + struct wolfSSL_network_connection network_connection_layer2; + union { + byte network_connection_layer2_addr_buffer_static[WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES]; + byte *network_connection_layer2_addr_buffer_dynamic; + }; + }; + #define WOLFSSL_NETWORK_INTROSPECTION_ADDR_BUFFER_IS_DYNAMIC(x) ((x).remote_addr_len + (x).local_addr_len > WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES) +#endif #ifdef WOLFSSL_DTLS WOLFSSL_DTLS_CTX dtlsCtx; /* DTLS connection context */ #ifndef NO_WOLFSSL_SERVER @@ -4075,6 +4096,10 @@ struct WOLFSSL { #ifdef OPENSSL_EXTRA byte cbioFlag; /* WOLFSSL_CBIO_RECV/SEND: CBIORecv/Send is set */ #endif +#ifdef WOLFSSL_NETWORK_INTROSPECTION + NetworkFilterCallback_t AcceptFilter; + void *AcceptFilter_arg; +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ CallbackIORecv CBIORecv; CallbackIOSend CBIOSend; #ifdef WOLFSSL_STATIC_MEMORY diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ff31dd662..56d6954f7 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1141,6 +1141,84 @@ WOLFSSL_API int wolfSSL_export_keying_material(WOLFSSL *ssl, int use_context); #endif /* HAVE_KEYING_MATERIAL */ +#ifdef WOLFSSL_NETWORK_INTROSPECTION + +#ifndef WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES +#define WOLFSSL_NETWORK_INTROSPECTION_STATIC_ADDR_BYTES 32 /* enough for 2 IPv6 addresses. */ +#endif + +struct wolfSSL_network_connection { + word16 family; + word16 proto; + word16 remote_port; + word16 local_port; + word16 remote_addr_len; + word16 local_addr_len; + byte interface; + byte addr_buffer[0]; +}; + +#define WOLFSSL_NETWORK_CONNECTION_BUFSIZ(remote_addr_len, local_addr_len) \ + ((unsigned int)(unsigned long int)(&((struct wolfSSL_network_connection *)0)->addr_buffer[0]) + \ + (remote_addr_len) + (local_addr_len)); + +WOLFSSL_API int wolfSSL_set_endpoints( + WOLFSSL *ssl, + unsigned int interface_id, + unsigned int family, + unsigned int proto, + unsigned int addr_len, + const byte *remote_addr, + const byte *local_addr, + unsigned int remote_port, + unsigned int local_port); + +WOLFSSL_API int wolfSSL_get_endpoints( + WOLFSSL *ssl, + const struct wolfSSL_network_connection **nc, + const void **remote_addr, + const void **local_addr); + +WOLFSSL_API int wolfSSL_copy_endpoints( + WOLFSSL *ssl, + struct wolfSSL_network_connection *nc, + size_t nc_size, + const void **remote_addr, + const void **local_addr); + +WOLFSSL_API int wolfSSL_set_endpoints_layer2( + WOLFSSL *ssl, + unsigned int interface_id, + unsigned int family, + unsigned int addr_len, + const byte *remote_addr, + const byte *local_addr); + +WOLFSSL_API int wolfSSL_get_endpoints_layer2( + WOLFSSL *ssl, + const struct wolfSSL_network_connection **nc, + const void **remote_addr, + const void **local_addr); + +WOLFSSL_API int wolfSSL_copy_endpoints_layer2( + WOLFSSL *ssl, + struct wolfSSL_network_connection *nc, + size_t nc_size, + const void **remote_addr, + const void **local_addr); + +typedef enum { + WOLFSSL_NETFILTER_PASS = 0, + WOLFSSL_NETFILTER_ACCEPT = 1, + WOLFSSL_NETFILTER_REJECT = 2 +} wolfSSL_netfilter_decision_t; + +typedef int (*NetworkFilterCallback_t)(WOLFSSL *ssl, struct wolfSSL_network_connection *nc, void *ctx, wolfSSL_netfilter_decision_t *decision); +WOLFSSL_API int wolfSSL_CTX_set_AcceptFilter(WOLFSSL_CTX *ctx, NetworkFilterCallback_t AcceptFilter, void *AcceptFilter_arg); +WOLFSSL_API int wolfSSL_set_AcceptFilter(WOLFSSL *ssl, NetworkFilterCallback_t AcceptFilter, void *AcceptFilter_arg); + +#endif /* WOLFSSL_NETWORK_INTROSPECTION */ + /* Nonblocking DTLS helper functions */ WOLFSSL_API void wolfSSL_dtls_set_using_nonblock(WOLFSSL*, int); WOLFSSL_API int wolfSSL_dtls_get_using_nonblock(WOLFSSL*); diff --git a/wolfssl/test.h b/wolfssl/test.h index a85871923..1d4cb9cf2 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1297,10 +1297,9 @@ static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, func_args* args, word16 port, int useAnyAddr, - int udp, int sctp, int ready_file, int do_listen) + int udp, int sctp, int ready_file, int do_listen, + SOCKADDR_IN_T *client_addr, socklen_t *client_len) { - SOCKADDR_IN_T client_addr; - socklen_t client_len = sizeof(client_addr); tcp_ready* ready = NULL; (void) ready; /* Account for case when "ready" is not used */ @@ -1357,8 +1356,8 @@ static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, } } - *clientfd = accept(*sockfd, (struct sockaddr*)&client_addr, - (ACCEPT_THIRD_T)&client_len); + *clientfd = accept(*sockfd, (struct sockaddr*)client_addr, + (ACCEPT_THIRD_T)client_len); if(WOLFSSL_SOCKET_IS_INVALID(*clientfd)) { err_sys_with_errno("tcp accept failed"); }