From 5f352dbad225e9e417112c354176607d8a49a672 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 25 Jul 2019 11:08:15 -0300 Subject: [PATCH] Adding callback to let the application (or user) to decide if the connection will continue on SSL error. --- lib3270.cbp | 1 - src/core/connect.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- src/core/session.c | 7 +++++++ src/include/lib3270-internals.h | 1 - src/include/lib3270/session.h | 1 + src/ssl/ctx_init.c | 86 ++------------------------------------------------------------------------------------ src/testprogram/testprogram.c | 3 ++- 7 files changed, 132 insertions(+), 119 deletions(-) diff --git a/lib3270.cbp b/lib3270.cbp index 689ea9b..048a21b 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -194,7 +194,6 @@ - diff --git a/src/core/connect.c b/src/core/connect.c index bdba32a..ba83ab1 100644 --- a/src/core/connect.c +++ b/src/core/connect.c @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(HAVE_LIBSSL) #include @@ -54,10 +55,123 @@ } #ifdef SSL_ENABLE_CRL_CHECK -static int background_ssl_crl_check(H3270 *hSession, void *ssl_error) +static int background_ssl_crl_get(H3270 *hSession, void *ssl_error) { - return lib3270_check_X509_crl(hSession, (SSL_ERROR_MESSAGE *) ssl_error); + if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error)) { + return -1; + } + + // Do I have X509 CRL? + if(hSession->ssl.crl.cert) + { + // Ok, have it. Is it valid? + + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c + // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0 + #if OPENSSL_VERSION_NUMBER < 0x10100000L + const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert); + #else + const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert); + #endif + + if(X509_cmp_current_time(next_update) == 1) + { + int day, sec; + if(ASN1_TIME_diff(&day, &sec, NULL, next_update)) + { + trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec); + return 0; + } + else + { + trace_ssl(hSession,"Can't get CRL next update, releasing it\n"); + } + + } + else + { + trace_ssl(hSession,"CRL Certificate is no longer valid\n"); + } + + // Certificate is no longer valid, release it. + X509_CRL_free(hSession->ssl.crl.cert); + hSession->ssl.crl.cert = NULL; + + } + + // + // Get CRL + // + // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session + // + trace_ssl(hSession,"Getting CRL from %s\n",lib3270_get_crl_url(hSession)); + + hSession->ssl.crl.cert = lib3270_get_crl(hSession,(SSL_ERROR_MESSAGE *) ssl_error,lib3270_get_crl_url(hSession)); + if(hSession->ssl.crl.cert) + { + // Got CRL, add it to ssl store + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) + { + lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession); + + if(text) + trace_ssl(hSession,"\n%s\n",text); + + } + + // Add CRL in the store. + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); + if(X509_STORE_add_crl(store, hSession->ssl.crl.cert)) + { + trace_ssl(hSession,"CRL was added to cert store\n"); + } + else + { + trace_ssl(hSession,"CRL was not added to cert store\n"); + } + + + } + + return 0; + } + +static int notify_crl_error(H3270 *hSession, int rc, const SSL_ERROR_MESSAGE *message) +{ + lib3270_write_log( + hSession, + "SSL-CRL-GET", + "CRL GET error: %s (rc=%d ssl_error=%d)", + message->title, + rc, + message->error + ); + + if(message->description) + { + lib3270_write_log(hSession,"SSL-CRL-GET","%s",message->description); + + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,message->description)) + return rc; + } + else if(message->error) + { + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf(_( "%s (SSL error %d)" ),ERR_reason_error_string(message->error),message->error); + lib3270_write_log(hSession,"SSL-CRL-GET","%s",formatted_error); + + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,formatted_error)) + return rc; + } + else + { + if(hSession->cbk.popup_ssl_error(hSession,rc,message->title,message->text,"")) + return rc; + } + + return 0; +} + #endif // SSL_ENABLE_CRL_CHECK int lib3270_reconnect(H3270 *hSession, int seconds) @@ -93,44 +207,18 @@ static int background_ssl_crl_check(H3270 *hSession, void *ssl_error) } #ifdef SSL_ENABLE_CRL_CHECK + SSL_ERROR_MESSAGE ssl_error; memset(&ssl_error,0,sizeof(ssl_error)); set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); - int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error); + int rc = lib3270_run_task(hSession, background_ssl_crl_get, &ssl_error); debug("CRL check returns %d",rc); - if(rc) - { - lib3270_write_log( - hSession, - "SSL-CRL-CHECK", - "CRL Check error: %s (rc=%d ssl_error=%d)", - ssl_error.title, - rc, - ssl_error.error - ); - - if(ssl_error.description) - { - lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",ssl_error.description); - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description); - } - else if(ssl_error.error) - { - lib3270_autoptr(char) formatted_error = lib3270_strdup_printf("%s (SSL error %d)",ERR_reason_error_string(ssl_error.error),ssl_error.error); - lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",formatted_error); - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", formatted_error); - } - else - { - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s",""); - } - - // return errno = rc; + if(rc && notify_crl_error(hSession, rc,&ssl_error)) + return errno = rc; - } #endif // SSL_ENABLE_CRL_CHECK #if defined(HAVE_LIBSSL) diff --git a/src/core/session.c b/src/core/session.c index 45a4e9e..8df6330 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -224,6 +224,12 @@ static void def_popup(H3270 *session, LIB3270_NOTIFY GNUC_UNUSED(type), const ch #endif // ANDROID } +static int def_popup_ssl_error(H3270 *session, int GNUC_UNUSED(rc), const char *title, const char *summary, const char *body) +{ + lib3270_popup_dialog(session, LIB3270_NOTIFY_ERROR, title, summary, "%s", body); + return -1; +} + static void def_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) { vfprintf(stdout,fmt,args); @@ -287,6 +293,7 @@ void lib3270_reset_callbacks(H3270 *hSession) hSession->cbk.cursor = set_cursor; hSession->cbk.message = message; hSession->cbk.popup = def_popup; + hSession->cbk.popup_ssl_error = def_popup_ssl_error; hSession->cbk.update_ssl = update_ssl; hSession->cbk.display = screen_disp; hSession->cbk.set_width = nop_int; diff --git a/src/include/lib3270-internals.h b/src/include/lib3270-internals.h index 048f69b..3d3aaf4 100644 --- a/src/include/lib3270-internals.h +++ b/src/include/lib3270-internals.h @@ -773,7 +773,6 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); #ifdef SSL_ENABLE_CRL_CHECK LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url); - LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message); #endif // SSL_ENABLE_CRL_CHECK /// @brief Clear element at adress. diff --git a/src/include/lib3270/session.h b/src/include/lib3270/session.h index 3b4efa1..c20a545 100644 --- a/src/include/lib3270/session.h +++ b/src/include/lib3270/session.h @@ -78,6 +78,7 @@ void (*message)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *text); void (*popup)(H3270 *session, LIB3270_NOTIFY id, const char *title, const char *msg, const char *fmt, va_list); + int (*popup_ssl_error)(H3270 *session, int rc, const char *title, const char *summary, const char *body); #ifdef HAVE_LIBSSL void (*set_peer_certificate)(const X509 *cert); diff --git a/src/ssl/ctx_init.c b/src/ssl/ctx_init.c index f1b4af4..e5601c4 100644 --- a/src/ssl/ctx_init.c +++ b/src/ssl/ctx_init.c @@ -63,8 +63,6 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ -#ifdef SSL_ENABLE_CRL_CHECK - /* #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsequence-point" @@ -101,85 +99,6 @@ static time_t ASN1_GetTimeT(const ASN1_TIME* time) #pragma GCC diagnostic pop */ -int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message) -{ - // Returns if don't have an SSL context. - if(!ssl_ctx) - { - trace("No SSL context %s will return %d",__FUNCTION__,0); - return 0; - } - - // Do I have X509 CRL? Is it valid? - if(hSession->ssl.crl.cert) - { - - // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c - // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0 - #if OPENSSL_VERSION_NUMBER < 0x10100000L - const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(hSession->ssl.crl.cert); - #else - const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(hSession->ssl.crl.cert); - #endif - - if(X509_cmp_current_time(next_update) == 1) - { - int day, sec; - if(ASN1_TIME_diff(&day, &sec, NULL, next_update)) - { - trace_ssl(hSession,"CRL Certificate is valid for %d day(s) and %d second(s)\n",day,sec); - return 0; - } - else - { - trace_ssl(hSession,"Can't get CRL next update\n"); - } - - } - - // Certificate is no longer valid, release it. - trace_ssl(hSession,"CRL Certificate is no longer valid\n"); - - X509_CRL_free(hSession->ssl.crl.cert); - hSession->ssl.crl.cert = NULL; - - } - - // - // Set up CRL validation - // - // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session - // - hSession->ssl.crl.cert = lib3270_get_crl(hSession,message,lib3270_get_crl_url(hSession)); - if(!hSession->ssl.crl.cert) - { - return -1; - } - - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) - { - lib3270_autoptr(char) text = lib3270_get_ssl_crl_text(hSession); - - if(text) - trace_ssl(hSession,"\n%s\n",text); - - } - - // Add CRL in the store. - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); - if(X509_STORE_add_crl(store, hSession->ssl.crl.cert)) - { - trace_ssl(hSession,"CRL was added to cert store\n"); - return 0; - } - - trace_ssl(hSession,"CRL was not added to cert store\n"); - - return -1; -} -#endif // SSL_ENABLE_CRL_CHECK - - /** * @brief Initialize openssl library. * @@ -251,11 +170,10 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) X509_VERIFY_PARAM_free(param); trace_ssl(hSession,"CRL CHECK was enabled\n"); - return lib3270_check_X509_crl(hSession,message); -#else - return 0; #endif // SSL_ENABLE_CRL_CHECK + return 0; + } #endif // HAVE_LIBSSL diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index 0fa2c0f..f493304 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -12,7 +13,7 @@ const char *trace_file = "test.trace"; -static void write_trace(H3270 *session, void *userdata, const char *fmt, va_list args) +static void write_trace(H3270 GNUC_UNUSED(*session), void GNUC_UNUSED(*userdata), const char *fmt, va_list args) { FILE *out = fopen(trace_file,"a"); if(out) -- libgit2 0.21.2