Commit 25546cf9fceb6a78434e91176c30f4a2cda68cf2
1 parent
4915344f
Exists in
master
and in
3 other branches
Working on SSL error notification dialog.
Showing
3 changed files
with
109 additions
and
80 deletions
Show diff stats
src/include/lib3270-internals.h
| @@ -746,10 +746,21 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | @@ -746,10 +746,21 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | ||
| 746 | const char * description; | 746 | const char * description; |
| 747 | } SSL_ERROR_MESSAGE; | 747 | } SSL_ERROR_MESSAGE; |
| 748 | 748 | ||
| 749 | - LIB3270_INTERNAL int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE *message); | ||
| 750 | - LIB3270_INTERNAL int ssl_init(H3270 *session); | ||
| 751 | - LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); | ||
| 752 | - LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); | 749 | + struct ssl_status_msg |
| 750 | + { | ||
| 751 | + long id; | ||
| 752 | + LIB3270_NOTIFY icon; | ||
| 753 | + const char * iconName; // Icon name from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html | ||
| 754 | + const char * message; | ||
| 755 | + const char * description; | ||
| 756 | + }; | ||
| 757 | + | ||
| 758 | + LIB3270_INTERNAL int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE *message); | ||
| 759 | + LIB3270_INTERNAL int ssl_init(H3270 *session); | ||
| 760 | + LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); | ||
| 761 | + LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); | ||
| 762 | + LIB3270_INTERNAL const struct ssl_status_msg * ssl_get_status_from_error_code(long id); | ||
| 763 | + | ||
| 753 | 764 | ||
| 754 | #if OPENSSL_VERSION_NUMBER >= 0x00907000L | 765 | #if OPENSSL_VERSION_NUMBER >= 0x00907000L |
| 755 | #define INFO_CONST const | 766 | #define INFO_CONST const |
src/ssl/negotiate.c
| @@ -164,69 +164,64 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) | @@ -164,69 +164,64 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) | ||
| 164 | X509 * peer = NULL; | 164 | X509 * peer = NULL; |
| 165 | rv = SSL_get_verify_result(hSession->ssl.con); | 165 | rv = SSL_get_verify_result(hSession->ssl.con); |
| 166 | 166 | ||
| 167 | - switch(rv) | ||
| 168 | - { | ||
| 169 | - // https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_set_error.html | ||
| 170 | - case X509_V_OK: | ||
| 171 | - peer = SSL_get_peer_certificate(hSession->ssl.con); | ||
| 172 | - trace_ssl(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); | ||
| 173 | - break; | 167 | + debug("SSL Verify result was %d", rv); |
| 174 | 168 | ||
| 175 | - case X509_V_ERR_UNABLE_TO_GET_CRL: | 169 | + const struct ssl_status_msg * msg = ssl_get_status_from_error_code((long) rv); |
| 176 | 170 | ||
| 177 | - trace_ssl(hSession,"%s","The CRL of a certificate could not be found.\n" ); | ||
| 178 | - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); | ||
| 179 | - ((SSL_ERROR_MESSAGE *) message)->text = _( "Unable to get certificate CRL." ); | ||
| 180 | - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) of a certificate could not be found." ); | 171 | + if(!msg) |
| 172 | + { | ||
| 173 | + trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); | ||
| 181 | 174 | ||
| 175 | +#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK | ||
| 176 | + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); | ||
| 177 | + ((SSL_ERROR_MESSAGE *) message)->text = _( "Can't verify." ); | ||
| 178 | + ((SSL_ERROR_MESSAGE *) message)->description = _( "Unexpected or invalid TLS/SSL verify result" ); | ||
| 182 | return EACCES; | 179 | return EACCES; |
| 180 | +#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK | ||
| 183 | 181 | ||
| 184 | - case X509_V_ERR_CRL_NOT_YET_VALID: | ||
| 185 | - trace_ssl(hSession,"%s","The CRL of a certificate is not yet valid.\n" ); | 182 | + } |
| 183 | + else | ||
| 184 | + { | ||
| 185 | + switch(rv) | ||
| 186 | + { | ||
| 187 | + case X509_V_OK: | ||
| 188 | + peer = SSL_get_peer_certificate(hSession->ssl.con); | ||
| 189 | + trace_ssl(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); | ||
| 190 | + break; | ||
| 186 | 191 | ||
| 187 | - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); | ||
| 188 | - ((SSL_ERROR_MESSAGE *) message)->text = _( "The CRL is not yet valid." ); | ||
| 189 | - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) is not yet valid." ); | ||
| 190 | - return EACCES; | 192 | + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: |
| 191 | 193 | ||
| 192 | - case X509_V_ERR_CRL_HAS_EXPIRED: | ||
| 193 | - trace_ssl(hSession,"%s","The CRL of a certificate has expired.\n" ); | 194 | + peer = SSL_get_peer_certificate(hSession->ssl.con); |
| 194 | 195 | ||
| 195 | -#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK | ||
| 196 | - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); | ||
| 197 | - ((SSL_ERROR_MESSAGE *) message)->text = _( "The CRL has expired." ); | ||
| 198 | - ((SSL_ERROR_MESSAGE *) message)->description = _( "The Certificate revocation list (CRL) has expired." ); | ||
| 199 | - return EACCES; | ||
| 200 | -#else | ||
| 201 | - break; | ||
| 202 | -#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK | 196 | + trace_ssl(hSession,"TLS/SSL negotiated connection complete with self signed certificate in certificate chain (rc=%d)\n",rv); |
| 203 | 197 | ||
| 204 | - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: | 198 | + #ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK |
| 199 | + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); | ||
| 200 | + ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." ); | ||
| 201 | + ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); | ||
| 202 | + return EACCES; | ||
| 203 | + #else | ||
| 204 | + break; | ||
| 205 | + #endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK | ||
| 205 | 206 | ||
| 206 | - peer = SSL_get_peer_certificate(hSession->ssl.con); | 207 | + default: |
| 208 | + trace_ssl(hSession,"TLS/SSL verify result was %d (%s)\n", rv, msg->description); | ||
| 207 | 209 | ||
| 208 | - debug("%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain" ); | ||
| 209 | - trace_ssl(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" ); | 210 | + debug("message: %s",msg->message); |
| 211 | + debug("description: %s",msg->description); | ||
| 210 | 212 | ||
| 211 | -#ifdef SSL_ENABLE_SELF_SIGNED_CERT_CHECK | ||
| 212 | - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); | ||
| 213 | - ((SSL_ERROR_MESSAGE *) message)->text = _( "The SSL certificate for this host is not trusted." ); | ||
| 214 | - ((SSL_ERROR_MESSAGE *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); | ||
| 215 | - return EACCES; | ||
| 216 | -#else | ||
| 217 | - break; | ||
| 218 | -#endif // SSL_ENABLE_SELF_SIGNED_CERT_CHECK | 213 | + ((SSL_ERROR_MESSAGE *) message)->text = gettext(msg->message); |
| 214 | + ((SSL_ERROR_MESSAGE *) message)->description = gettext(msg->description); | ||
| 219 | 215 | ||
| 220 | - default: | 216 | + if(msg->icon == LIB3270_NOTIFY_ERROR) |
| 217 | + { | ||
| 218 | + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security error" ); | ||
| 219 | + return EACCES; | ||
| 220 | + } | ||
| 221 | 221 | ||
| 222 | - trace_ssl(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); | 222 | + ((SSL_ERROR_MESSAGE *) message)->title = _( "Security warning" ); |
| 223 | 223 | ||
| 224 | -#ifdef SSL_ENABLE_CRL_EXPIRATION_CHECK | ||
| 225 | - ((SSL_ERROR_MESSAGE *) message)->title = _( "SSL error" ); | ||
| 226 | - ((SSL_ERROR_MESSAGE *) message)->text = _( "Can't verify." ); | ||
| 227 | - ((SSL_ERROR_MESSAGE *) message)->description = _( "Unexpected or invalid TLS/SSL verify result" ); | ||
| 228 | - return EACCES; | ||
| 229 | -#endif // SSL_ENABLE_CRL_EXPIRATION_CHECK | 224 | + } |
| 230 | 225 | ||
| 231 | } | 226 | } |
| 232 | 227 | ||
| @@ -277,6 +272,7 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) | @@ -277,6 +272,7 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) | ||
| 277 | return 0; | 272 | return 0; |
| 278 | } | 273 | } |
| 279 | 274 | ||
| 275 | +/* | ||
| 280 | int ssl_negotiate(H3270 *hSession) | 276 | int ssl_negotiate(H3270 *hSession) |
| 281 | { | 277 | { |
| 282 | int rc; | 278 | int rc; |
| @@ -288,9 +284,9 @@ int ssl_negotiate(H3270 *hSession) | @@ -288,9 +284,9 @@ int ssl_negotiate(H3270 *hSession) | ||
| 288 | non_blocking(hSession,False); | 284 | non_blocking(hSession,False); |
| 289 | 285 | ||
| 290 | rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); | 286 | rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); |
| 291 | - if(rc) | 287 | + else if(rc) |
| 292 | { | 288 | { |
| 293 | - // SSL Negotiation has failed. | 289 | + // SSL negotiation has failed. |
| 294 | host_disconnect(hSession,1); // Disconnect with "failed" status. | 290 | host_disconnect(hSession,1); // Disconnect with "failed" status. |
| 295 | 291 | ||
| 296 | if(msg.description) | 292 | if(msg.description) |
| @@ -298,30 +294,26 @@ int ssl_negotiate(H3270 *hSession) | @@ -298,30 +294,26 @@ int ssl_negotiate(H3270 *hSession) | ||
| 298 | else | 294 | else |
| 299 | lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); | 295 | lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); |
| 300 | 296 | ||
| 301 | - | ||
| 302 | - } | ||
| 303 | - else | ||
| 304 | - { | ||
| 305 | - /* Tell the world that we are (still) connected, now in secure mode. */ | ||
| 306 | - lib3270_set_connected_initial(hSession); | ||
| 307 | } | 297 | } |
| 308 | 298 | ||
| 309 | non_blocking(hSession,True); | 299 | non_blocking(hSession,True); |
| 310 | 300 | ||
| 311 | return rc; | 301 | return rc; |
| 312 | } | 302 | } |
| 303 | +*/ | ||
| 313 | 304 | ||
| 314 | -int ssl_init(H3270 *hSession) | 305 | +int ssl_negotiate(H3270 *hSession) |
| 315 | { | 306 | { |
| 316 | - | ||
| 317 | int rc; | 307 | int rc; |
| 318 | SSL_ERROR_MESSAGE msg; | 308 | SSL_ERROR_MESSAGE msg; |
| 319 | 309 | ||
| 320 | memset(&msg,0,sizeof(msg)); | 310 | memset(&msg,0,sizeof(msg)); |
| 321 | 311 | ||
| 312 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | ||
| 322 | non_blocking(hSession,False); | 313 | non_blocking(hSession,False); |
| 323 | 314 | ||
| 324 | - rc = lib3270_run_task(hSession, background_ssl_init, &msg); | 315 | + rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); |
| 316 | + | ||
| 325 | if(rc == EACCES) | 317 | if(rc == EACCES) |
| 326 | { | 318 | { |
| 327 | // SSL validation has failed | 319 | // SSL validation has failed |
| @@ -329,23 +321,52 @@ int ssl_init(H3270 *hSession) | @@ -329,23 +321,52 @@ int ssl_init(H3270 *hSession) | ||
| 329 | int abort = -1; | 321 | int abort = -1; |
| 330 | 322 | ||
| 331 | if(msg.description) | 323 | if(msg.description) |
| 332 | - abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,""); | 324 | + abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,msg.description); |
| 333 | else | 325 | else |
| 334 | abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,ERR_reason_error_string(msg.error)); | 326 | abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,ERR_reason_error_string(msg.error)); |
| 335 | 327 | ||
| 336 | if(abort) | 328 | if(abort) |
| 337 | { | 329 | { |
| 338 | host_disconnect(hSession,1); // Disconnect with "failed" status. | 330 | host_disconnect(hSession,1); // Disconnect with "failed" status. |
| 339 | - } | ||
| 340 | - else | ||
| 341 | - { | ||
| 342 | - rc = 0; | 331 | + return rc; |
| 343 | } | 332 | } |
| 344 | 333 | ||
| 345 | } | 334 | } |
| 346 | else if(rc) | 335 | else if(rc) |
| 347 | { | 336 | { |
| 348 | - // SSL negotiation has failed. | 337 | + // SSL Negotiation has failed. |
| 338 | + host_disconnect(hSession,1); // Disconnect with "failed" status. | ||
| 339 | + | ||
| 340 | + if(msg.description) | ||
| 341 | + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description); | ||
| 342 | + else | ||
| 343 | + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); | ||
| 344 | + | ||
| 345 | + | ||
| 346 | + return rc; | ||
| 347 | + | ||
| 348 | + } | ||
| 349 | + | ||
| 350 | + /* Tell the world that we are (still) connected, now in secure mode. */ | ||
| 351 | + lib3270_set_connected_initial(hSession); | ||
| 352 | + non_blocking(hSession,True); | ||
| 353 | + | ||
| 354 | + return 0; | ||
| 355 | +} | ||
| 356 | + | ||
| 357 | +int ssl_init(H3270 *hSession) { | ||
| 358 | + | ||
| 359 | + int rc; | ||
| 360 | + SSL_ERROR_MESSAGE msg; | ||
| 361 | + | ||
| 362 | + memset(&msg,0,sizeof(msg)); | ||
| 363 | + | ||
| 364 | + non_blocking(hSession,False); | ||
| 365 | + | ||
| 366 | + rc = lib3270_run_task(hSession, background_ssl_init, &msg); | ||
| 367 | + if(rc) | ||
| 368 | + { | ||
| 369 | + // SSL init has failed. | ||
| 349 | host_disconnect(hSession,1); // Disconnect with "failed" status. | 370 | host_disconnect(hSession,1); // Disconnect with "failed" status. |
| 350 | 371 | ||
| 351 | if(msg.description) | 372 | if(msg.description) |
| @@ -361,6 +382,7 @@ int ssl_init(H3270 *hSession) | @@ -361,6 +382,7 @@ int ssl_init(H3270 *hSession) | ||
| 361 | 382 | ||
| 362 | } | 383 | } |
| 363 | 384 | ||
| 385 | + | ||
| 364 | /* Callback for tracing protocol negotiation. */ | 386 | /* Callback for tracing protocol negotiation. */ |
| 365 | void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | 387 | void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) |
| 366 | { | 388 | { |
src/ssl/state.c
| @@ -82,15 +82,7 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | @@ -82,15 +82,7 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | ||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | #ifdef HAVE_LIBSSL | 84 | #ifdef HAVE_LIBSSL |
| 85 | - static const struct ssl_status_msg | ||
| 86 | - { | ||
| 87 | - long id; | ||
| 88 | - LIB3270_NOTIFY icon; | ||
| 89 | - const char * iconName; // Icon name from https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html | ||
| 90 | - const char * message; | ||
| 91 | - const char * description; | ||
| 92 | - } | ||
| 93 | - status_msg[] = | 85 | + static const struct ssl_status_msg status_msg[] = |
| 94 | { | 86 | { |
| 95 | // http://www.openssl.org/docs/apps/verify.html | 87 | // http://www.openssl.org/docs/apps/verify.html |
| 96 | { | 88 | { |
| @@ -354,10 +346,9 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | @@ -354,10 +346,9 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | ||
| 354 | 346 | ||
| 355 | }; | 347 | }; |
| 356 | 348 | ||
| 357 | - static const struct ssl_status_msg * get_ssl_status_msg(H3270 *hSession) | 349 | + const struct ssl_status_msg * ssl_get_status_from_error_code(long id) |
| 358 | { | 350 | { |
| 359 | size_t f; | 351 | size_t f; |
| 360 | - long id = lib3270_get_SSL_verify_result(hSession); | ||
| 361 | 352 | ||
| 362 | for(f=0;f < (sizeof(status_msg)/sizeof(status_msg[0]));f++) | 353 | for(f=0;f < (sizeof(status_msg)/sizeof(status_msg[0]));f++) |
| 363 | { | 354 | { |
| @@ -367,6 +358,11 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | @@ -367,6 +358,11 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | ||
| 367 | return NULL; | 358 | return NULL; |
| 368 | } | 359 | } |
| 369 | 360 | ||
| 361 | + static const struct ssl_status_msg * get_ssl_status_msg(H3270 *hSession) | ||
| 362 | + { | ||
| 363 | + return ssl_get_status_from_error_code(lib3270_get_SSL_verify_result(hSession)); | ||
| 364 | + } | ||
| 365 | + | ||
| 370 | const char * lib3270_get_ssl_state_message(H3270 *hSession) | 366 | const char * lib3270_get_ssl_state_message(H3270 *hSession) |
| 371 | { | 367 | { |
| 372 | if(lib3270_get_secure(hSession) != LIB3270_SSL_UNSECURE) | 368 | if(lib3270_get_secure(hSession) != LIB3270_SSL_UNSECURE) |