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 | 746 | const char * description; |
| 747 | 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 | 765 | #if OPENSSL_VERSION_NUMBER >= 0x00907000L |
| 755 | 766 | #define INFO_CONST const | ... | ... |
src/ssl/negotiate.c
| ... | ... | @@ -164,69 +164,64 @@ static int background_ssl_negotiation(H3270 *hSession, void *message) |
| 164 | 164 | X509 * peer = NULL; |
| 165 | 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 | 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 | 272 | return 0; |
| 278 | 273 | } |
| 279 | 274 | |
| 275 | +/* | |
| 280 | 276 | int ssl_negotiate(H3270 *hSession) |
| 281 | 277 | { |
| 282 | 278 | int rc; |
| ... | ... | @@ -288,9 +284,9 @@ int ssl_negotiate(H3270 *hSession) |
| 288 | 284 | non_blocking(hSession,False); |
| 289 | 285 | |
| 290 | 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 | 290 | host_disconnect(hSession,1); // Disconnect with "failed" status. |
| 295 | 291 | |
| 296 | 292 | if(msg.description) |
| ... | ... | @@ -298,30 +294,26 @@ int ssl_negotiate(H3270 *hSession) |
| 298 | 294 | else |
| 299 | 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 | 299 | non_blocking(hSession,True); |
| 310 | 300 | |
| 311 | 301 | return rc; |
| 312 | 302 | } |
| 303 | +*/ | |
| 313 | 304 | |
| 314 | -int ssl_init(H3270 *hSession) | |
| 305 | +int ssl_negotiate(H3270 *hSession) | |
| 315 | 306 | { |
| 316 | - | |
| 317 | 307 | int rc; |
| 318 | 308 | SSL_ERROR_MESSAGE msg; |
| 319 | 309 | |
| 320 | 310 | memset(&msg,0,sizeof(msg)); |
| 321 | 311 | |
| 312 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | |
| 322 | 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 | 317 | if(rc == EACCES) |
| 326 | 318 | { |
| 327 | 319 | // SSL validation has failed |
| ... | ... | @@ -329,23 +321,52 @@ int ssl_init(H3270 *hSession) |
| 329 | 321 | int abort = -1; |
| 330 | 322 | |
| 331 | 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 | 325 | else |
| 334 | 326 | abort = hSession->cbk.popup_ssl_error(hSession,rc,msg.title,msg.text,ERR_reason_error_string(msg.error)); |
| 335 | 327 | |
| 336 | 328 | if(abort) |
| 337 | 329 | { |
| 338 | 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 | 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 | 370 | host_disconnect(hSession,1); // Disconnect with "failed" status. |
| 350 | 371 | |
| 351 | 372 | if(msg.description) |
| ... | ... | @@ -361,6 +382,7 @@ int ssl_init(H3270 *hSession) |
| 361 | 382 | |
| 362 | 383 | } |
| 363 | 384 | |
| 385 | + | |
| 364 | 386 | /* Callback for tracing protocol negotiation. */ |
| 365 | 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 | 82 | } |
| 83 | 83 | |
| 84 | 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 | 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 | 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 | 351 | size_t f; |
| 360 | - long id = lib3270_get_SSL_verify_result(hSession); | |
| 361 | 352 | |
| 362 | 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 | 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 | 366 | const char * lib3270_get_ssl_state_message(H3270 *hSession) |
| 371 | 367 | { |
| 372 | 368 | if(lib3270_get_secure(hSession) != LIB3270_SSL_UNSECURE) | ... | ... |