diff --git a/src/include/lib3270-internals.h b/src/include/lib3270-internals.h index 3d3aaf4..c1bcbca 100644 --- a/src/include/lib3270-internals.h +++ b/src/include/lib3270-internals.h @@ -746,10 +746,21 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); const char * description; } SSL_ERROR_MESSAGE; - LIB3270_INTERNAL int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE *message); - LIB3270_INTERNAL int ssl_init(H3270 *session); - LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); - LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); + struct ssl_status_msg + { + long id; + LIB3270_NOTIFY icon; + const char * iconName; // Icon name from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html + const char * message; + const char * description; + }; + + LIB3270_INTERNAL int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE *message); + LIB3270_INTERNAL int ssl_init(H3270 *session); + LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); + LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); + LIB3270_INTERNAL const struct ssl_status_msg * ssl_get_status_from_error_code(long id); + #if OPENSSL_VERSION_NUMBER >= 0x00907000L #define INFO_CONST const diff --git a/src/ssl/negotiate.c b/src/ssl/negotiate.c index a1c2962..df22ae6 100644 --- a/src/ssl/negotiate.c +++ b/src/ssl/negotiate.c @@ -164,69 +164,64 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) X509 * peer = NULL; rv = SSL_get_verify_result(hSession->ssl.con); - switch(rv) - { - // https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_set_error.html - case X509_V_OK: - peer = SSL_get_peer_certificate(hSession->ssl.con); - trace_ssl(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); - break; + debug("SSL Verify result was %d", rv); - case X509_V_ERR_UNABLE_TO_GET_CRL: + const struct ssl_status_msg * msg = ssl_get_status_from_error_code((long) rv); - trace_ssl(hSession,"%s","The CRL of a certificate could not be found.\n" ); - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); - ((SSL_ERROR_MESSAGE *) message)->text = _( "Unable to get certificate CRL." ); - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) of a certificate could not be found." ); + if(!msg) + { + trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); +#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); + ((SSL_ERROR_MESSAGE *) message)->text = _( "Can't verify." ); + ((SSL_ERROR_MESSAGE *) message)->description = _( "Unexpected or invalid TLS/SSL verify result" ); return EACCES; +#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK - case X509_V_ERR_CRL_NOT_YET_VALID: - trace_ssl(hSession,"%s","The CRL of a certificate is not yet valid.\n" ); + } + else + { + switch(rv) + { + case X509_V_OK: + peer = SSL_get_peer_certificate(hSession->ssl.con); + trace_ssl(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); + break; - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); - ((SSL_ERROR_MESSAGE *) message)->text = _( "The CRL is not yet valid." ); - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) is not yet valid." ); - return EACCES; + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - case X509_V_ERR_CRL_HAS_EXPIRED: - trace_ssl(hSession,"%s","The CRL of a certificate has expired.\n" ); + peer = SSL_get_peer_certificate(hSession->ssl.con); -#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); - ((SSL_ERROR_MESSAGE *) message)->text = _( "The CRL has expired." ); - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) has expired." ); - return EACCES; -#else - break; -#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK + trace_ssl(hSession,"TLS/SSL negotiated connection complete with self signed certificate in certificate chain (rc=%d)\n",rv); - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + #ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); + ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." ); + ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); + return EACCES; + #else + break; + #endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK - peer = SSL_get_peer_certificate(hSession->ssl.con); + default: + trace_ssl(hSession,"TLS/SSL verify result was %d (%s)\n", rv, msg->description); - debug("%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain" ); - trace_ssl(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" ); + debug("message: %s",msg->message); + debug("description: %s",msg->description); -#ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); - ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." ); - ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); - return EACCES; -#else - break; -#endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK + ((SSL_ERROR_MESSAGE *) message)->text = gettext(msg->message); + ((SSL_ERROR_MESSAGE *) message)->description = gettext(msg->description); - default: + if(msg->icon == LIB3270_NOTIFY_ERROR) + { + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); + return EACCES; + } - trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security warning" ); -#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); - ((SSL_ERROR_MESSAGE *) message)->text = _( "Can't verify." ); - ((SSL_ERROR_MESSAGE *) message)->description = _( "Unexpected or invalid TLS/SSL verify result" ); - return EACCES; -#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK + } } @@ -277,6 +272,7 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) return 0; } +/* int ssl_negotiate(H3270 *hSession) { int rc; @@ -288,9 +284,9 @@ int ssl_negotiate(H3270 *hSession) non_blocking(hSession,False); rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); - if(rc) + else if(rc) { - // SSL Negotiation has failed. + // SSL negotiation has failed. host_disconnect(hSession,1); // Disconnect with "failed" status. if(msg.description) @@ -298,30 +294,26 @@ int ssl_negotiate(H3270 *hSession) else lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); - - } - else - { - /* Tell the world that we are (still) connected, now in secure mode. */ - lib3270_set_connected_initial(hSession); } non_blocking(hSession,True); return rc; } +*/ -int ssl_init(H3270 *hSession) +int ssl_negotiate(H3270 *hSession) { - int rc; SSL_ERROR_MESSAGE msg; memset(&msg,0,sizeof(msg)); + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); non_blocking(hSession,False); - rc = lib3270_run_task(hSession, background_ssl_init, &msg); + rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); + if(rc == EACCES) { // SSL validation has failed @@ -329,23 +321,52 @@ int ssl_init(H3270 *hSession) int abort = -1; if(msg.description) - abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,""); + abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,msg.description); else abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,ERR_reason_error_string(msg.error)); if(abort) { host_disconnect(hSession,1); // Disconnect with "failed" status. - } - else - { - rc = 0; + return rc; } } else if(rc) { - // SSL negotiation has failed. + // SSL Negotiation has failed. + host_disconnect(hSession,1); // Disconnect with "failed" status. + + if(msg.description) + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description); + else + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); + + + return rc; + + } + + /* Tell the world that we are (still) connected, now in secure mode. */ + lib3270_set_connected_initial(hSession); + non_blocking(hSession,True); + + return 0; +} + +int ssl_init(H3270 *hSession) { + + int rc; + SSL_ERROR_MESSAGE msg; + + memset(&msg,0,sizeof(msg)); + + non_blocking(hSession,False); + + rc = lib3270_run_task(hSession, background_ssl_init, &msg); + if(rc) + { + // SSL init has failed. host_disconnect(hSession,1); // Disconnect with "failed" status. if(msg.description) @@ -361,6 +382,7 @@ int ssl_init(H3270 *hSession) } + /* Callback for tracing protocol negotiation. */ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) { diff --git a/src/ssl/state.c b/src/ssl/state.c index 69a6311..13a73e5 100644 --- a/src/ssl/state.c +++ b/src/ssl/state.c @@ -82,15 +82,7 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) } #ifdef HAVE_LIBSSL - static const struct ssl_status_msg - { - long id; - LIB3270_NOTIFY icon; - const char * iconName; // Icon name from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html - const char * message; - const char * description; - } - status_msg[] = + static const struct ssl_status_msg status_msg[] = { // http://www.openssl.org/docs/apps/verify.html { @@ -354,10 +346,9 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) }; - static const struct ssl_status_msg * get_ssl_status_msg(H3270 *hSession) + const struct ssl_status_msg * ssl_get_status_from_error_code(long id) { size_t f; - long id = lib3270_get_SSL_verify_result(hSession); for(f=0;f < (sizeof(status_msg)/sizeof(status_msg[0]));f++) { @@ -367,6 +358,11 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) return NULL; } + static const struct ssl_status_msg * get_ssl_status_msg(H3270 *hSession) + { + return ssl_get_status_from_error_code(lib3270_get_SSL_verify_result(hSession)); + } + const char * lib3270_get_ssl_state_message(H3270 *hSession) { if(lib3270_get_secure(hSession) != LIB3270_SSL_UNSECURE) -- libgit2 0.21.2