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) |