diff --git a/examples/client/client.c b/examples/client/client.c index f9376c278..9ede92d1b 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -30,6 +30,13 @@ #include +#ifdef WOLFSSL_WOLFSENTRY_HOOKS +#include +#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 #include @@ -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 "-? Help, print this usage\n" - " 0: English, 1: Japanese\n", /* 3 */ + " 0: English, 1: Japanese\n" + "--help Help, in English\n", /* 3 */ "-h Host to connect to, default", /* 4 */ "-p 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 Path for JSON wolfSentry config\n", + /* 68 */ #endif NULL, }, @@ -1171,7 +1184,8 @@ static const char* client_usage_msg[][67] = { "無限\n", /* 2 */ #endif "-? ヘルプ, 使い方を表示\n" - " 0: 英語、 1: 日本語\n", /* 3 */ + " 0: 英語、 1: 日本語\n" + "--ヘルプ 使い方を表示, 日本語で\n", /* 3 */ "-h 接続先ホスト, 既定値", /* 4 */ "-p 接続先ポート, 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 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 diff --git a/examples/client/include.am b/examples/client/include.am index 876f6a28e..e44831b82 100644 --- a/examples/client/include.am +++ b/examples/client/include.am @@ -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 diff --git a/examples/server/server.c b/examples/server/server.c index c6fa74f61..a1956f395 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -36,8 +36,11 @@ #endif #ifdef WOLFSSL_WOLFSENTRY_HOOKS -# include +#include +#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 @@ -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 */ "-? Help, print this usage\n" - " 0: English, 1: Japanese\n", /* 1 */ + " 0: English, 1: Japanese\n" + "--help Help, in English\n", /* 1 */ "-p Port to listen on, not 0, default", /* 2 */ #ifndef WOLFSSL_TLS13 "-v 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 Path for JSON wolfSentry config\n", + /* 58 */ #endif NULL, }, @@ -946,7 +823,8 @@ static const char* server_usage_msg[][57] = { " 注意 : 全てのファイルは" " wolfSSL ホーム・ディレクトリからの相対です。\n", /* 0 */ "-? ヘルプ, 使い方を表示\n" - " 0: 英語、 1: 日本語\n", /* 1 */ + " 0: 英語、 1: 日本語\n" + "--ヘルプ 使い方を表示, 日本語で\n", /* 1 */ "-p 接続先ポート, 0は無効, 既定値", /* 2 */ #ifndef WOLFSSL_TLS13 "-v 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 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()"); } diff --git a/src/internal.c b/src/internal.c index e13e5536b..12c0c8923 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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; diff --git a/src/ssl.c b/src/ssl.c index 28772bd84..a973a2bcf 100644 --- a/src/ssl.c +++ b/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 ******************************************************************************/ - diff --git a/src/tls13.c b/src/tls13.c index d67b79f50..6d547b9a0 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -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 diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0cdaaa54f..6ac710908 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b4ff12a46..ef7e0befc 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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 diff --git a/wolfssl/test.h b/wolfssl/test.h index 35c2f2dfd..920cd65de 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -16,7 +16,7 @@ #include #endif #include -#include +#include #include #include #include @@ -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 + +#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) +#include +#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) {