BOOL tls_send_alert(rdpTls* tls) { if (!tls) return FALSE; if (!tls->ssl) return TRUE; if (tls->alertDescription != TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY) { /** * OpenSSL doesn't really expose an API for sending a TLS alert manually. * * The following code disables the sending of the default "close notify" * and then proceeds to force sending a custom TLS alert before shutting down. * * Manually sending a TLS alert is necessary in certain cases, * like when server-side NLA results in an authentication failure. */ SSL_set_quiet_shutdown(tls->ssl, 1); if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (tls->ssl->session)) SSL_CTX_remove_session(tls->ssl->ctx, tls->ssl->session); tls->ssl->s3->alert_dispatch = 1; tls->ssl->s3->send_alert[0] = tls->alertLevel; tls->ssl->s3->send_alert[1] = tls->alertDescription; if (tls->ssl->s3->wbuf.left == 0) tls->ssl->method->ssl_dispatch_alert(tls->ssl); } return TRUE; }
static int openssl_ssl_shutdown(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); int ret = 0; if (lua_isnoneornil(L, 2)) { ret = SSL_shutdown(s); return openssl_ssl_pushresult(L, s, ret); } else if (lua_isstring(L, 2)) { const static char* sMode[] = {"read", "write", "quiet", "noquiet", NULL}; int mode = luaL_checkoption(L, 2, NULL, sMode); if (mode == 0) SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN); else if (mode == 1) SSL_set_shutdown(s, SSL_SENT_SHUTDOWN); else if (mode == 2) SSL_set_quiet_shutdown(s, 1); else if (mode == 3) SSL_set_quiet_shutdown(s, 0); } else if (lua_isboolean(L, 2)) { int quiet = lua_toboolean(L, 2); if (quiet) lua_pushboolean(L, SSL_get_quiet_shutdown(s)); else { int shut = SSL_get_shutdown(s); if (shut == SSL_RECEIVED_SHUTDOWN) lua_pushstring(L, "read"); else if (shut == SSL_SENT_SHUTDOWN) lua_pushstring(L, "write"); else if (shut == 0) lua_pushnil(L); else luaL_error(L, "Can't understand SSL_get_shutdown result"); } return 1; } else luaL_argerror(L, 2, "should be boolean or string[read|write|quiet|noquite]"); return 0; };
void swSSL_close(swConnection *conn) { SSL_set_quiet_shutdown(conn->ssl, 1); SSL_set_shutdown(conn->ssl, SSL_RECEIVED_SHUTDOWN | SSL_SENT_SHUTDOWN); SSL_shutdown(conn->ssl); SSL_free(conn->ssl); conn->ssl = NULL; }
/** Free a TLS session and any associated OpenSSL data * * @param session to free. * @return 0. */ static int _tls_session_free(tls_session_t *session) { if (session->ssl) { SSL_set_quiet_shutdown(session->ssl, 1); SSL_shutdown(session->ssl); SSL_free(session->ssl); session->ssl = NULL; } return 0; }
int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) { if (conn == NULL) return -1; /* Shutdown previous TLS connection without notifying the peer * because the connection was already terminated in practice * and "close notify" shutdown alert would confuse AS. */ SSL_set_quiet_shutdown(conn->ssl, 1); SSL_shutdown(conn->ssl); return 0; }
BOOL tls_send_alert(rdpTls* tls) { if (!tls) return FALSE; if (!tls->ssl) return TRUE; /** * FIXME: The following code does not work on OpenSSL > 1.1.0 because the * SSL struct is opaqe now */ #if OPENSSL_VERSION_NUMBER < 0x10100000L if (tls->alertDescription != TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY) { /** * OpenSSL doesn't really expose an API for sending a TLS alert manually. * * The following code disables the sending of the default "close notify" * and then proceeds to force sending a custom TLS alert before shutting down. * * Manually sending a TLS alert is necessary in certain cases, * like when server-side NLA results in an authentication failure. */ SSL_SESSION* ssl_session = SSL_get_session(tls->ssl); SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(tls->ssl); SSL_set_quiet_shutdown(tls->ssl, 1); if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (ssl_session)) SSL_CTX_remove_session(ssl_ctx, ssl_session); tls->ssl->s3->alert_dispatch = 1; tls->ssl->s3->send_alert[0] = tls->alertLevel; tls->ssl->s3->send_alert[1] = tls->alertDescription; if (tls->ssl->s3->wbuf.left == 0) tls->ssl->method->ssl_dispatch_alert(tls->ssl); } #endif return TRUE; }
/* close ssl connection and free ssl object SYNOPSIS my_ssl_close() vio vio RETURN VALUES 1 ok 0 or -1 on error */ int my_ssl_close(Vio *vio) { int i, rc; DBUG_ENTER("my_ssl_close"); if (!vio || !vio->ssl) DBUG_RETURN(1); SSL_set_quiet_shutdown(vio->ssl, 1); /* 2 x pending + 2 * data = 4 */ for (i=0; i < 4; i++) if ((rc= SSL_shutdown(vio->ssl))) break; SSL_free(vio->ssl); vio->ssl= NULL; DBUG_RETURN(rc); }
my_bool ma_tls_close(MARIADB_TLS *ctls) { int i, rc; SSL *ssl; if (!ctls || !ctls->ssl) return 1; ssl= (SSL *)ctls->ssl; SSL_set_quiet_shutdown(ssl, 1); /* 2 x pending + 2 * data = 4 */ for (i=0; i < 4; i++) if ((rc= SSL_shutdown(ssl))) break; SSL_free(ssl); ctls->ssl= NULL; return rc; }
int vio_ssl_close(Vio *vio) { int r= 0; SSL *ssl= (SSL*)vio->ssl_arg; DBUG_ENTER("vio_ssl_close"); if (ssl) { /* THE SSL standard says that SSL sockets must send and receive a close_notify alert on socket shutdown to avoid truncation attacks. However, this can cause problems since we often hold a lock during shutdown and this IO can take an unbounded amount of time to complete. Since our packets are self describing with length, we aren't vunerable to these attacks. Therefore, we just shutdown by closing the socket (quiet shutdown). */ SSL_set_quiet_shutdown(ssl, 1); switch ((r= SSL_shutdown(ssl))) { case 1: /* Shutdown successful */ break; case 0: /* Shutdown not yet finished - since the socket is going to be closed there is no need to call SSL_shutdown() a second time to wait for the other side to respond */ break; default: /* Shutdown failed */ DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %d", SSL_get_error(ssl, r))); break; } } DBUG_RETURN(vio_close(vio)); }
my_bool ma_tls_close(MARIADB_TLS *ctls) { int i, rc; SSL *ssl; if (!ctls || !ctls->ssl) return 1; ssl= (SSL *)ctls->ssl; SSL_set_quiet_shutdown(ssl, 1); /* 2 x pending + 2 * data = 4 */ for (i=0; i < 4; i++) if ((rc= SSL_shutdown(ssl))) break; /* Since we transferred ownership of BIO to ssl, BIO will automatically freed - no need for an explicit BIO_free_all */ SSL_free(ssl); ctls->ssl= NULL; return rc; }
/* Asynchronous SSL stream reader */ int ssl_read_thread(thread_t * thread) { checker_t *checker = THREAD_ARG(thread); http_checker_t *http_get_check = CHECKER_ARG(checker); http_arg_t *http_arg = HTTP_ARG(http_get_check); request_t *req = HTTP_REQ(http_arg); unsigned char digest[16]; int r = 0; int val; /* Handle read timeout */ if (thread->type == THREAD_READ_TIMEOUT && !req->extracted) return timeout_epilog(thread, "=> SSL CHECK failed on service" " : recevice data <=\n\n", "SSL read"); /* Set descriptor non blocking */ val = fcntl(thread->u.fd, F_GETFL, 0); fcntl(thread->u.fd, F_SETFL, val | O_NONBLOCK); /* read the SSL stream */ r = SSL_read(req->ssl, req->buffer + req->len, MAX_BUFFER_LENGTH - req->len); /* restore descriptor flags */ fcntl(thread->u.fd, F_SETFL, val); req->error = SSL_get_error(req->ssl, r); if (req->error == SSL_ERROR_WANT_READ) { /* async read unfinished */ thread_add_read(thread->master, ssl_read_thread, checker, thread->u.fd, http_get_check->connection_to); } else if (r > 0 && req->error == 0) { /* Handle response stream */ http_process_response(req, r); /* * Register next ssl stream reader. * Register itself to not perturbe global I/O multiplexer. */ thread_add_read(thread->master, ssl_read_thread, checker, thread->u.fd, http_get_check->connection_to); } else if (req->error) { /* All the SSL streal has been parsed */ MD5_Final(digest, &req->context); SSL_set_quiet_shutdown(req->ssl, 1); r = (req->error == SSL_ERROR_ZERO_RETURN) ? SSL_shutdown(req->ssl) : 0; if (r && !req->extracted) { /* check if server is currently alive */ if (svr_checker_up(checker->id, checker->rs)) { smtp_alert(checker->rs, NULL, NULL, "DOWN", "=> SSL CHECK failed on service" " : cannot receive data <=\n\n"); update_svr_checker_state(DOWN, checker->id , checker->vs , checker->rs); } return epilog(thread, 1, 0, 0); } /* Handle response stream */ http_handle_response(thread, digest, (!req->extracted) ? 1 : 0); } return 0; }
extern "C" void CryptoNative_SslSetQuietShutdown(SSL* ssl, int mode) { SSL_set_quiet_shutdown(ssl, mode); }