Merge pull request from douzzer/wolfsentry-client

outbound connection filtering and wolfSentry integration
This commit is contained in:
David Garske 2021-06-22 07:27:18 -07:00 committed by GitHub
commit 67b87a8883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 820 additions and 267 deletions

@ -30,6 +30,13 @@
#include <wolfssl/ssl.h>
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
#include <wolfsentry/wolfsentry.h>
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
static const char *wolfsentry_config_path = NULL;
#endif
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
#include <stdio.h>
#include <string.h>
@ -967,7 +974,7 @@ static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
/* 4. add the same message into Japanese section */
/* (will be translated later) */
/* 5. add printf() into suitable position of Usage() */
static const char* client_usage_msg[][67] = {
static const char* client_usage_msg[][68] = {
/* English */
{
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
@ -989,7 +996,8 @@ static const char* client_usage_msg[][67] = {
"INFINITE\n", /* 2 */
#endif
"-? <num> Help, print this usage\n"
" 0: English, 1: Japanese\n", /* 3 */
" 0: English, 1: Japanese\n"
"--help Help, in English\n", /* 3 */
"-h <host> Host to connect to, default", /* 4 */
"-p <num> Port to connect on, not 0, default", /* 5 */
@ -1147,6 +1155,11 @@ static const char* client_usage_msg[][67] = {
" e.g symbolic link to the file at certs folder\n"
" ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n",
/* 67 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
"--wolfsentry-config <file> Path for JSON wolfSentry config\n",
/* 68 */
#endif
NULL,
},
@ -1171,7 +1184,8 @@ static const char* client_usage_msg[][67] = {
"無限\n", /* 2 */
#endif
"-? <num> ヘルプ, 使い方を表示\n"
" 0: 英語、 1: 日本語\n", /* 3 */
" 0: 英語、 1: 日本語\n"
"--ヘルプ 使い方を表示, 日本語で\n", /* 3 */
"-h <host> 接続先ホスト, 既定値", /* 4 */
"-p <num> 接続先ポート, 0は無効, 既定値", /* 5 */
@ -1332,6 +1346,11 @@ static const char* client_usage_msg[][67] = {
" 以下の例ではca-cert.pemにシンボリックリンクを設定します\n"
" ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n",
/* 67 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
"--wolfsentry-config <file> wolfSentry コンフィグファイル\n",
/* 68 */
#endif
NULL,
},
@ -1446,6 +1465,7 @@ static void Usage(void)
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
printf("%s", msg[++msgid]); /* -W */
printf("%s", msg[++msgid]); /* note for -W */
#endif
#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
printf("%s", msg[++msgid]); /* -U */
@ -1510,6 +1530,10 @@ static void Usage(void)
!defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
printf("%s", msg[++msgid]); /* -9 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
printf("%s", msg[++msgid]); /* --wolfsentry-config */
#endif
}
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
@ -1520,6 +1544,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
wolfsentry_errcode_t wolfsentry_ret;
#endif
WOLFSSL* sslResume = 0;
WOLFSSL_SESSION* session = 0;
byte* flatSession = NULL;
@ -1537,6 +1565,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
*/
#ifndef WOLFSSL_VXWORKS
int ch;
static const struct mygetopt_long_config long_options[] = {
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
{ "wolfsentry-config", 1, 256 },
#endif
{ "help", 0, 257 },
{ "ヘルプ", 0, 258 },
{ 0, 0, 0 }
};
#endif
int version = CLIENT_INVALID_VERSION;
int minVersion = CLIENT_INVALID_VERSION;
@ -1736,11 +1773,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifndef WOLFSSL_VXWORKS
/* Not used: All used */
while ((ch = mygetopt(argc, argv, "?:"
while ((ch = mygetopt_long(argc, argv, "?:"
"ab:c:defgh:i;jk:l:mnop:q:rstu;v:wxyz"
"A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:"
"01:23:4567:89"
"@#")) != -1) {
"@#", long_options, 0)) != -1) {
switch (ch) {
case '?' :
if(myoptarg!=NULL) {
@ -1752,6 +1789,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
Usage();
XEXIT_T(EXIT_SUCCESS);
case 257 :
lng_index = 0;
Usage();
XEXIT_T(EXIT_SUCCESS);
case 258 :
lng_index = 1;
Usage();
XEXIT_T(EXIT_SUCCESS);
case 'g' :
sendGET = 1;
break;
@ -2231,8 +2278,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
!defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
useCertFolder = 1;
break;
#endif
break;
case '@' :
{
#ifdef HAVE_WC_INTROSPECTION
@ -2267,6 +2314,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif
}
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
case 256:
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
wolfsentry_config_path = myoptarg;
#endif
break;
#endif
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -2509,6 +2564,22 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
#endif
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path,
WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT) < 0) {
err_sys("unable to initialize wolfSentry");
}
if (wolfSSL_CTX_set_ConnectFilter(
ctx,
(NetworkFilterCallback_t)wolfSentry_NetworkFilterCallback,
wolfsentry) < 0) {
err_sys("unable to install wolfSentry_NetworkFilterCallback");
}
#endif
if (cipherList && !useDefCipherList) {
if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != WOLFSSL_SUCCESS) {
wolfSSL_CTX_free(ctx); ctx = NULL;
@ -3854,6 +3925,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
exit:
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
wolfsentry_ret = wolfsentry_shutdown(&wolfsentry);
if (wolfsentry_ret < 0) {
fprintf(stderr,
"wolfsentry_shutdown() returned " WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
}
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
wolfAsync_DevClose(&devId);
#endif

@ -5,8 +5,9 @@ if BUILD_EXAMPLE_CLIENTS
noinst_PROGRAMS += examples/client/client
noinst_HEADERS += examples/client/client.h
examples_client_client_SOURCES = examples/client/client.c
examples_client_client_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD)
examples_client_client_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD) $(WOLFSENTRY_LIB)
examples_client_client_DEPENDENCIES = src/libwolfssl.la
examples_client_client_CFLAGS = $(WOLFSENTRY_INCLUDE) $(AM_CFLAGS)
endif
EXTRA_DIST += examples/client/client.sln
EXTRA_DIST += examples/client/client-ntru.vcproj

@ -36,8 +36,11 @@
#endif
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
# include <wolfsentry/wolfsentry.h>
#include <wolfsentry/wolfsentry.h>
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
static const char *wolfsentry_config_path = NULL;
#endif
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
#include <stdio.h>
@ -279,137 +282,6 @@ static int TestEmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
}
#endif /* WOLFSSL_DTLS && USE_WOLFSSL_IO */
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
struct wolfsentry_data {
struct wolfsentry_sockaddr remote;
byte remote_addrbuf[16];
struct wolfsentry_sockaddr local;
byte local_addrbuf[16];
wolfsentry_route_flags_t flags;
void *heap;
int alloctype;
};
static void free_wolfsentry_data(struct wolfsentry_data *data) {
XFREE(data, data->heap, data->alloctype);
}
static int wolfsentry_data_index = -1;
static int wolfsentry_store_endpoints(
WOLFSSL *ssl,
SOCKADDR_IN_T *remote,
SOCKADDR_IN_T *local,
int proto,
wolfsentry_route_flags_t flags)
{
struct wolfsentry_data *data = (struct wolfsentry_data *)XMALLOC(
sizeof *data, NULL, DYNAMIC_TYPE_SOCKADDR);
if (data == NULL)
return WOLFSSL_FAILURE;
data->heap = NULL;
data->alloctype = DYNAMIC_TYPE_SOCKADDR;
#ifdef TEST_IPV6
if ((sizeof data->remote_addrbuf < sizeof remote->sin6_addr) ||
(sizeof data->local_addrbuf < sizeof local->sin6_addr))
return WOLFSSL_FAILURE;
data->remote.sa_family = data->local.sa_family = remote->sin6_family;
data->remote.sa_port = ntohs(remote->sin6_port);
data->local.sa_port = ntohs(local->sin6_port);
data->remote.addr_len = sizeof remote->sin6_addr * BITS_PER_BYTE;
XMEMCPY(data->remote.addr, &remote->sin6_addr, sizeof remote->sin6_addr);
data->local.addr_len = sizeof local->sin6_addr * BITS_PER_BYTE;
XMEMCPY(data->local.addr, &local->sin6_addr, sizeof local->sin6_addr);
#else
if ((sizeof data->remote_addrbuf < sizeof remote->sin_addr) ||
(sizeof data->local_addrbuf < sizeof local->sin_addr))
return WOLFSSL_FAILURE;
data->remote.sa_family = data->local.sa_family = remote->sin_family;
data->remote.sa_port = ntohs(remote->sin_port);
data->local.sa_port = ntohs(local->sin_port);
data->remote.addr_len = sizeof remote->sin_addr * BITS_PER_BYTE;
XMEMCPY(data->remote.addr, &remote->sin_addr, sizeof remote->sin_addr);
data->local.addr_len = sizeof local->sin_addr * BITS_PER_BYTE;
XMEMCPY(data->local.addr, &local->sin_addr, sizeof local->sin_addr);
#endif
data->remote.sa_proto = data->local.sa_proto = proto;
data->remote.interface = data->local.interface = 0;
data->flags = flags;
if (wolfSSL_set_ex_data_with_cleanup(
ssl, wolfsentry_data_index, data,
(wolfSSL_ex_data_cleanup_routine_t)free_wolfsentry_data) !=
WOLFSSL_SUCCESS) {
free_wolfsentry_data(data);
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
static int wolfSentry_NetworkFilterCallback(
WOLFSSL *ssl,
struct wolfsentry_context *wolfsentry,
wolfSSL_netfilter_decision_t *decision)
{
struct wolfsentry_data *data;
char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN];
wolfsentry_errcode_t ret;
wolfsentry_action_res_t action_results;
if ((data = wolfSSL_get_ex_data(ssl, wolfsentry_data_index)) == NULL)
return WOLFSSL_FAILURE;
ret = wolfsentry_route_event_dispatch(
wolfsentry,
&data->remote,
&data->local,
data->flags,
NULL /* event_label */,
0 /* event_label_len */,
NULL /* caller_context */,
NULL /* id */,
NULL /* inexact_matches */,
&action_results);
if (ret >= 0) {
if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_REJECT))
*decision = WOLFSSL_NETFILTER_REJECT;
else if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_ACCEPT))
*decision = WOLFSSL_NETFILTER_ACCEPT;
else
*decision = WOLFSSL_NETFILTER_PASS;
} else {
printf("wolfsentry_route_event_dispatch error "
WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret));
*decision = WOLFSSL_NETFILTER_PASS;
}
printf("wolfSentry got network filter callback: family=%d proto=%d rport=%d"
"lport=%d raddr=%s laddr=%s interface=%d; decision=%d (%s)\n",
data->remote.sa_family,
data->remote.sa_proto,
data->remote.sa_port,
data->local.sa_port,
inet_ntop(data->remote.sa_family, data->remote.addr, inet_ntop_buf,
sizeof inet_ntop_buf),
inet_ntop(data->local.sa_family, data->local.addr, inet_ntop_buf2,
sizeof inet_ntop_buf2),
data->remote.interface,
*decision,
*decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" :
*decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" :
*decision == WOLFSSL_NETFILTER_PASS ? "PASS" :
"???");
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
static int NonBlockingSSL_Accept(SSL* ssl)
{
#ifndef WOLFSSL_CALLBACKS
@ -804,12 +676,13 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
/* 4. add the same message into Japanese section */
/* (will be translated later) */
/* 5. add printf() into suitable position of Usage() */
static const char* server_usage_msg[][57] = {
static const char* server_usage_msg[][58] = {
/* English */
{
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
"-? <num> Help, print this usage\n"
" 0: English, 1: Japanese\n", /* 1 */
" 0: English, 1: Japanese\n"
"--help Help, in English\n", /* 1 */
"-p <num> Port to listen on, not 0, default", /* 2 */
#ifndef WOLFSSL_TLS13
"-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default", /* 3 */
@ -937,6 +810,10 @@ static const char* server_usage_msg[][57] = {
" e.g symbolic link to the file at certs folder\n"
" ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n",
/* 57 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
"--wolfsentry-config <file> Path for JSON wolfSentry config\n",
/* 58 */
#endif
NULL,
},
@ -946,7 +823,8 @@ static const char* server_usage_msg[][57] = {
" 注意 : 全てのファイルは"
" wolfSSL ホーム・ディレクトリからの相対です。\n", /* 0 */
"-? <num> ヘルプ, 使い方を表示\n"
" 0: 英語、 1: 日本語\n", /* 1 */
" 0: 英語、 1: 日本語\n"
"--ヘルプ 使い方を表示, 日本語で\n", /* 1 */
"-p <num> 接続先ポート, 0は無効, 既定値", /* 2 */
#ifndef WOLFSSL_TLS13
"-v <num> SSL バージョン [0-3], SSLv3(0) - TLS1.2(3)),"
@ -1080,6 +958,10 @@ static const char* server_usage_msg[][57] = {
" 以下の例ではca-cert.pemにシンボリックリンクを設定します\n"
" ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n",
/* 57 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
"--wolfsentry-config <file> wolfSentry コンフィグファイル\n",
/* 58 */
#endif
NULL,
},
@ -1217,6 +1099,10 @@ static void Usage(void)
!defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
printf("%s", msg[++msgId]); /* -9 */
#endif
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
printf("%s", msg[++msgId]); /* --wolfsentry-config */
#endif
}
THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
@ -1230,7 +1116,6 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
SSL_CTX* ctx = 0;
SSL* ssl = 0;
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
struct wolfsentry_context *wolfsentry = NULL;
wolfsentry_errcode_t wolfsentry_ret;
#endif
@ -1238,6 +1123,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
char input[SRV_READ_SZ];
#ifndef WOLFSSL_VXWORKS
int ch;
static const struct mygetopt_long_config long_options[] = {
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSENTRY_NO_JSON)
{ "wolfsentry-config", 1, 256 },
#endif
{ "help", 0, 257 },
{ "ヘルプ", 0, 258 },
{ 0, 0, 0 }
};
#endif
int version = SERVER_DEFAULT_VERSION;
#ifndef WOLFSSL_NO_CLIENT_AUTH
@ -1450,12 +1344,12 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
/* Reinitialize the global myVerifyAction. */
myVerifyAction = VERIFY_OVERRIDE_ERROR;
/* Not Used: h, z, W, X, 7, 9 */
while ((ch = mygetopt(argc, argv, "?:"
/* Not Used: h, z, W, X, 7 */
while ((ch = mygetopt_long(argc, argv, "?:"
"abc:defgijk:l:mnop:q:rstu;v:wxy"
"A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:"
"01:23:4:5689"
"@#")) != -1) {
"@#", long_options, 0)) != -1) {
switch (ch) {
case '?' :
if(myoptarg!=NULL) {
@ -1467,6 +1361,16 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
Usage();
XEXIT_T(EXIT_SUCCESS);
case 257 :
lng_index = 0;
Usage();
XEXIT_T(EXIT_SUCCESS);
case 258 :
lng_index = 1;
Usage();
XEXIT_T(EXIT_SUCCESS);
case 'x' :
runWithErrors = 1;
break;
@ -1928,6 +1832,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif
}
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
case 256:
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
wolfsentry_config_path = myoptarg;
#endif
break;
#endif
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -2069,86 +1981,18 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
err_sys_ex(catastrophic, "unable to get ctx");
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
wolfsentry_ret = wolfsentry_init(NULL /* hpi */, NULL /* default config */,
&wolfsentry);
if (wolfsentry_ret < 0) {
fprintf(stderr, "wolfsentry_init() returned " WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
err_sys_ex(catastrophic, "unable to initialize wolfSentry");
if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path,
WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) {
err_sys("unable to initialize wolfSentry");
}
if (wolfsentry_data_index < 0)
wolfsentry_data_index = wolfSSL_get_ex_new_index(0, NULL, NULL, NULL,
NULL);
{
struct wolfsentry_route_table *table;
if ((wolfsentry_ret = wolfsentry_route_get_table_static(wolfsentry,
&table)) < 0)
fprintf(stderr, "wolfsentry_route_get_table_static() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
if (wolfsentry_ret >= 0) {
if ((wolfsentry_ret = wolfsentry_route_table_default_policy_set(
wolfsentry, table,
WOLFSENTRY_ACTION_RES_REJECT|WOLFSENTRY_ACTION_RES_STOP))
< 0)
fprintf(stderr,
"wolfsentry_route_table_default_policy_set() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
}
if (wolfsentry_ret >= 0) {
struct {
struct wolfsentry_sockaddr sa;
byte buf[16];
} remote, local;
wolfsentry_ent_id_t id;
wolfsentry_action_res_t action_results;
memset(&remote, 0, sizeof remote);
memset(&local, 0, sizeof local);
#ifdef TEST_IPV6
remote.sa.sa_family = local.sa.sa_family = AF_INET6;
remote.sa.addr_len = 128;
memcpy(remote.sa.addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", 16);
#else
remote.sa.sa_family = local.sa.sa_family = AF_INET;
remote.sa.addr_len = 32;
memcpy(remote.sa.addr, "\177\000\000\001", 4);
#endif
if ((wolfsentry_ret = wolfsentry_route_insert_static
(wolfsentry, NULL /* caller_context */, &remote.sa, &local.sa,
WOLFSENTRY_ROUTE_FLAG_GREENLISTED |
WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN |
WOLFSENTRY_ROUTE_FLAG_TRIGGER_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD|
WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_PROTO_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_PORT_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD,
0 /* event_label_len */, 0 /* event_label */, &id,
&action_results)) < 0)
fprintf(stderr, "wolfsentry_route_insert_static() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
}
if (wolfsentry_ret < 0)
err_sys_ex(catastrophic, "unable to configure route table");
}
if (wolfSSL_CTX_set_AcceptFilter(
ctx,
(NetworkFilterCallback_t)wolfSentry_NetworkFilterCallback,
wolfsentry) < 0)
wolfsentry) < 0) {
err_sys_ex(catastrophic,
"unable to install wolfSentry_NetworkFilterCallback");
}
#endif
if (simulateWantWrite)
@ -2807,7 +2651,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
if (wolfsentry_store_endpoints(
ssl, &client_addr, &local_addr,
dtlsUDP ? IPPROTO_UDP : IPPROTO_TCP,
WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) != WOLFSSL_SUCCESS)
WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN, NULL) != WOLFSSL_SUCCESS)
err_sys_ex(catastrophic,
"error in wolfsentry_store_endpoints()");
}

@ -5634,6 +5634,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
ssl->AcceptFilter = ctx->AcceptFilter;
ssl->AcceptFilter_arg = ctx->AcceptFilter_arg;
ssl->ConnectFilter = ctx->ConnectFilter;
ssl->ConnectFilter_arg = ctx->ConnectFilter_arg;
#endif
ssl->CBIORecv = ctx->CBIORecv;

120
src/ssl.c

@ -1025,7 +1025,7 @@ int wolfSSL_CTX_set_AcceptFilter(
return BAD_FUNC_ARG;
ctx->AcceptFilter = AcceptFilter;
ctx->AcceptFilter_arg = AcceptFilter_arg;
return WOLFSSL_SUCCESS;
return 0;
}
int wolfSSL_set_AcceptFilter(
@ -1037,7 +1037,31 @@ int wolfSSL_set_AcceptFilter(
return BAD_FUNC_ARG;
ssl->AcceptFilter = AcceptFilter;
ssl->AcceptFilter_arg = AcceptFilter_arg;
return WOLFSSL_SUCCESS;
return 0;
}
int wolfSSL_CTX_set_ConnectFilter(
WOLFSSL_CTX *ctx,
NetworkFilterCallback_t ConnectFilter,
void *ConnectFilter_arg)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
ctx->ConnectFilter = ConnectFilter;
ctx->ConnectFilter_arg = ConnectFilter_arg;
return 0;
}
int wolfSSL_set_ConnectFilter(
WOLFSSL *ssl,
NetworkFilterCallback_t ConnectFilter,
void *ConnectFilter_arg)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
ssl->ConnectFilter = ConnectFilter;
ssl->ConnectFilter_arg = ConnectFilter_arg;
return 0;
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
@ -12581,6 +12605,18 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return wolfSSL_connect_TLSv13(ssl);
#endif
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
if (ssl->ConnectFilter) {
wolfSSL_netfilter_decision_t res;
if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
WOLFSSL_SUCCESS) &&
(res == WOLFSSL_NETFILTER_REJECT)) {
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
return WOLFSSL_FATAL_ERROR;
}
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
if (ssl->options.side != WOLFSSL_CLIENT_END) {
WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
return WOLFSSL_FATAL_ERROR;
@ -12942,6 +12978,15 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
}
#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
return wolfSSL_accept_TLSv13(ssl);
#else
#ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3)
return wolfSSL_accept_TLSv13(ssl);
#endif
WOLFSSL_ENTER("SSL_accept()");
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
if (ssl->AcceptFilter) {
wolfSSL_netfilter_decision_t res;
@ -12954,15 +12999,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
return wolfSSL_accept_TLSv13(ssl);
#else
#ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3)
return wolfSSL_accept_TLSv13(ssl);
#endif
WOLFSSL_ENTER("SSL_accept()");
#ifdef HAVE_ERRNO_H
errno = 0;
#endif
@ -43660,10 +43696,7 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
#endif /* OPENSSL_EXTRA */
#if ((defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && defined(HAVE_EX_DATA) || \
defined(FORTRESS) || defined(WOLFSSL_WPAS_SMALL) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY))
#if defined(HAVE_EX_DATA) || defined(FORTRESS) || defined(WOLFSSL_WPAS_SMALL)
/**
* get_ex_new_index is a helper function for the following
* xx_get_ex_new_index functions:
@ -43713,7 +43746,7 @@ static int get_ex_new_index(int class_index)
}
return index;
}
#endif /* HAVE_EX_DATA || FORTRESS */
#endif /* HAVE_EX_DATA || FORTRESS || WOLFSSL_WPAS_SMALL */
#if defined(HAVE_EX_DATA) || defined(FORTRESS) || defined(WOLFSSL_WPAS_SMALL)
void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
@ -47442,8 +47475,9 @@ void wolfSSL_OPENSSL_config(char *config_name)
#endif /* !NO_WOLFSSL_STUB */
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_STUNNEL*/
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
|| defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
#if defined(HAVE_EX_DATA) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
|| defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) \
|| defined(HAVE_LIGHTY))
int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c)
{
@ -48547,6 +48581,7 @@ int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings)
return (int)strings->num;
return 0;
}
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
@ -54003,6 +54038,30 @@ int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
return ret;
}
/**
* Return DH p, q and g parameters
* @param dh a pointer to WOLFSSL_DH
* @param p a pointer to WOLFSSL_BIGNUM to be obtained from dh
* @param q a pointer to WOLFSSL_BIGNUM to be obtained from dh
* @param q a pointer to WOLFSSL_BIGNUM to be obtained from dh
*/
void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
{
WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
if (dh == NULL)
return;
if (p != NULL)
*p = dh->p;
if (q != NULL)
*q = dh->q;
if (g != NULL)
*g = dh->g;
}
#endif /* OPENSSL_EXTRA */
#if defined(HAVE_EX_DATA) || defined(FORTRESS)
/**
* Issues unique index for the class specified by class_index.
@ -54035,30 +54094,6 @@ int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
}
#endif /* HAVE_EX_DATA || FORTRESS */
/**
* Return DH p, q and g parameters
* @param dh a pointer to WOLFSSL_DH
* @param p a pointer to WOLFSSL_BIGNUM to be obtained from dh
* @param q a pointer to WOLFSSL_BIGNUM to be obtained from dh
* @param q a pointer to WOLFSSL_BIGNUM to be obtained from dh
*/
void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
{
WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
if (dh == NULL)
return;
if (p != NULL)
*p = dh->p;
if (q != NULL)
*q = dh->q;
if (g != NULL)
*g = dh->g;
}
#endif /* OPENSSL_EXTRA */
#ifndef NO_CERTS
/*******************************************************************************
@ -56858,4 +56893,3 @@ int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,
/*******************************************************************************
* END OF CRYPTO-ONLY APIs
******************************************************************************/

@ -8236,6 +8236,18 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
return WOLFSSL_FATAL_ERROR;
}
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
if (ssl->ConnectFilter) {
wolfSSL_netfilter_decision_t res;
if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
WOLFSSL_SUCCESS) &&
(res == WOLFSSL_NETFILTER_REJECT)) {
WOLFSSL_ERROR(ssl->error = SOCKET_FILTERED_E);
return WOLFSSL_FATAL_ERROR;
}
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
if (ssl->buffers.outputBuffer.length > 0
#ifdef WOLFSSL_ASYNC_CRYPT
/* do not send buffered or advance state if last error was an

@ -2877,6 +2877,8 @@ struct WOLFSSL_CTX {
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
NetworkFilterCallback_t AcceptFilter;
void *AcceptFilter_arg;
NetworkFilterCallback_t ConnectFilter;
void *ConnectFilter_arg;
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
CallbackIORecv CBIORecv;
CallbackIOSend CBIOSend;
@ -4109,6 +4111,8 @@ struct WOLFSSL {
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
NetworkFilterCallback_t AcceptFilter;
void *AcceptFilter_arg;
NetworkFilterCallback_t ConnectFilter;
void *ConnectFilter_arg;
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
CallbackIORecv CBIORecv;
CallbackIOSend CBIOSend;

@ -1187,6 +1187,14 @@ WOLFSSL_API int wolfSSL_set_AcceptFilter(
WOLFSSL *ssl,
NetworkFilterCallback_t AcceptFilter,
void *AcceptFilter_arg);
WOLFSSL_API int wolfSSL_CTX_set_ConnectFilter(
WOLFSSL_CTX *ctx,
NetworkFilterCallback_t ConnectFilter,
void *ConnectFilter_arg);
WOLFSSL_API int wolfSSL_set_ConnectFilter(
WOLFSSL *ssl,
NetworkFilterCallback_t ConnectFilter,
void *ConnectFilter_arg);
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
@ -4445,13 +4453,13 @@ WOLFSSL_API int wolfSSL_CONF_CTX_finish(WOLFSSL_CONF_CTX* cctx);
#define WOLFSSL_CONF_TYPE_FILE 0x2
WOLFSSL_API int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value);
#if defined(HAVE_EX_DATA) || defined(FORTRESS)
#endif /* OPENSSL_EXTRA */
#if defined(HAVE_EX_DATA) || defined(FORTRESS) || defined(WOLFSSL_WPAS_SMALL)
WOLFSSL_API int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
WOLFSSL_CRYPTO_EX_new* new_func,
WOLFSSL_CRYPTO_EX_dup* dup_func,
WOLFSSL_CRYPTO_EX_free* free_func);
#endif /* HAVE_EX_DATA || FORTRESS */
#endif /* OPENSSL_EXTRA */
#ifdef __cplusplus
} /* extern "C" */
#endif

