From 93dfb4c7f4ef0ccc50155605928e5efe6033fc80 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 16 Jun 2021 00:26:48 -0500 Subject: [PATCH 1/6] add outbound connection filtering support to libwolfssl, add wolfSentry support to the test client, and add wolfSentry JSON config file support to the test client and server using --wolfsentry-config. also, add mygetopt_long() to wolfssl/test.h, and add --help and Japanese counterpart options to test client and server. --- examples/client/client.c | 212 ++++++++++++++++++++- examples/client/include.am | 3 +- examples/server/server.c | 239 ++++++++++-------------- src/internal.c | 2 + src/ssl.c | 62 ++++-- src/tls13.c | 12 ++ wolfssl/internal.h | 4 + wolfssl/ssl.h | 12 +- wolfssl/test.h | 374 +++++++++++++++++++++++++++++++++++++ 9 files changed, 757 insertions(+), 163 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index f9376c278..f31ac1e06 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -30,6 +30,19 @@ #include +#ifdef WOLFSSL_WOLFSENTRY_HOOKS +# include +# include +# include + +static struct wolfsentry_context *wolfsentry = NULL; + +#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 @@ -39,6 +52,10 @@ #include +#ifdef WOLFSSL_WOLFSENTRY_HOOKS +#define tcp_connect(sockfd, ip, port, udp, sctp, ssl) tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry) +#endif + #include #include @@ -967,7 +984,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 +1006,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 +1165,10 @@ 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 +1193,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 +1355,10 @@ 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 +1473,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 +1538,9 @@ 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 +1551,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 +1572,14 @@ 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 +1779,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 +1795,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 +2284,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 +2320,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 +2570,136 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif + + +#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("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 ((wolfsentry_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(wolfsentry_ret)); + err_sys("error while initlalizing 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"); + } + + wolfsentry_ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf); + if (wolfsentry_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 ((wolfsentry_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 /* !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) */ + { + + 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_ACCEPT)) + < 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_OUT | + 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(wolfsentry_ret)); + } + + if (wolfsentry_ret < 0) + err_sys("unable to configure route table"); + } + + 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 +4045,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..047969be6 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -37,6 +37,13 @@ #ifdef WOLFSSL_WOLFSENTRY_HOOKS # include +# include +# include + +#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) +static const char *wolfsentry_config_path = NULL; +#endif + #endif #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) @@ -279,137 +286,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 +680,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 +814,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 +827,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 +962,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 +1103,9 @@ 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) @@ -1238,6 +1127,14 @@ 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 +1347,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 +1364,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 +1835,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); @@ -2081,6 +1996,52 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) 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_ex(catastrophic, "unable to open wolfSentry config file"); + } + + if ((wolfsentry_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(wolfsentry_ret)); + err_sys_ex(catastrophic, "error while initlalizing 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_ex(catastrophic, "error while reading wolfSentry config file"); + } + + wolfsentry_ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf); + if (wolfsentry_ret < 0) { + fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf); + err_sys_ex(catastrophic, "error while loading wolfSentry config file"); + } + if ((n < sizeof buf) && feof(f)) + break; + } + fclose(f); + + if ((wolfsentry_ret = wolfsentry_config_json_fini(jps, err_buf, sizeof err_buf)) < 0) { + fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf); + err_sys_ex(catastrophic, "error while loading wolfSentry config file"); + } + + } else +#endif /* !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) */ { struct wolfsentry_route_table *table; @@ -2124,7 +2085,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) (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_PARENT_EVENT_WILDCARD | WOLFSENTRY_ROUTE_FLAG_REMOTE_INTERFACE_WILDCARD| WOLFSENTRY_ROUTE_FLAG_LOCAL_INTERFACE_WILDCARD | WOLFSENTRY_ROUTE_FLAG_SA_LOCAL_ADDR_WILDCARD | @@ -2807,7 +2768,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 18732349d..f33630d99 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5616,6 +5616,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 579e13fcc..4d5f667d6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1040,6 +1040,30 @@ int wolfSSL_set_AcceptFilter( return WOLFSSL_SUCCESS; } +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 WOLFSSL_SUCCESS; +} + +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 WOLFSSL_SUCCESS; +} + #endif /* WOLFSSL_WOLFSENTRY_HOOKS */ #ifndef WOLFSSL_LEANPSK @@ -12580,6 +12604,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; @@ -12941,6 +12977,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; @@ -12953,15 +12998,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 @@ -43458,10 +43494,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: @@ -43511,7 +43544,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) @@ -56656,4 +56689,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 00bf17de9..bf3d1c408 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2876,6 +2876,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; @@ -4108,6 +4110,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 a131c6842..2d2478199 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1183,6 +1183,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 */ @@ -4441,13 +4449,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 60f310a28..1b1188253 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -646,6 +646,131 @@ 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 @@ -1051,6 +1176,255 @@ 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) + +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 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 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; +} + +#endif /* WOLFSSL_WOLFSENTRY_HOOKS */ + static WC_INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, int udp, int sctp, WOLFSSL* ssl) { From 1c9ea6228c77f245d7ce6ea88d9ca35c05894e8c Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 16 Jun 2021 00:49:33 -0500 Subject: [PATCH 2/6] ssl.c: fix build gating on wolfSSL_X509_get_ex_new_index(). --- src/ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ssl.c b/src/ssl.c index 4d5f667d6..c77108dca 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -48378,6 +48378,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) From 55ed985c9abfe28f925c360de0bab8234f4b326d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 17 Jun 2021 15:56:02 -0500 Subject: [PATCH 3/6] include error-ssl.h, not error-crypt.h, in wolfssl/test.h, and fix rebase error in src/ssl.c. --- src/ssl.c | 48 ++++++++++++++++++++++++------------------------ wolfssl/test.h | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index c77108dca..d6444c5e0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -53835,6 +53835,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. @@ -53867,30 +53891,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 /******************************************************************************* diff --git a/wolfssl/test.h b/wolfssl/test.h index 1b1188253..ffd11ea8c 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -16,7 +16,7 @@ #include #endif #include -#include +#include #include #include #include From 8c75553e08a02e74dbce47ee81647744cbb06cfb Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 17 Jun 2021 20:02:34 -0500 Subject: [PATCH 4/6] wolfSentry integration: move rest of recyclable code out of examples and into wolfsentry_setup() in wolfssl/test.h, and implement peer review corrections on error codes and string.h wrapper macros. --- examples/client/client.c | 131 +------------------------- examples/server/server.c | 130 +------------------------- src/ssl.c | 8 +- wolfssl/test.h | 196 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 204 insertions(+), 261 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index f31ac1e06..d305a4082 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -31,16 +31,10 @@ #include #ifdef WOLFSSL_WOLFSENTRY_HOOKS -# include -# include -# include - -static struct wolfsentry_context *wolfsentry = NULL; - +#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) @@ -52,10 +46,6 @@ static const char *wolfsentry_config_path = NULL; #include -#ifdef WOLFSSL_WOLFSENTRY_HOOKS -#define tcp_connect(sockfd, ip, port, udp, sctp, ssl) tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry) -#endif - #include #include @@ -2573,125 +2563,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #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)); + if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT) < 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); - -#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 ((wolfsentry_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(wolfsentry_ret)); - err_sys("error while initlalizing 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"); - } - - wolfsentry_ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf); - if (wolfsentry_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 ((wolfsentry_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 /* !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) */ - { - - 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_ACCEPT)) - < 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_OUT | - 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(wolfsentry_ret)); - } - - if (wolfsentry_ret < 0) - err_sys("unable to configure route table"); - } if (wolfSSL_CTX_set_ConnectFilter( ctx, diff --git a/examples/server/server.c b/examples/server/server.c index 047969be6..b20f2d43d 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -36,15 +36,11 @@ #endif #ifdef WOLFSSL_WOLFSENTRY_HOOKS -# include -# include -# include - +#include #if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) static const char *wolfsentry_config_path = NULL; #endif - -#endif +#endif /* WOLFSSL_WOLFSENTRY_HOOKS */ #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) #include @@ -1119,7 +1115,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 @@ -1984,125 +1979,8 @@ 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_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_ex(catastrophic, "unable to open wolfSentry config file"); - } - - if ((wolfsentry_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(wolfsentry_ret)); - err_sys_ex(catastrophic, "error while initlalizing 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_ex(catastrophic, "error while reading wolfSentry config file"); - } - - wolfsentry_ret = wolfsentry_config_json_feed(jps, buf, n, err_buf, sizeof err_buf); - if (wolfsentry_ret < 0) { - fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf); - err_sys_ex(catastrophic, "error while loading wolfSentry config file"); - } - if ((n < sizeof buf) && feof(f)) - break; - } - fclose(f); - - if ((wolfsentry_ret = wolfsentry_config_json_fini(jps, err_buf, sizeof err_buf)) < 0) { - fprintf(stderr, "%.*s\n", (int)sizeof err_buf, err_buf); - err_sys_ex(catastrophic, "error while loading wolfSentry config file"); - } - - } else -#endif /* !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) */ - { - 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_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(wolfsentry_ret)); - } - - if (wolfsentry_ret < 0) - err_sys_ex(catastrophic, "unable to configure route table"); - } - + if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) + err_sys("unable to initialize wolfSentry"); if (wolfSSL_CTX_set_AcceptFilter( ctx, diff --git a/src/ssl.c b/src/ssl.c index d6444c5e0..8ff728f7b 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,7 @@ 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( @@ -1049,7 +1049,7 @@ int wolfSSL_CTX_set_ConnectFilter( return BAD_FUNC_ARG; ctx->ConnectFilter = ConnectFilter; ctx->ConnectFilter_arg = ConnectFilter_arg; - return WOLFSSL_SUCCESS; + return 0; } int wolfSSL_set_ConnectFilter( @@ -1061,7 +1061,7 @@ int wolfSSL_set_ConnectFilter( return BAD_FUNC_ARG; ssl->ConnectFilter = ConnectFilter; ssl->ConnectFilter_arg = ConnectFilter_arg; - return WOLFSSL_SUCCESS; + return 0; } #endif /* WOLFSSL_WOLFSENTRY_HOOKS */ diff --git a/wolfssl/test.h b/wolfssl/test.h index ffd11ea8c..1246ec5dd 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1053,7 +1053,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; @@ -1178,6 +1178,12 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) #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]; @@ -1192,6 +1198,8 @@ 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( @@ -1329,6 +1337,186 @@ static int wolfSentry_NetworkFilterCallback( 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 initlalizing 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 /* !defined(NO_FILESYSTEM) && !defined(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, @@ -1423,7 +1611,9 @@ static WC_INLINE int tcp_connect_with_wolfSentry( return WOLFSSL_SUCCESS; } -#endif /* WOLFSSL_WOLFSENTRY_HOOKS */ +#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) @@ -1441,6 +1631,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) { From b59c60db8a54d704f1150a142597a08137e98b51 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 17 Jun 2021 20:14:54 -0500 Subject: [PATCH 5/6] ssl.c: fix build gating on wolfSSL_X509_get_ex_new_index() again (fixing rebase error). --- src/ssl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 8ff728f7b..674dec28c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -47273,8 +47273,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) { From 716237c5dd08e6318d6dc4832c376563703716d4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 21 Jun 2021 15:09:39 -0700 Subject: [PATCH 6/6] Fix minor line length and spelling. --- examples/client/client.c | 19 +++++++++++++------ examples/server/server.c | 13 +++++++++---- wolfssl/test.h | 14 ++++++++------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index d305a4082..9ede92d1b 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1156,7 +1156,8 @@ static const char* client_usage_msg[][68] = { " 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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) "--wolfsentry-config Path for JSON wolfSentry config\n", /* 68 */ #endif @@ -1346,7 +1347,8 @@ static const char* client_usage_msg[][68] = { " 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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) "--wolfsentry-config wolfSentry コンフィグファイル\n", /* 68 */ #endif @@ -1528,7 +1530,8 @@ 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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) printf("%s", msg[++msgid]); /* --wolfsentry-config */ #endif } @@ -1563,7 +1566,8 @@ 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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) { "wolfsentry-config", 1, 256 }, #endif { "help", 0, 257 }, @@ -2563,14 +2567,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_WOLFSENTRY_HOOKS - if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT) < 0) + 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) + wolfsentry) < 0) { err_sys("unable to install wolfSentry_NetworkFilterCallback"); + } #endif if (cipherList && !useDefCipherList) { diff --git a/examples/server/server.c b/examples/server/server.c index b20f2d43d..a1956f395 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -1099,7 +1099,8 @@ 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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) printf("%s", msg[++msgId]); /* --wolfsentry-config */ #endif } @@ -1123,7 +1124,8 @@ THREAD_RETURN WOLFSSL_THREAD server_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) +#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFSENTRY_NO_JSON) { "wolfsentry-config", 1, 256 }, #endif { "help", 0, 257 }, @@ -1979,15 +1981,18 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) err_sys_ex(catastrophic, "unable to get ctx"); #ifdef WOLFSSL_WOLFSENTRY_HOOKS - if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) + if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, + WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) { err_sys("unable to initialize wolfSentry"); + } 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) diff --git a/wolfssl/test.h b/wolfssl/test.h index 1246ec5dd..3d12e5e4f 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -663,7 +663,8 @@ struct mygetopt_long_config { * 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 WC_INLINE int mygetopt_long(int argc, char** argv, const char* optstring, + const struct mygetopt_long_config *longopts, int *longindex) { static char* next = NULL; @@ -1374,7 +1375,7 @@ static int wolfsentry_setup( fprintf(stderr, "wolfsentry_config_json_init() returned " WOLFSENTRY_ERROR_FMT "\n", WOLFSENTRY_ERROR_FMT_ARGS(ret)); - err_sys("error while initlalizing wolfSentry config parser"); + err_sys("error while initializing wolfSentry config parser"); } for (;;) { @@ -1400,7 +1401,7 @@ static int wolfsentry_setup( } } else -#endif /* !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) */ +#endif /* !NO_FILESYSTEM && !WOLFSENTRY_NO_JSON */ { struct wolfsentry_route_table *table; @@ -1559,7 +1560,7 @@ static WC_INLINE int tcp_connect_with_wolfSentry( &wolfsentry_data->local, wolfsentry_data->flags, NULL /* event_label */, - 0 /* event_label_len */, + 0 /* event_label_len */, NULL /* caller_context */, NULL /* id */, NULL /* inexact_matches */, @@ -1592,7 +1593,7 @@ static WC_INLINE int tcp_connect_with_wolfSentry( decision, decision == WOLFSSL_NETFILTER_REJECT ? "REJECT" : decision == WOLFSSL_NETFILTER_ACCEPT ? "ACCEPT" : - decision == WOLFSSL_NETFILTER_PASS ? "PASS" : + decision == WOLFSSL_NETFILTER_PASS ? "PASS" : "???"); if (decision == WOLFSSL_NETFILTER_REJECT) @@ -1611,7 +1612,8 @@ static WC_INLINE int tcp_connect_with_wolfSentry( return WOLFSSL_SUCCESS; } -#define tcp_connect(sockfd, ip, port, udp, sctp, ssl) tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry) +#define tcp_connect(sockfd, ip, port, udp, sctp, ssl) \ + tcp_connect_with_wolfSentry(sockfd, ip, port, udp, sctp, ssl, wolfsentry) #else /* !WOLFSSL_WOLFSENTRY_HOOKS */