Commit 2144db0a authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added trace facility for GNUTLS calls

parent da60501b
......@@ -942,13 +942,13 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
fd_log_debug("TLS Session information for connection '%s':\n", conn->cc_id);
/* print the key exchange's algorithm name */
kx = gnutls_kx_get (session);
tmp = gnutls_kx_get_name (kx);
GNUTLS_TRACE( kx = gnutls_kx_get (session) );
GNUTLS_TRACE( tmp = gnutls_kx_get_name (kx) );
fd_log_debug("\t - Key Exchange: %s\n", tmp);
/* Check the authentication type used and switch
* to the appropriate. */
cred = gnutls_auth_get_type (session);
GNUTLS_TRACE( cred = gnutls_auth_get_type (session) );
switch (cred)
{
case GNUTLS_CRD_IA:
......@@ -1031,7 +1031,7 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
return EINVAL;
cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
GNUTLS_TRACE( cert_list = gnutls_certificate_get_peers (session, &cert_list_size) );
if (cert_list == NULL)
return EINVAL;
......@@ -1053,8 +1053,8 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
fd_log_debug(" Certificate %d info:\n", i);
expiration_time = gnutls_x509_crt_get_expiration_time (cert);
activation_time = gnutls_x509_crt_get_activation_time (cert);
GNUTLS_TRACE( expiration_time = gnutls_x509_crt_get_expiration_time (cert) );
GNUTLS_TRACE( activation_time = gnutls_x509_crt_get_activation_time (cert) );
fd_log_debug("\t - Certificate is valid since: %s", ctime (&activation_time));
fd_log_debug("\t - Certificate expires: %s", ctime (&expiration_time));
......@@ -1073,7 +1073,7 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
fd_log_debug("\n");
/* Extract some of the public key algorithm's parameters */
algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
GNUTLS_TRACE( algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits) );
fd_log_debug("\t - Certificate public key: %s\n",
gnutls_pk_algorithm_get_name (algo));
......@@ -1082,14 +1082,14 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
gnutls_x509_crt_get_version (cert));
size = sizeof (dn);
gnutls_x509_crt_get_dn (cert, dn, &size);
GNUTLS_TRACE( gnutls_x509_crt_get_dn (cert, dn, &size) );
fd_log_debug("\t - DN: %s\n", dn);
size = sizeof (dn);
gnutls_x509_crt_get_issuer_dn (cert, dn, &size);
GNUTLS_TRACE( gnutls_x509_crt_get_issuer_dn (cert, dn, &size) );
fd_log_debug("\t - Issuer's DN: %s\n", dn);
gnutls_x509_crt_deinit (cert);
GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) );
}
}
......@@ -1101,7 +1101,7 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return EINVAL);
CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL);
deadline = gnutls_x509_crt_get_expiration_time(cert);
GNUTLS_TRACE( deadline = gnutls_x509_crt_get_expiration_time(cert) );
if ((deadline != (time_t)-1) && (deadline < now)) {
if (TRACE_BOOL(INFO)) {
fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
......@@ -1110,7 +1110,7 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
return EINVAL;
}
deadline = gnutls_x509_crt_get_activation_time(cert);
GNUTLS_TRACE( deadline = gnutls_x509_crt_get_activation_time(cert) );
if ((deadline != (time_t)-1) && (deadline > now)) {
if (TRACE_BOOL(INFO)) {
fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id);
......@@ -1129,7 +1129,7 @@ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, in
}
}
gnutls_x509_crt_deinit (cert);
GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) );
}
return 0;
......@@ -1164,11 +1164,11 @@ int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority, void * alt
#endif /* DISABLE_SCTP */
} else {
/* Set the transport pointer passed to push & pull callbacks */
gnutls_transport_set_ptr( conn->cc_tls_para.session, (gnutls_transport_ptr_t) conn );
GNUTLS_TRACE( gnutls_transport_set_ptr( conn->cc_tls_para.session, (gnutls_transport_ptr_t) conn ) );
/* Set the push and pull callbacks */
gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv);
gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send);
GNUTLS_TRACE( gnutls_transport_set_pull_function(conn->cc_tls_para.session, (void *)fd_cnx_s_recv) );
GNUTLS_TRACE( gnutls_transport_set_push_function(conn->cc_tls_para.session, (void *)fd_cnx_s_send) );
}
/* Mark the connection as protected from here, so that the gnutls credentials will be freed */
......@@ -1221,7 +1221,7 @@ int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsig
/* This function only works for X.509 certificates. */
CHECK_PARAMS( gnutls_certificate_type_get (conn->cc_tls_para.session) == GNUTLS_CRT_X509 );
*cert_list = gnutls_certificate_get_peers (conn->cc_tls_para.session, cert_list_size);
GNUTLS_TRACE( *cert_list = gnutls_certificate_get_peers (conn->cc_tls_para.session, cert_list_size) );
if (*cert_list == NULL) {
TRACE_DEBUG(INFO, "No certificate was provided by remote peer / an error occurred.");
return EINVAL;
......@@ -1406,7 +1406,7 @@ void fd_cnx_destroy(struct cnxctx * conn)
/* Deinit gnutls resources */
fd_sctps_gnutls_deinit_others(conn);
if (conn->cc_tls_para.session) {
gnutls_deinit(conn->cc_tls_para.session);
GNUTLS_TRACE( gnutls_deinit(conn->cc_tls_para.session) );
conn->cc_tls_para.session = NULL;
}
......@@ -1434,7 +1434,7 @@ void fd_cnx_destroy(struct cnxctx * conn)
/* Free the resources of the TLS session */
if (conn->cc_tls_para.session) {
gnutls_deinit(conn->cc_tls_para.session);
GNUTLS_TRACE( gnutls_deinit(conn->cc_tls_para.session) );
conn->cc_tls_para.session = NULL;
}
......
......@@ -74,9 +74,9 @@ int main(int argc, char * argv[])
fd_log_threadname("Main");
/* Initialize gcrypt and gnutls */
(void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
(void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
(void) gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0);
GNUTLS_TRACE( (void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread) );
GNUTLS_TRACE( (void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0) );
GNUTLS_TRACE( (void) gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0) );
CHECK_GNUTLS_DO( gnutls_global_init(), return EINVAL );
if ( ! gnutls_check_version(GNUTLS_VERSION) ) {
fprintf(stderr, "The GNUTLS library is too old; found '%s', need '" GNUTLS_VERSION "'\n", gnutls_check_version(NULL));
......@@ -172,7 +172,7 @@ end:
CHECK_FCT_DO( fd_thr_term(&sig_th), /* reclaim resources of the signal thread */ );
gnutls_global_deinit();
GNUTLS_TRACE( gnutls_global_deinit() );
fd_log_debug(FD_PROJECT_BINARY " daemon is terminated.\n");
return ret;
......
......@@ -211,14 +211,14 @@ static ssize_t sctps_pull(gnutls_transport_ptr_t tr, void * buf, size_t len)
static void set_sess_transport(gnutls_session_t session, struct sctps_ctx *ctx)
{
/* Set the transport pointer passed to push & pull callbacks */
gnutls_transport_set_ptr( session, (gnutls_transport_ptr_t) ctx );
GNUTLS_TRACE( gnutls_transport_set_ptr( session, (gnutls_transport_ptr_t) ctx ) );
/* Reset the low water value, since we don't use sockets */
gnutls_transport_set_lowat( session, 0 );
GNUTLS_TRACE( gnutls_transport_set_lowat( session, 0 ) );
/* Set the push and pull callbacks */
gnutls_transport_set_pull_function(session, sctps_pull);
gnutls_transport_set_push_function(session, sctps_push);
GNUTLS_TRACE( gnutls_transport_set_pull_function(session, sctps_pull) );
GNUTLS_TRACE( gnutls_transport_set_push_function(session, sctps_push) );
return;
}
......@@ -241,9 +241,6 @@ struct sr_data {
gnutls_datum_t data;
};
/* The level at which we debug session resuming */
#define SR_LEVEL (FULL + 1)
/* Initialize the store area for a connection */
static int store_init(struct cnxctx * conn)
{
......@@ -325,10 +322,11 @@ static int sr_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data)
int match = 0;
int ret = 0;
TRACE_DEBUG( GNUTLS_DBG_LEVEL, "Callback: %s", __PRETTY_FUNCTION__ );
CHECK_PARAMS_DO( sto && key.data && data.data, return -1 );
CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 );
TRACE_DEBUG_BUFFER(SR_LEVEL, "Session store [key ", key.data, key.size, "]");
TRACE_DEBUG_BUFFER(GNUTLS_DBG_LEVEL, "Session store [key ", key.data, key.size, "]");
li = find_or_next(sto, key, &match);
if (match) {
......@@ -339,7 +337,7 @@ static int sr_store (void *dbf, gnutls_datum_t key, gnutls_datum_t data)
TRACE_DEBUG(INFO, "GnuTLS tried to store a session with same key and different data!");
ret = -1;
} else {
TRACE_DEBUG(SR_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped.");
TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GnuTLS tried to store a session with same key and same data, skipped.");
}
goto out;
}
......@@ -374,10 +372,11 @@ static int sr_remove (void *dbf, gnutls_datum_t key)
int match = 0;
int ret = 0;
TRACE_DEBUG( GNUTLS_DBG_LEVEL, "Callback: %s", __PRETTY_FUNCTION__ );
CHECK_PARAMS_DO( sto && key.data, return -1 );
CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 );
TRACE_DEBUG_BUFFER(SR_LEVEL, "Session delete [key ", key.data, key.size, "]");
TRACE_DEBUG_BUFFER(GNUTLS_DBG_LEVEL, "Session delete [key ", key.data, key.size, "]");
li = find_or_next(sto, key, &match);
if (match) {
......@@ -406,20 +405,21 @@ static gnutls_datum_t sr_fetch (void *dbf, gnutls_datum_t key)
gnutls_datum_t res = { NULL, 0 };
gnutls_datum_t error = { NULL, 0 };
TRACE_DEBUG( GNUTLS_DBG_LEVEL, "Callback: %s", __PRETTY_FUNCTION__ );
CHECK_PARAMS_DO( sto && key.data, return error );
CHECK_POSIX_DO( pthread_rwlock_rdlock(&sto->lock), return error );
TRACE_DEBUG_BUFFER(SR_LEVEL, "Session fetch [key ", key.data, key.size, "]");
TRACE_DEBUG_BUFFER(GNUTLS_DBG_LEVEL, "Session fetch [key ", key.data, key.size, "]");
li = find_or_next(sto, key, &match);
if (match) {
sr = (struct sr_data *)li;
CHECK_MALLOC_DO(res.data = gnutls_malloc(sr->data.size), goto out );
GNUTLS_TRACE( CHECK_MALLOC_DO(res.data = gnutls_malloc(sr->data.size), goto out ) );
res.size = sr->data.size;
memcpy(res.data, sr->data.data, res.size);
}
out:
TRACE_DEBUG(SR_LEVEL, "Fetched (%p, %d) from store %p", res.data, res.size, sto);
TRACE_DEBUG(GNUTLS_DBG_LEVEL, "Fetched (%p, %d) from store %p", res.data, res.size, sto);
CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return error);
return res;
}
......@@ -429,10 +429,10 @@ static void set_resume_callbacks(gnutls_session_t session, struct cnxctx * conn)
{
TRACE_ENTRY("%p", conn);
gnutls_db_set_retrieve_function(session, sr_fetch);
gnutls_db_set_remove_function (session, sr_remove);
gnutls_db_set_store_function (session, sr_store);
gnutls_db_set_ptr (session, conn->cc_sctps_data.sess_store);
GNUTLS_TRACE( gnutls_db_set_retrieve_function(session, sr_fetch));
GNUTLS_TRACE( gnutls_db_set_remove_function (session, sr_remove));
GNUTLS_TRACE( gnutls_db_set_store_function (session, sr_store));
GNUTLS_TRACE( gnutls_db_set_ptr (session, conn->cc_sctps_data.sess_store));
return;
}
......@@ -455,7 +455,7 @@ static void * handshake_resume_th(void * arg)
TRACE_DEBUG(FULL, "Starting TLS resumed handshake on stream %hu", ctx->strid);
CHECK_GNUTLS_DO( gnutls_handshake( ctx->session ), return NULL);
resumed = gnutls_session_is_resumed(ctx->session);
GNUTLS_TRACE( resumed = gnutls_session_is_resumed(ctx->session) );
if (!resumed) {
/* Check the credentials here also */
CHECK_FCT_DO( fd_tls_verify_credentials(ctx->session, ctx->parent, 0), return NULL );
......@@ -529,11 +529,11 @@ int fd_sctps_handshake_others(struct cnxctx * conn, char * priority, void * alt_
if (conn->cc_tls_para.mode == GNUTLS_CLIENT) {
CHECK_GNUTLS_DO( gnutls_session_get_data2(conn->cc_tls_para.session, &master_data), return ENOMEM );
/* For debug: */
if (TRACE_BOOL(SR_LEVEL)) {
if (TRACE_BOOL(GNUTLS_DBG_LEVEL)) {
uint8_t id[256];
size_t ids = sizeof(id);
CHECK_GNUTLS_DO( gnutls_session_get_id(conn->cc_tls_para.session, id, &ids), /* continue */ );
TRACE_DEBUG_BUFFER(SR_LEVEL, "Master session id: [", id, ids, "]");
TRACE_DEBUG_BUFFER(GNUTLS_DBG_LEVEL, "Master session id: [", id, ids, "]");
}
}
......@@ -558,7 +558,7 @@ int fd_sctps_handshake_others(struct cnxctx * conn, char * priority, void * alt_
/* We can now release the memory of master session data if any */
if (conn->cc_tls_para.mode == GNUTLS_CLIENT) {
gnutls_free(master_data.data);
GNUTLS_TRACE( gnutls_free(master_data.data) );
}
/* Now wait for all handshakes to finish */
......@@ -638,7 +638,7 @@ void fd_sctps_gnutls_deinit_others(struct cnxctx * conn)
for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
if (conn->cc_sctps_data.array[i].session) {
gnutls_deinit(conn->cc_sctps_data.array[i].session);
GNUTLS_TRACE( gnutls_deinit(conn->cc_sctps_data.array[i].session) );
conn->cc_sctps_data.array[i].session = NULL;
}
}
......@@ -678,7 +678,7 @@ void fd_sctps_destroy(struct cnxctx * conn)
fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free );
free(conn->cc_sctps_data.array[i].partial.buf);
if (conn->cc_sctps_data.array[i].session) {
gnutls_deinit(conn->cc_sctps_data.array[i].session);
GNUTLS_TRACE( gnutls_deinit(conn->cc_sctps_data.array[i].session) );
conn->cc_sctps_data.array[i].session = NULL;
}
}
......
......@@ -46,10 +46,15 @@
#define GNUTLS_VERSION LIBGNUTLS_VERSION
#endif /* GNUTLS_VERSION */
/* GNUTLS calls debug level */
#ifndef GNUTLS_DBG_LEVEL
#define GNUTLS_DBG_LEVEL ANNOYING
#endif /* GNUTLS_DBG_LEVEL */
/* Check the return value of a GNUTLS function, log and propagate */
#define CHECK_GNUTLS_DO( __call__, __fallback__ ) { \
int __ret__; \
TRACE_DEBUG_ALL( "Check FCT: " #__call__ ); \
TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: " #__call__ ); \
__ret__ = (__call__); \
if (__ret__ < 0) { \
TRACE_DEBUG(INFO, "Error in '" #__call__ "':\t%s", gnutls_strerror(__ret__)); \
......@@ -57,6 +62,13 @@
} \
}
/* For GNUTLS routines that do not return a value */
#define GNUTLS_TRACE( __call__) { \
TRACE_DEBUG(GNUTLS_DBG_LEVEL, "GNUTLS call: " #__call__ ); \
(__call__); \
}
/* Structure to hold the configuration of the freeDiameter daemon */
struct fd_config {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment