forked from wolfSSL/wolfssl
Merge pull request #6668 from julek-wolfssl/zd/16515
DTLS downgrade bug fixes
This commit is contained in:
@ -19949,7 +19949,7 @@ static int DtlsShouldDrop(WOLFSSL* ssl, int retcode)
|
|||||||
|
|
||||||
#ifndef NO_WOLFSSL_SERVER
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END
|
if (ssl->options.side == WOLFSSL_SERVER_END
|
||||||
&& ssl->curRL.type != handshake) {
|
&& ssl->curRL.type != handshake && !IsSCR(ssl)) {
|
||||||
int beforeCookieVerified = 0;
|
int beforeCookieVerified = 0;
|
||||||
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
||||||
beforeCookieVerified =
|
beforeCookieVerified =
|
||||||
|
@ -4004,7 +4004,7 @@ int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
|
|||||||
return WOLFSSL_SUCCESS;
|
return WOLFSSL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
/* do a secure renegotiation handshake, user forced, we discourage */
|
/* do a secure renegotiation handshake, user forced, we discourage */
|
||||||
static int _Rehandshake(WOLFSSL* ssl)
|
static int _Rehandshake(WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
@ -4069,7 +4069,7 @@ static int _Rehandshake(WOLFSSL* ssl)
|
|||||||
|
|
||||||
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
||||||
|
|
||||||
#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SECURE_RENEGOTIATION)
|
#if !defined(NO_WOLFSSL_SERVER)
|
||||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||||
ret = SendHelloRequest(ssl);
|
ret = SendHelloRequest(ssl);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -4077,7 +4077,7 @@ static int _Rehandshake(WOLFSSL* ssl)
|
|||||||
return WOLFSSL_FATAL_ERROR;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !NO_WOLFSSL_SERVER && HAVE_SECURE_RENEGOTIATION */
|
#endif /* !NO_WOLFSSL_SERVER */
|
||||||
|
|
||||||
ret = InitHandshakeHashes(ssl);
|
ret = InitHandshakeHashes(ssl);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -4151,6 +4151,8 @@ int wolfSSL_SecureResume(WOLFSSL* ssl)
|
|||||||
|
|
||||||
#endif /* NO_WOLFSSL_CLIENT */
|
#endif /* NO_WOLFSSL_CLIENT */
|
||||||
|
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
|
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
|
||||||
{
|
{
|
||||||
WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
|
WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
|
||||||
|
@ -11917,7 +11917,7 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
|||||||
case CLIENT_HELLO_SENT:
|
case CLIENT_HELLO_SENT:
|
||||||
/* Get the response/s from the server. */
|
/* Get the response/s from the server. */
|
||||||
while (ssl->options.serverState <
|
while (ssl->options.serverState <
|
||||||
SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
SERVER_HELLOVERIFYREQUEST_COMPLETE) {
|
||||||
if ((ssl->error = ProcessReply(ssl)) < 0) {
|
if ((ssl->error = ProcessReply(ssl)) < 0) {
|
||||||
WOLFSSL_ERROR(ssl->error);
|
WOLFSSL_ERROR(ssl->error);
|
||||||
return WOLFSSL_FATAL_ERROR;
|
return WOLFSSL_FATAL_ERROR;
|
||||||
|
141
tests/api.c
141
tests/api.c
@ -6152,6 +6152,8 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|||||||
size_t msg_len = 0;
|
size_t msg_len = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
wolfSSL_SetLoggingPrefix("server");
|
||||||
|
|
||||||
#ifdef WOLFSSL_TIRTOS
|
#ifdef WOLFSSL_TIRTOS
|
||||||
fdOpenSession(Task_self());
|
fdOpenSession(Task_self());
|
||||||
#endif
|
#endif
|
||||||
@ -6365,7 +6367,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|||||||
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = wolfSSL_accept(ssl);
|
ret = wolfSSL_negotiate(ssl);
|
||||||
err = wolfSSL_get_error(ssl, 0);
|
err = wolfSSL_get_error(ssl, 0);
|
||||||
} while (err == WC_PENDING_E);
|
} while (err == WC_PENDING_E);
|
||||||
if (ret != WOLFSSL_SUCCESS) {
|
if (ret != WOLFSSL_SUCCESS) {
|
||||||
@ -6442,6 +6444,8 @@ done:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wolfSSL_SetLoggingPrefix(NULL);
|
||||||
|
|
||||||
#ifndef WOLFSSL_TIRTOS
|
#ifndef WOLFSSL_TIRTOS
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -6688,6 +6692,8 @@ static int test_client_nofail(void* args, cbType cb)
|
|||||||
int doUdp = 0;
|
int doUdp = 0;
|
||||||
const char* cipherName1, *cipherName2;
|
const char* cipherName1, *cipherName2;
|
||||||
|
|
||||||
|
wolfSSL_SetLoggingPrefix("client");
|
||||||
|
|
||||||
#ifdef WOLFSSL_TIRTOS
|
#ifdef WOLFSSL_TIRTOS
|
||||||
fdOpenSession(Task_self());
|
fdOpenSession(Task_self());
|
||||||
#endif
|
#endif
|
||||||
@ -6830,7 +6836,7 @@ static int test_client_nofail(void* args, cbType cb)
|
|||||||
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = wolfSSL_connect(ssl);
|
ret = wolfSSL_negotiate(ssl);
|
||||||
err = wolfSSL_get_error(ssl, 0);
|
err = wolfSSL_get_error(ssl, 0);
|
||||||
} while (err == WC_PENDING_E);
|
} while (err == WC_PENDING_E);
|
||||||
if (ret != WOLFSSL_SUCCESS) {
|
if (ret != WOLFSSL_SUCCESS) {
|
||||||
@ -6907,6 +6913,9 @@ done:
|
|||||||
(void)args;
|
(void)args;
|
||||||
(void)cb;
|
(void)cb;
|
||||||
#endif /* !NO_WOLFSSL_CLIENT */
|
#endif /* !NO_WOLFSSL_CLIENT */
|
||||||
|
|
||||||
|
wolfSSL_SetLoggingPrefix(NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63153,8 +63162,8 @@ static int test_dtls_1_0_hvr_downgrade(void)
|
|||||||
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
|
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
|
||||||
|
|
||||||
func_cb_client.doUdp = func_cb_server.doUdp = 1;
|
func_cb_client.doUdp = func_cb_server.doUdp = 1;
|
||||||
func_cb_server.method = wolfDTLSv1_2_server_method;
|
|
||||||
func_cb_client.method = wolfDTLS_client_method;
|
func_cb_client.method = wolfDTLS_client_method;
|
||||||
|
func_cb_server.method = wolfDTLSv1_2_server_method;
|
||||||
func_cb_client.ctx_ready = test_dtls_1_0_hvr_downgrade_ctx_ready;
|
func_cb_client.ctx_ready = test_dtls_1_0_hvr_downgrade_ctx_ready;
|
||||||
|
|
||||||
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
|
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
|
||||||
@ -63242,6 +63251,130 @@ static int test_session_ticket_no_id(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
|
||||||
|
static void test_dtls_downgrade_scr_server_ctx_ready_server(WOLFSSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dtls_downgrade_scr_server_ctx_ready(WOLFSSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dtls_downgrade_scr_server_on_result(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
char testMsg[] = "Message after SCR";
|
||||||
|
char msgBuf[sizeof(testMsg)];
|
||||||
|
if (wolfSSL_is_server(ssl)) {
|
||||||
|
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_FATAL_ERROR);
|
||||||
|
AssertIntEQ(wolfSSL_get_error(ssl, -1), APP_DATA_READY);
|
||||||
|
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
|
||||||
|
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
|
||||||
|
sizeof(testMsg));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
|
||||||
|
sizeof(testMsg));
|
||||||
|
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_dtls_downgrade_scr_server(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
callback_functions func_cb_client;
|
||||||
|
callback_functions func_cb_server;
|
||||||
|
|
||||||
|
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
|
||||||
|
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
|
||||||
|
|
||||||
|
func_cb_client.doUdp = func_cb_server.doUdp = 1;
|
||||||
|
func_cb_client.method = wolfDTLSv1_2_client_method;
|
||||||
|
func_cb_server.method = wolfDTLS_server_method;
|
||||||
|
func_cb_client.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready;
|
||||||
|
func_cb_server.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready_server;
|
||||||
|
func_cb_client.on_result = test_dtls_downgrade_scr_server_on_result;
|
||||||
|
func_cb_server.on_result = test_dtls_downgrade_scr_server_on_result;
|
||||||
|
|
||||||
|
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
|
||||||
|
|
||||||
|
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
|
||||||
|
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
|
||||||
|
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int test_dtls_downgrade_scr_server(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||||
|
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
|
||||||
|
static void test_dtls_downgrade_scr_ctx_ready(WOLFSSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
|
||||||
|
WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dtls_downgrade_scr_on_result(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
char testMsg[] = "Message after SCR";
|
||||||
|
char msgBuf[sizeof(testMsg)];
|
||||||
|
if (wolfSSL_is_server(ssl)) {
|
||||||
|
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_FATAL_ERROR);
|
||||||
|
AssertIntEQ(wolfSSL_get_error(ssl, -1), APP_DATA_READY);
|
||||||
|
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
|
||||||
|
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
|
||||||
|
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
|
||||||
|
sizeof(testMsg));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
|
||||||
|
sizeof(testMsg));
|
||||||
|
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_dtls_downgrade_scr(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
callback_functions func_cb_client;
|
||||||
|
callback_functions func_cb_server;
|
||||||
|
|
||||||
|
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
|
||||||
|
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
|
||||||
|
|
||||||
|
func_cb_client.doUdp = func_cb_server.doUdp = 1;
|
||||||
|
func_cb_client.method = wolfDTLS_client_method;
|
||||||
|
func_cb_server.method = wolfDTLSv1_2_server_method;
|
||||||
|
func_cb_client.ctx_ready = test_dtls_downgrade_scr_ctx_ready;
|
||||||
|
func_cb_client.on_result = test_dtls_downgrade_scr_on_result;
|
||||||
|
func_cb_server.on_result = test_dtls_downgrade_scr_on_result;
|
||||||
|
|
||||||
|
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
|
||||||
|
|
||||||
|
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
|
||||||
|
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
|
||||||
|
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int test_dtls_downgrade_scr(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
| Main
|
| Main
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@ -64496,6 +64629,8 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
|
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
|
||||||
TEST_DECL(test_dtls_1_0_hvr_downgrade),
|
TEST_DECL(test_dtls_1_0_hvr_downgrade),
|
||||||
TEST_DECL(test_session_ticket_no_id),
|
TEST_DECL(test_session_ticket_no_id),
|
||||||
|
TEST_DECL(test_dtls_downgrade_scr_server),
|
||||||
|
TEST_DECL(test_dtls_downgrade_scr),
|
||||||
/* This test needs to stay at the end to clean up any caches allocated. */
|
/* This test needs to stay at the end to clean up any caches allocated. */
|
||||||
TEST_DECL(test_wolfSSL_Cleanup)
|
TEST_DECL(test_wolfSSL_Cleanup)
|
||||||
};
|
};
|
||||||
|
@ -127,6 +127,7 @@ THREAD_LS_T void *StackSizeCheck_stackOffsetPointer = 0;
|
|||||||
/* Set these to default values initially. */
|
/* Set these to default values initially. */
|
||||||
static wolfSSL_Logging_cb log_function = NULL;
|
static wolfSSL_Logging_cb log_function = NULL;
|
||||||
static int loggingEnabled = 0;
|
static int loggingEnabled = 0;
|
||||||
|
THREAD_LS_T const char* log_prefix = NULL;
|
||||||
|
|
||||||
#if defined(WOLFSSL_APACHE_MYNEWT)
|
#if defined(WOLFSSL_APACHE_MYNEWT)
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
@ -186,6 +187,15 @@ void wolfSSL_Debugging_OFF(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOLFSSL_API void wolfSSL_SetLoggingPrefix(const char* prefix)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_WOLFSSL
|
||||||
|
log_prefix = prefix;
|
||||||
|
#else
|
||||||
|
(void)prefix;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_FUNC_TIME
|
#ifdef WOLFSSL_FUNC_TIME
|
||||||
/* WARNING: This code is only to be used for debugging performance.
|
/* WARNING: This code is only to be used for debugging performance.
|
||||||
* The code is not thread-safe.
|
* The code is not thread-safe.
|
||||||
@ -316,7 +326,10 @@ static void wolfssl_log(const int logLevel, const char *const logMessage)
|
|||||||
defined(HAVE_STACK_SIZE_VERBOSE) && defined(HAVE_STACK_SIZE_VERBOSE_LOG)
|
defined(HAVE_STACK_SIZE_VERBOSE) && defined(HAVE_STACK_SIZE_VERBOSE_LOG)
|
||||||
STACK_SIZE_CHECKPOINT_MSG(logMessage);
|
STACK_SIZE_CHECKPOINT_MSG(logMessage);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "%s\n", logMessage);
|
if (log_prefix != NULL)
|
||||||
|
fprintf(stderr, "[%s]: %s\n", log_prefix, logMessage);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%s\n", logMessage);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3984,8 +3984,10 @@ WOLFSSL_API int wolfSSL_NoKeyShares(WOLFSSL* ssl);
|
|||||||
|
|
||||||
WOLFSSL_API int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl);
|
WOLFSSL_API int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl);
|
||||||
WOLFSSL_API int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx);
|
WOLFSSL_API int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx);
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl);
|
WOLFSSL_API int wolfSSL_Rehandshake(WOLFSSL* ssl);
|
||||||
WOLFSSL_API int wolfSSL_SecureResume(WOLFSSL* ssl);
|
WOLFSSL_API int wolfSSL_SecureResume(WOLFSSL* ssl);
|
||||||
|
#endif
|
||||||
WOLFSSL_API long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl);
|
WOLFSSL_API long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -100,6 +100,8 @@ WOLFSSL_API int wolfSSL_Debugging_ON(void);
|
|||||||
/* turn logging off */
|
/* turn logging off */
|
||||||
WOLFSSL_API void wolfSSL_Debugging_OFF(void);
|
WOLFSSL_API void wolfSSL_Debugging_OFF(void);
|
||||||
|
|
||||||
|
WOLFSSL_API void wolfSSL_SetLoggingPrefix(const char* prefix);
|
||||||
|
|
||||||
#ifdef HAVE_WC_INTROSPECTION
|
#ifdef HAVE_WC_INTROSPECTION
|
||||||
WOLFSSL_API const char *wolfSSL_configure_args(void);
|
WOLFSSL_API const char *wolfSSL_configure_args(void);
|
||||||
WOLFSSL_API const char *wolfSSL_global_cflags(void);
|
WOLFSSL_API const char *wolfSSL_global_cflags(void);
|
||||||
|
Reference in New Issue
Block a user