Commit 25546cf9fceb6a78434e91176c30f4a2cda68cf2

Authored by Perry Werneck
1 parent 4915344f

Working on SSL error notification dialog.

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