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