@ -16,7 +16,7 @@
#include <errno.h>
#endif
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/mem_track.h>
#include <wolfssl/wolfio.h>
@ -646,6 +646,132 @@ static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
return c;
}
struct mygetopt_long_config {
const char *name;
int takes_arg;
int value;
};
/**
*
* @param argc Number of argv strings
* @param argv Array of string arguments
* @param optstring String containing the supported alphanumeric arguments.
* A ':' following a character means that it requires a
* value in myoptarg to be set. A ';' means that the
* myoptarg is optional. myoptarg is set to "" if not
* present.
* @return Option letter in argument
*/
static WC_INLINE int mygetopt_long(int argc, char** argv, const char* optstring,
const struct mygetopt_long_config *longopts, int *longindex)
{
static char* next = NULL;
int c;
char* cp;
/* Added sanity check because scan-build complains argv[myoptind] access
* results in a null pointer dereference. */
if (argv == NULL) {
myoptarg = NULL;
return -1;
}
if (myoptind == 0)
next = NULL; /* we're starting new/over */
if (next == NULL || *next == '\0') {
if (myoptind == 0)
myoptind++;
if (myoptind >= argc || argv[myoptind] == NULL ||
argv[myoptind][0] != '-' || argv[myoptind][1] == '\0') {
myoptarg = NULL;
if (myoptind < argc)
myoptarg = argv[myoptind];
return -1;
}
if (strcmp(argv[myoptind], "--") == 0) {
myoptind++;
myoptarg = NULL;
if (myoptind < argc)
myoptarg = argv[myoptind];
return -1;
}
if (strncmp(argv[myoptind], "--", 2) == 0) {
const struct mygetopt_long_config *i;
c = -1;
myoptarg = NULL;
for (i = longopts; i->name; ++i) {
if (! strcmp(argv[myoptind] + 2, i->name)) {
c = i->value;
myoptind++;
if (longindex)
*longindex = (int)((i - longopts) / sizeof *i);
if (i->takes_arg) {
if (myoptind < argc) {
myoptarg = argv[myoptind];
myoptind++;
} else
return -1;
}
break;
}
}
return c;
}
next = argv[myoptind];
next++; /* skip - */
myoptind++;
}
c = *next++;
/* The C++ strchr can return a different value */
cp = (char*)strchr(optstring, c);
if (cp == NULL || c == ':' || c == ';')
return '?';
cp++;
if (*cp == ':') {
if (*next != '\0') {
myoptarg = next;
next = NULL;
}
else if (myoptind < argc) {
myoptarg = argv[myoptind];
myoptind++;
}
else
return '?';
}
else if (*cp == ';') {
myoptarg = (char*)"";
if (*next != '\0') {
myoptarg = next;
next = NULL;
}
else if (myoptind < argc) {
/* Check if next argument is not a parameter argument */
if (argv[myoptind] && argv[myoptind][0] != '-') {
myoptarg = argv[myoptind];
myoptind++;
}
}
}
return c;
}
#ifdef WOLFSSL_ENCRYPTED_KEYS
@ -938,7 +1064,7 @@ static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer,
struct zsock_addrinfo hints, *addrInfo;
char portStr[6];
XSNPRINTF(portStr, sizeof(portStr), "%d", port);
memset(&hints, 0, sizeof(hints));
XMEMSET(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
@ -1061,6 +1187,446 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
#endif /* USE_WINDOWS_API */
}
#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && defined(WOLFSENTRY_H)
#include <wolfsentry/wolfsentry_util.h>
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
#include <wolfsentry/wolfsentry_json.h>
#endif
struct wolfsentry_data {
struct wolfsentry_sockaddr remote;
byte remote_addrbuf[16];
struct wolfsentry_sockaddr local;
byte local_addrbuf[16];
wolfsentry_route_flags_t flags;
void *heap;
int alloctype;
};
static void free_wolfsentry_data(struct wolfsentry_data *data) {
XFREE(data, data->heap, data->alloctype);
}
static struct wolfsentry_context *wolfsentry = NULL;
static int wolfsentry_data_index = -1;
static WC_INLINE int wolfsentry_store_endpoints(
WOLFSSL *ssl,
SOCKADDR_IN_T *remote,
SOCKADDR_IN_T *local,
int proto,
wolfsentry_route_flags_t flags,
struct wolfsentry_data **wolfsentry_data_out)
{
struct wolfsentry_data *wolfsentry_data = (struct wolfsentry_data *)XMALLOC(
sizeof *wolfsentry_data, NULL, DYNAMIC_TYPE_SOCKADDR);
if (wolfsentry_data == NULL)
return WOLFSSL_FAILURE;
wolfsentry_data->heap = NULL;
wolfsentry_data->alloctype = DYNAMIC_TYPE_SOCKADDR;
#ifdef TEST_IPV6
if ((sizeof wolfsentry_data->remote_addrbuf < sizeof remote->sin6_addr) ||
(sizeof wolfsentry_data->local_addrbuf < sizeof local->sin6_addr))
return WOLFSSL_FAILURE;
wolfsentry_data->remote.sa_family = wolfsentry_data->local.sa_family = remote->sin6_family;
wolfsentry_data->remote.sa_port = ntohs(remote->sin6_port);
wolfsentry_data->local.sa_port = ntohs(local->sin6_port);
if (WOLFSENTRY_CHECK_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) {
wolfsentry_data->remote.addr_len = 0;
XMEMSET(wolfsentry_data->remote.addr, 0, sizeof remote->sin6_addr);
} else {
wolfsentry_data->remote.addr_len = sizeof remote->sin6_addr * BITS_PER_BYTE;
XMEMCPY(wolfsentry_data->remote.addr, &remote->sin6_addr, sizeof remote->sin6_addr);
}
if (WOLFSENTRY_CHECK_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD)) {
wolfsentry_data->local.addr_len = 0;
XMEMSET(wolfsentry_data->local.addr, 0, sizeof local->sin6_addr);
} else {
wolfsentry_data->local.addr_len = sizeof local->sin6_addr * BITS_PER_BYTE;
XMEMCPY(wolfsentry_data->local.addr, &local->sin6_addr, sizeof local->sin6_addr);
}
#else
if ((sizeof wolfsentry_data->remote_addrbuf < sizeof remote->sin_addr) ||
(sizeof wolfsentry_data->local_addrbuf < sizeof local->sin_addr))
return WOLFSSL_FAILURE;
wolfsentry_data->remote.sa_family = wolfsentry_data->local.sa_family = remote->sin_family;
wolfsentry_data->remote.sa_port = ntohs(remote->sin_port);
wolfsentry_data->local.sa_port = ntohs(local->sin_port);
if (WOLFSENTRY_CHECK_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_ADDR_WILDCARD)) {
wolfsentry_data->remote.addr_len = 0;
XMEMSET(wolfsentry_data->remote.addr, 0, sizeof remote->sin_addr);
} else {
wolfsentry_data->remote.addr_len = sizeof remote->sin_addr * BITS_PER_BYTE;
XMEMCPY(wolfsentry_data->remote.addr, &remote->sin_addr, sizeof remote->sin_addr);
}
if (WOLFSENTRY_CHECK_BITS(flags, WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD)) {
wolfsentry_data->local.addr_len = 0;
XMEMSET(wolfsentry_data->local.addr, 0, sizeof local->sin_addr);
} else {
wolfsentry_data->local.addr_len = sizeof local->sin_addr * BITS_PER_BYTE;
XMEMCPY(wolfsentry_data->local.addr, &local->sin_addr, sizeof local->sin_addr);
}
#endif
wolfsentry_data->remote.sa_proto = wolfsentry_data->local.sa_proto = proto;
wolfsentry_data->remote.interface = wolfsentry_data->local.interface = 0;
wolfsentry_data->flags = flags;
if (wolfSSL_set_ex_data_with_cleanup(
ssl, wolfsentry_data_index, wolfsentry_data,
(wolfSSL_ex_data_cleanup_routine_t)free_wolfsentry_data) !=
WOLFSSL_SUCCESS) {
free_wolfsentry_data(wolfsentry_data);
return WOLFSSL_FAILURE;
}
if (wolfsentry_data_out != NULL)
*wolfsentry_data_out = wolfsentry_data;
return WOLFSSL_SUCCESS;
}
static int wolfSentry_NetworkFilterCallback(
WOLFSSL *ssl,
struct wolfsentry_context *_wolfsentry,
wolfSSL_netfilter_decision_t *decision)
{
struct wolfsentry_data *data;
char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN];
wolfsentry_errcode_t ret;
wolfsentry_action_res_t action_results;
if ((data = wolfSSL_get_ex_data(ssl, wolfsentry_data_index)) == NULL)
return WOLFSSL_FAILURE;
ret = wolfsentry_route_event_dispatch(
_wolfsentry,
&data->remote,
&data->local,
data->flags,
NULL /* event_label */,
0 /* event_label_len */,
NULL /* caller_context */,
NULL /* id */,
NULL /* inexact_matches */,
&action_results);
if (ret >= 0) {
if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_REJECT))
*decision = WOLFSSL_NETFILTER_REJECT;
else if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_ACCEPT))
*decision = WOLFSSL_NETFILTER_ACCEPT;
else
*decision = WOLFSSL_NETFILTER_PASS;
} else {
printf("wolfsentry_route_event_dispatch error "
WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret));
*decision = WOLFSSL_NETFILTER_PASS;
}
printf("wolfSentry got network filter callback: family=%d proto=%d rport=%d"
" lport=%d raddr=%s laddr=%s interface=%d; decision=%d (%s)\n",
data->remote.sa_family,
data->remote.sa_proto,
data->remote.sa_port,
data->local.sa_port,
inet_ntop(data->remote.sa_family, data->remote.addr, inet_ntop_buf,
sizeof inet_ntop_buf),
inet_ntop(data->local.sa_family, data->local.addr, inet_ntop_buf2,
sizeof inet_ntop_buf2),
data->remote.interface,
*decision,
*decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" :
*decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" :
*decision == WOLFSSL_NETFILTER_PASS ? "PASS" :
"???");
return WOLFSSL_SUCCESS;
}
static int wolfsentry_setup(
struct wolfsentry_context **_wolfsentry,
const char *_wolfsentry_config_path,
wolfsentry_route_flags_t route_flags)
{
wolfsentry_errcode_t ret;
ret = wolfsentry_init(NULL /* hpi */, NULL /* default config */,
_wolfsentry);
if (ret < 0) {
fprintf(stderr, "wolfsentry_init() returned " WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
err_sys("unable to initialize wolfSentry");
}
if (wolfsentry_data_index < 0)
wolfsentry_data_index = wolfSSL_get_ex_new_index(0, NULL, NULL, NULL,
NULL);
#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
if (_wolfsentry_config_path != NULL) {
char buf[512], err_buf[512];
struct wolfsentry_json_process_state *jps;
FILE *f = fopen(_wolfsentry_config_path, "r");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n",_wolfsentry_config_path,strerror(errno));
err_sys("unable to open wolfSentry config file");
}
if ((ret = wolfsentry_config_json_init(
*_wolfsentry,
WOLFSENTRY_CONFIG_LOAD_FLAG_NONE,
&jps)) < 0) {
fprintf(stderr, "wolfsentry_config_json_init() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
err_sys("error while initializing wolfSentry config parser");
}
for (;;) {
size_t n = fread(buf, 1, sizeof buf, f);
if ((n < sizeof buf) && ferror(f)) {
fprintf(stderr,"fread(%s): %s\n",_wolfsentry_config_path, strerror(errno));
err_sys("error while reading wolfSentry config file");
}
ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf);
if (ret < 0) {
fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf);
err_sys("error while loading wolfSentry config file");
}
if ((n < sizeof buf) && feof(f))
break;
}
fclose(f);
if ((ret = wolfsentry_config_json_fini(jps, err_buf, sizeof err_buf)) < 0) {
fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf);
err_sys("error while loading wolfSentry config file");
}
} else
#endif /* !NO_FILESYSTEM && !WOLFSENTRY_NO_JSON */
{
struct wolfsentry_route_table *table;
if ((ret = wolfsentry_route_get_table_static(*_wolfsentry,
&table)) < 0)
fprintf(stderr, "wolfsentry_route_get_table_static() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
if (ret < 0)
return ret;
if (WOLFSENTRY_CHECK_BITS(route_flags, WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT)) {
struct {
struct wolfsentry_sockaddr sa;
byte buf[16];
} remote, local;
wolfsentry_ent_id_t id;
wolfsentry_action_res_t action_results;
if ((ret = wolfsentry_route_table_default_policy_set(
*_wolfsentry, table,
WOLFSENTRY_ACTION_RES_ACCEPT))
< 0) {
fprintf(stderr,
"wolfsentry_route_table_default_policy_set() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
return ret;
}
XMEMSET(&remote, 0, sizeof remote);
XMEMSET(&local, 0, sizeof local);
#ifdef TEST_IPV6
remote.sa.sa_family = local.sa.sa_family = AF_INET6;
remote.sa.addr_len = 128;
XMEMCPY(remote.sa.addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", 16);
#else
remote.sa.sa_family = local.sa.sa_family = AF_INET;
remote.sa.addr_len = 32;
XMEMCPY(remote.sa.addr, "\177\000\000\001", 4);
#endif
if ((ret = wolfsentry_route_insert_static
(*_wolfsentry, NULL /* caller_context */, &remote.sa, &local.sa,
route_flags |
WOLFSENTRY_ROUTE_FLAG_GREENLISTED |
WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD|
WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_PROTO_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_PORT_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD,
0 /* event_label_len */, 0 /* event_label */, &id,
&action_results)) < 0) {
fprintf(stderr, "wolfsentry_route_insert_static() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
return ret;
}
} else if (WOLFSENTRY_CHECK_BITS(route_flags, WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN)) {
struct {
struct wolfsentry_sockaddr sa;
byte buf[16];
} remote, local;
wolfsentry_ent_id_t id;
wolfsentry_action_res_t action_results;
if ((ret = wolfsentry_route_table_default_policy_set(
*_wolfsentry, table,
WOLFSENTRY_ACTION_RES_REJECT|WOLFSENTRY_ACTION_RES_STOP))
< 0) {
fprintf(stderr,
"wolfsentry_route_table_default_policy_set() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
return ret;
}
XMEMSET(&remote, 0, sizeof remote);
XMEMSET(&local, 0, sizeof local);
#ifdef TEST_IPV6
remote.sa.sa_family = local.sa.sa_family = AF_INET6;
remote.sa.addr_len = 128;
XMEMCPY(remote.sa.addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", 16);
#else
remote.sa.sa_family = local.sa.sa_family = AF_INET;
remote.sa.addr_len = 32;
XMEMCPY(remote.sa.addr, "\177\000\000\001", 4);
#endif
if ((ret = wolfsentry_route_insert_static
(*_wolfsentry, NULL /* caller_context */, &remote.sa, &local.sa,
route_flags |
WOLFSENTRY_ROUTE_FLAG_GREENLISTED |
WOLFSENTRY_ROUTE_FLAG_PARENT_EVENT_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD|
WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_PROTO_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_REMOTE_PORT_WILDCARD |
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD,
0 /* event_label_len */, 0 /* event_label */, &id,
&action_results)) < 0) {
fprintf(stderr, "wolfsentry_route_insert_static() returned "
WOLFSENTRY_ERROR_FMT "\n",
WOLFSENTRY_ERROR_FMT_ARGS(ret));
return ret;
}
}
}
return 0;
}
static WC_INLINE int tcp_connect_with_wolfSentry(
SOCKET_T* sockfd,
const char* ip,
word16 port,
int udp,
int sctp,
WOLFSSL* ssl,
struct wolfsentry_context *_wolfsentry)
{
SOCKADDR_IN_T remote_addr;
struct wolfsentry_data *wolfsentry_data;
char inet_ntop_buf[INET6_ADDRSTRLEN], inet_ntop_buf2[INET6_ADDRSTRLEN];
wolfsentry_errcode_t ret;
wolfsentry_action_res_t action_results;
wolfSSL_netfilter_decision_t decision;
build_addr(&remote_addr, ip, port, udp, sctp);
{
SOCKADDR_IN_T local_addr;
#ifdef TEST_IPV6
local_addr.sin6_port = 0;
#else
local_addr.sin_port = 0;
#endif
((struct sockaddr *)&local_addr)->sa_family = ((struct sockaddr *)&remote_addr)->sa_family;
if (wolfsentry_store_endpoints(
ssl, &remote_addr, &local_addr,
udp ? IPPROTO_UDP : IPPROTO_TCP,
WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT|
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD|
WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_PORT_WILDCARD, &wolfsentry_data) != WOLFSSL_SUCCESS)
return WOLFSSL_FAILURE;
}
ret = wolfsentry_route_event_dispatch(
_wolfsentry,
&wolfsentry_data->remote,
&wolfsentry_data->local,
wolfsentry_data->flags,
NULL /* event_label */,
0 /* event_label_len */,
NULL /* caller_context */,
NULL /* id */,
NULL /* inexact_matches */,
&action_results);
if (ret < 0) {
printf("wolfsentry_route_event_dispatch error "
WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret));
decision = WOLFSSL_NETFILTER_PASS;
} else {
if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_REJECT))
decision = WOLFSSL_NETFILTER_REJECT;
else if (WOLFSENTRY_CHECK_BITS(action_results, WOLFSENTRY_ACTION_RES_ACCEPT))
decision = WOLFSSL_NETFILTER_ACCEPT;
else
decision = WOLFSSL_NETFILTER_PASS;
}
printf("wolfSentry callin from tcp_connect_with_wolfSentry: family=%d proto=%d rport=%d"
" lport=%d raddr=%s laddr=%s interface=%d; decision=%d (%s)\n",
wolfsentry_data->remote.sa_family,
wolfsentry_data->remote.sa_proto,
wolfsentry_data->remote.sa_port,
wolfsentry_data->local.sa_port,
inet_ntop(wolfsentry_data->remote.sa_family, wolfsentry_data->remote.addr, inet_ntop_buf,
sizeof inet_ntop_buf),
inet_ntop(wolfsentry_data->local.sa_family, wolfsentry_data->local.addr, inet_ntop_buf2,
sizeof inet_ntop_buf2),
wolfsentry_data->remote.interface,
decision,
decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" :
decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" :
decision == WOLFSSL_NETFILTER_PASS ? "PASS" :
"???");
if (decision == WOLFSSL_NETFILTER_REJECT)
return SOCKET_FILTERED_E;
if (udp) {
wolfSSL_dtls_set_peer(ssl, &remote_addr, sizeof(remote_addr));
}
tcp_socket(sockfd, udp, sctp);
if (!udp) {
if (connect(*sockfd, (const struct sockaddr*)&remote_addr, sizeof(remote_addr)) != 0)
err_sys_with_errno("tcp connect failed");
}
return WOLFSSL_SUCCESS;
}
#define tcp_connect(sockfd, ip, port, udp, sctp, ssl) \
tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry)
#else /* !WOLFSSL_WOLFSENTRY_HOOKS */
static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
int udp, int sctp, WOLFSSL* ssl)
{
@ -1077,6 +1643,8 @@ static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
}
}
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
static WC_INLINE void udp_connect(SOCKET_T* sockfd, void* addr, int addrSz)
{