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