Replace OpenSSL with GnuTLS for all network communications
This commit is contained in:
parent
00d9e0c4c8
commit
166d1bc14d
@ -22,7 +22,7 @@ before_install:
|
|||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libpcsclite-dev libxcursor-dev libao-dev libasound2-dev libtasn1-dev nettle-dev ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libpcsclite-dev libxcursor-dev libao-dev libasound2-dev libtasn1-dev nettle-dev libgnutls-dev ; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./bootstrap
|
- ./bootstrap
|
||||||
|
15
configure.ac
15
configure.ac
@ -229,6 +229,21 @@ else
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# GnuTLS
|
||||||
|
if test -n "$PKG_CONFIG"; then
|
||||||
|
PKG_CHECK_MODULES(GNUTLS, gnutls, [HAVE_GNUTLS=1], [HAVE_GNUTLS=0])
|
||||||
|
fi
|
||||||
|
if test x"$HAVE_GNUTLS" = "x1"; then
|
||||||
|
CFLAGS="$CFLAGS $GNUTLS_CFLAGS"
|
||||||
|
LIBS="$LIBS $GNUTLS_LIBS"
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "rdesktop requires GnuTLS. Please install the dependency"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Smartcard support
|
dnl Smartcard support
|
||||||
AC_ARG_ENABLE(smartcard, AS_HELP_STRING([--disable-smartcard], [disable support for smartcard]))
|
AC_ARG_ENABLE(smartcard, AS_HELP_STRING([--disable-smartcard], [disable support for smartcard]))
|
||||||
AS_IF([test "x$enable_smartcard" != "xno"], [
|
AS_IF([test "x$enable_smartcard" != "xno"], [
|
||||||
|
299
tcp.c
299
tcp.c
@ -4,6 +4,7 @@
|
|||||||
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
|
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
|
||||||
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
|
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
|
||||||
Copyright 2012-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
Copyright 2012-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||||
|
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -28,14 +29,18 @@
|
|||||||
#include <netinet/tcp.h> /* TCP_NODELAY */
|
#include <netinet/tcp.h> /* TCP_NODELAY */
|
||||||
#include <arpa/inet.h> /* inet_addr */
|
#include <arpa/inet.h> /* inet_addr */
|
||||||
#include <errno.h> /* errno */
|
#include <errno.h> /* errno */
|
||||||
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <gnutls/gnutls.h>
|
||||||
#include <openssl/x509.h>
|
#include <gnutls/x509.h>
|
||||||
#include <openssl/err.h>
|
|
||||||
|
|
||||||
#include "rdesktop.h"
|
#include "rdesktop.h"
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
|
#include "asn.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CHECK(x) assert((x)>=0)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define socklen_t int
|
#define socklen_t int
|
||||||
@ -66,8 +71,6 @@ struct sockaddr_in *g_server_address = NULL;
|
|||||||
|
|
||||||
static char *g_last_server_name = NULL;
|
static char *g_last_server_name = NULL;
|
||||||
static RD_BOOL g_ssl_initialized = False;
|
static RD_BOOL g_ssl_initialized = False;
|
||||||
static SSL *g_ssl = NULL;
|
|
||||||
static SSL_CTX *g_ssl_ctx = NULL;
|
|
||||||
static int g_sock;
|
static int g_sock;
|
||||||
static RD_BOOL g_run_ui = False;
|
static RD_BOOL g_run_ui = False;
|
||||||
static struct stream g_in;
|
static struct stream g_in;
|
||||||
@ -79,6 +82,8 @@ extern RD_BOOL g_network_error;
|
|||||||
extern RD_BOOL g_reconnect_loop;
|
extern RD_BOOL g_reconnect_loop;
|
||||||
extern char g_tls_version[];
|
extern char g_tls_version[];
|
||||||
|
|
||||||
|
static gnutls_session_t g_tls_session;
|
||||||
|
|
||||||
/* wait till socket is ready to write or timeout */
|
/* wait till socket is ready to write or timeout */
|
||||||
static RD_BOOL
|
static RD_BOOL
|
||||||
tcp_can_send(int sck, int millis)
|
tcp_can_send(int sck, int millis)
|
||||||
@ -123,7 +128,6 @@ tcp_init(uint32 maxlen)
|
|||||||
void
|
void
|
||||||
tcp_send(STREAM s)
|
tcp_send(STREAM s)
|
||||||
{
|
{
|
||||||
int ssl_err;
|
|
||||||
int length = s->end - s->data;
|
int length = s->end - s->data;
|
||||||
int sent, total = 0;
|
int sent, total = 0;
|
||||||
|
|
||||||
@ -133,30 +137,22 @@ tcp_send(STREAM s)
|
|||||||
#ifdef WITH_SCARD
|
#ifdef WITH_SCARD
|
||||||
scard_lock(SCARD_LOCK_TCP);
|
scard_lock(SCARD_LOCK_TCP);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (total < length)
|
while (total < length)
|
||||||
{
|
{
|
||||||
if (g_ssl)
|
if (g_ssl_initialized) {
|
||||||
{
|
sent = gnutls_record_send(g_tls_session, s->data + total, length - total);
|
||||||
sent = SSL_write(g_ssl, s->data + total, length - total);
|
if (sent <= 0) {
|
||||||
if (sent <= 0)
|
if (gnutls_error_is_fatal(sent)) {
|
||||||
{
|
|
||||||
ssl_err = SSL_get_error(g_ssl, sent);
|
|
||||||
if (sent < 0 && (ssl_err == SSL_ERROR_WANT_READ ||
|
|
||||||
ssl_err == SSL_ERROR_WANT_WRITE))
|
|
||||||
{
|
|
||||||
tcp_can_send(g_sock, 100);
|
|
||||||
sent = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef WITH_SCARD
|
#ifdef WITH_SCARD
|
||||||
scard_unlock(SCARD_LOCK_TCP);
|
scard_unlock(SCARD_LOCK_TCP);
|
||||||
#endif
|
#endif
|
||||||
logger(Core, Error,
|
logger(Core, Error, "tcp_send(), gnutls_record_send() failed with %d: %s\n", sent, gnutls_strerror(sent));
|
||||||
"tcp_send(), SSL_write() failed with %d: %s",
|
|
||||||
ssl_err, TCP_STRERROR);
|
|
||||||
g_network_error = True;
|
g_network_error = True;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
tcp_can_send(g_sock, 100);
|
||||||
|
sent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +190,7 @@ STREAM
|
|||||||
tcp_recv(STREAM s, uint32 length)
|
tcp_recv(STREAM s, uint32 length)
|
||||||
{
|
{
|
||||||
uint32 new_length, end_offset, p_offset;
|
uint32 new_length, end_offset, p_offset;
|
||||||
int rcvd = 0, ssl_err;
|
int rcvd = 0;
|
||||||
|
|
||||||
if (g_network_error == True)
|
if (g_network_error == True)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -227,7 +223,8 @@ tcp_recv(STREAM s, uint32 length)
|
|||||||
|
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
{
|
{
|
||||||
if ((!g_ssl || SSL_pending(g_ssl) <= 0) && g_run_ui)
|
|
||||||
|
if ((!g_ssl_initialized || (gnutls_record_check_pending(g_tls_session) <= 0)) && g_run_ui)
|
||||||
{
|
{
|
||||||
ui_select(g_sock);
|
ui_select(g_sock);
|
||||||
|
|
||||||
@ -237,35 +234,17 @@ tcp_recv(STREAM s, uint32 length)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ssl)
|
if (g_ssl_initialized) {
|
||||||
{
|
rcvd = gnutls_record_recv(g_tls_session, s->end, length);
|
||||||
rcvd = SSL_read(g_ssl, s->end, length);
|
|
||||||
ssl_err = SSL_get_error(g_ssl, rcvd);
|
|
||||||
|
|
||||||
if (ssl_err == SSL_ERROR_SSL)
|
if (rcvd < 0) {
|
||||||
{
|
if (gnutls_error_is_fatal(rcvd)) {
|
||||||
if (SSL_get_shutdown(g_ssl) & SSL_RECEIVED_SHUTDOWN)
|
logger(Core, Error, "tcp_recv(), gnutls_record_recv() failed with %d: %s\n", rcvd, gnutls_strerror(rcvd));
|
||||||
{
|
|
||||||
logger(Core, Error,
|
|
||||||
"tcp_recv(), remote peer initiated ssl shutdown");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rdssl_log_ssl_errors("tcp_recv()");
|
|
||||||
g_network_error = True;
|
g_network_error = True;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)
|
|
||||||
{
|
|
||||||
rcvd = 0;
|
rcvd = 0;
|
||||||
}
|
}
|
||||||
else if (ssl_err != SSL_ERROR_NONE)
|
|
||||||
{
|
|
||||||
logger(Core, Error, "tcp_recv(), SSL_read() failed with %d: %s",
|
|
||||||
ssl_err, TCP_STRERROR);
|
|
||||||
g_network_error = True;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -305,91 +284,75 @@ RD_BOOL
|
|||||||
tcp_tls_connect(void)
|
tcp_tls_connect(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
long options;
|
|
||||||
|
|
||||||
|
int type;
|
||||||
|
int status;
|
||||||
|
gnutls_datum_t out;
|
||||||
|
gnutls_certificate_credentials_t xcred;
|
||||||
|
|
||||||
|
/* Initialize TLS session */
|
||||||
if (!g_ssl_initialized)
|
if (!g_ssl_initialized)
|
||||||
{
|
{
|
||||||
SSL_load_error_strings();
|
gnutls_global_init();
|
||||||
SSL_library_init();
|
CHECK(gnutls_init(&g_tls_session, GNUTLS_CLIENT));
|
||||||
g_ssl_initialized = True;
|
g_ssl_initialized = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create process context */
|
/* It is recommended to use the default priorities */
|
||||||
if (g_ssl_ctx == NULL)
|
CHECK(gnutls_set_default_priority(g_tls_session));
|
||||||
{
|
CHECK(gnutls_certificate_allocate_credentials(&xcred));
|
||||||
|
CHECK(gnutls_credentials_set(g_tls_session, GNUTLS_CRD_CERTIFICATE, xcred));
|
||||||
|
|
||||||
|
#if GNUTLS_VERSION_NUMBER >= 0x030109
|
||||||
|
gnutls_transport_set_int(g_tls_session, g_sock);
|
||||||
|
#else
|
||||||
|
gnutls_transport_set_ptr(g_tls_session, (gnutls_transport_ptr_t)g_sock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GNUTLS_VERSION_NUMBER >= 0x030100
|
||||||
|
gnutls_handshake_set_timeout(g_tls_session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Perform the TLS handshake */
|
||||||
|
do {
|
||||||
|
err = gnutls_handshake(g_tls_session);
|
||||||
|
} while (err < 0 && gnutls_error_is_fatal(err) == 0);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
|
||||||
|
#if GNUTLS_VERSION_NUMBER >= 0x030406
|
||||||
|
if (err == GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR) {
|
||||||
|
/* check certificate verification status */
|
||||||
|
type = gnutls_certificate_type_get(g_tls_session);
|
||||||
|
status = gnutls_session_get_verify_cert_status(g_tls_session);
|
||||||
|
CHECK(gnutls_certificate_verification_status_print(status, type, &out, 0));
|
||||||
|
gnutls_free(out.data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const SSL_METHOD *(*tlsmeth) (void) = NULL;
|
|
||||||
if (g_tls_version[0] == 0)
|
|
||||||
tlsmeth = TLSv1_method;
|
|
||||||
else if (!strcmp(g_tls_version, "1.0"))
|
|
||||||
tlsmeth = TLSv1_method;
|
|
||||||
else if (!strcmp(g_tls_version, "1.1"))
|
|
||||||
tlsmeth = TLSv1_1_method;
|
|
||||||
else if (!strcmp(g_tls_version, "1.2"))
|
|
||||||
tlsmeth = TLSv1_2_method;
|
|
||||||
if (tlsmeth == NULL)
|
|
||||||
{
|
|
||||||
logger(Core, Error,
|
|
||||||
"tcp_tls_connect(), TLS method should be 1.0, 1.1, or 1.2\n");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
g_ssl_ctx = SSL_CTX_new(tlsmeth());
|
} else {
|
||||||
if (g_ssl_ctx == NULL)
|
#if GNUTLS_VERSION_NUMBER >= 0x03010a
|
||||||
{
|
char *desc;
|
||||||
logger(Core, Error,
|
desc = gnutls_session_get_desc(g_tls_session);
|
||||||
"tcp_tls_connect(), SSL_CTX_new() failed to create TLS v1.x context\n");
|
logger(Core, Verbose, "TLS Session info: %s\n", desc);
|
||||||
goto fail;
|
gnutls_free(desc);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
options = 0;
|
|
||||||
#ifdef SSL_OP_NO_COMPRESSION
|
|
||||||
options |= SSL_OP_NO_COMPRESSION;
|
|
||||||
#endif // __SSL_OP_NO_COMPRESSION
|
|
||||||
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
|
||||||
SSL_CTX_set_options(g_ssl_ctx, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free old connection */
|
|
||||||
if (g_ssl)
|
|
||||||
SSL_free(g_ssl);
|
|
||||||
|
|
||||||
/* create new ssl connection */
|
|
||||||
g_ssl = SSL_new(g_ssl_ctx);
|
|
||||||
if (g_ssl == NULL)
|
|
||||||
{
|
|
||||||
logger(Core, Error, "tcp_tls_connect(), SSL_new() failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SSL_set_fd(g_ssl, g_sock) < 1)
|
|
||||||
{
|
|
||||||
logger(Core, Error, "tcp_tls_connect(), SSL_set_fd() failed");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
err = SSL_connect(g_ssl);
|
|
||||||
}
|
|
||||||
while (SSL_get_error(g_ssl, err) == SSL_ERROR_WANT_READ);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
rdssl_log_ssl_errors("tcp_tls_connect()");
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (g_ssl)
|
|
||||||
SSL_free(g_ssl);
|
|
||||||
if (g_ssl_ctx)
|
|
||||||
SSL_CTX_free(g_ssl_ctx);
|
|
||||||
|
|
||||||
g_ssl = NULL;
|
if (g_ssl_initialized) {
|
||||||
g_ssl_ctx = NULL;
|
gnutls_deinit(g_tls_session);
|
||||||
|
// Not needed since 3.3.0
|
||||||
|
gnutls_global_deinit();
|
||||||
|
|
||||||
|
g_ssl_initialized = False;
|
||||||
|
}
|
||||||
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,47 +360,85 @@ tcp_tls_connect(void)
|
|||||||
RD_BOOL
|
RD_BOOL
|
||||||
tcp_tls_get_server_pubkey(STREAM s)
|
tcp_tls_get_server_pubkey(STREAM s)
|
||||||
{
|
{
|
||||||
X509 *cert = NULL;
|
int ret;
|
||||||
EVP_PKEY *pkey = NULL;
|
unsigned int list_size;
|
||||||
|
gnutls_datum_t *cert_list;
|
||||||
|
gnutls_x509_crt_t cert;
|
||||||
|
|
||||||
|
unsigned int algo, bits;
|
||||||
|
gnutls_datum_t m, e;
|
||||||
|
|
||||||
|
int pk_size;
|
||||||
|
uint8_t pk_data[1024];
|
||||||
|
|
||||||
s->data = s->p = NULL;
|
s->data = s->p = NULL;
|
||||||
s->size = 0;
|
s->size = 0;
|
||||||
|
|
||||||
if (g_ssl == NULL)
|
cert_list = gnutls_certificate_get_peers(g_tls_session, &list_size);
|
||||||
goto out;
|
|
||||||
|
|
||||||
cert = SSL_get_peer_certificate(g_ssl);
|
if (!cert_list) {
|
||||||
if (cert == NULL)
|
logger(Core, Error, "%s:%s:%d Failed to get peer's certs' list\n", __FILE__, __func__, __LINE__);
|
||||||
{
|
|
||||||
logger(Core, Error,
|
|
||||||
"tcp_tls_get_server_pubkey(), SSL_get_peer_certificate() failed");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkey = X509_get_pubkey(cert);
|
if ((ret = gnutls_x509_crt_init(&cert)) != GNUTLS_E_SUCCESS) {
|
||||||
if (pkey == NULL)
|
logger(Core, Error, "%s:%s:%d Failed to init certificate structure. GnuTLS error: %s\n",
|
||||||
{
|
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||||
logger(Core, Error, "tcp_tls_get_server_pubkey(), X509_get_pubkey() failed");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->size = i2d_PublicKey(pkey, NULL);
|
if ((ret = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)) != GNUTLS_E_SUCCESS) {
|
||||||
if (s->size < 1)
|
logger(Core, Error, "%s:%s:%d Failed to import DER certificate. GnuTLS error:%s\n",
|
||||||
{
|
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||||
logger(Core, Error, "tcp_tls_get_server_pubkey(), i2d_PublicKey() failed");
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
algo = gnutls_x509_crt_get_pk_algorithm(cert, &bits);
|
||||||
|
|
||||||
|
if (algo == GNUTLS_PK_RSA) {
|
||||||
|
if ((ret = gnutls_x509_crt_get_pk_rsa_raw(cert, &m, &e)) != GNUTLS_E_SUCCESS) {
|
||||||
|
logger(Core, Error, "%s:%s:%d Failed to get RSA public key parameters from certificate. GnuTLS error:%s\n",
|
||||||
|
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger(Core, Error, "%s:%s:%d Peer's certificate public key algorithm is not RSA. GnuTLS error:%s\n",
|
||||||
|
__FILE__, __func__, __LINE__, gnutls_strerror(algo));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pk_size = sizeof(pk_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This key will be used further in cssp_connect() for server's key comparison.
|
||||||
|
*
|
||||||
|
* Note that we need to encode this RSA public key into PKCS#1 DER
|
||||||
|
* ATM there's no way to encode/export RSA public key to PKCS#1 using GnuTLS,
|
||||||
|
* gnutls_pubkey_export() encodes into PKCS#8. So besides fixing GnuTLS
|
||||||
|
* we can use libtasn1 for encoding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((ret = write_pkcs1_der_pubkey(&m, &e, pk_data, &pk_size)) != 0) {
|
||||||
|
logger(Core, Error, "%s:%s:%d Failed to encode RSA public key to PKCS#1 DER\n",
|
||||||
|
__FILE__, __func__, __LINE__);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->size = pk_size;
|
||||||
s->data = s->p = xmalloc(s->size);
|
s->data = s->p = xmalloc(s->size);
|
||||||
i2d_PublicKey(pkey, &s->p);
|
memcpy((void *)s->data, (void *)pk_data, pk_size);
|
||||||
s->p = s->data;
|
s->p = s->data;
|
||||||
s->end = s->p + s->size;
|
s->end = s->p + s->size;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (cert)
|
if ((e.size != 0) && (e.data)) {
|
||||||
X509_free(cert);
|
free(e.data);
|
||||||
if (pkey)
|
}
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
|
if ((m.size != 0) && (m.data)) {
|
||||||
|
free(m.data);
|
||||||
|
}
|
||||||
|
|
||||||
return (s->size != 0);
|
return (s->size != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,15 +634,15 @@ void
|
|||||||
tcp_disconnect(void)
|
tcp_disconnect(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int rv;
|
||||||
|
|
||||||
if (g_ssl)
|
if (g_ssl_initialized) {
|
||||||
{
|
rv = gnutls_bye(g_tls_session, GNUTLS_SHUT_WR);
|
||||||
if (!g_network_error)
|
gnutls_deinit(g_tls_session);
|
||||||
(void) SSL_shutdown(g_ssl);
|
// Not needed since 3.3.0
|
||||||
SSL_free(g_ssl);
|
gnutls_global_deinit();
|
||||||
g_ssl = NULL;
|
|
||||||
SSL_CTX_free(g_ssl_ctx);
|
g_ssl_initialized = False;
|
||||||
g_ssl_ctx = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TCP_CLOSE(g_sock);
|
TCP_CLOSE(g_sock);
|
||||||
|
Loading…
Reference in New Issue
Block a user