Commit 5da874ff252d453dbbf8f957177438650a97b15c
1 parent
19d4f4f6
Exists in
master
and in
3 other branches
Reorganizing SSL methods.
Showing
15 changed files
with
697 additions
and
582 deletions
Show diff stats
configure.ac
| @@ -332,18 +332,6 @@ if test "$app_cv_self_signed_certs" == "yes"; then | @@ -332,18 +332,6 @@ if test "$app_cv_self_signed_certs" == "yes"; then | ||
| 332 | AC_DEFINE(SSL_ALLOW_SELF_SIGNED_CERT) | 332 | AC_DEFINE(SSL_ALLOW_SELF_SIGNED_CERT) |
| 333 | fi | 333 | fi |
| 334 | 334 | ||
| 335 | -dnl AC_ARG_WITH([ssl-crl-check], | ||
| 336 | -dnl [AS_HELP_STRING([--with-ssl-crl-check], [enable validation of the certificate revogation list in TN3270S connections])], | ||
| 337 | -dnl [ | ||
| 338 | -dnl app_cv_enable_crl_check="$withval" | ||
| 339 | -dnl ],[ | ||
| 340 | -dnl app_cv_enable_crl_check="no" | ||
| 341 | -dnl ]) | ||
| 342 | -dnl | ||
| 343 | -dnl if test "$app_cv_enable_crl_check" == "yes"; then | ||
| 344 | -dnl AC_DEFINE(SSL_ENABLE_CRL_CHECK) | ||
| 345 | -dnl fi | ||
| 346 | - | ||
| 347 | dnl --------------------------------------------------------------------------- | 335 | dnl --------------------------------------------------------------------------- |
| 348 | dnl Check for pic | 336 | dnl Check for pic |
| 349 | dnl --------------------------------------------------------------------------- | 337 | dnl --------------------------------------------------------------------------- |
lib3270.cbp
| @@ -212,6 +212,15 @@ | @@ -212,6 +212,15 @@ | ||
| 212 | <Unit filename="src/lib3270/ssl.c"> | 212 | <Unit filename="src/lib3270/ssl.c"> |
| 213 | <Option compilerVar="CC" /> | 213 | <Option compilerVar="CC" /> |
| 214 | </Unit> | 214 | </Unit> |
| 215 | + <Unit filename="src/lib3270/ssl/init.c"> | ||
| 216 | + <Option compilerVar="CC" /> | ||
| 217 | + </Unit> | ||
| 218 | + <Unit filename="src/lib3270/ssl/negotiate.c"> | ||
| 219 | + <Option compilerVar="CC" /> | ||
| 220 | + </Unit> | ||
| 221 | + <Unit filename="src/lib3270/ssl/state.c"> | ||
| 222 | + <Option compilerVar="CC" /> | ||
| 223 | + </Unit> | ||
| 215 | <Unit filename="src/lib3270/state.c"> | 224 | <Unit filename="src/lib3270/state.c"> |
| 216 | <Option compilerVar="CC" /> | 225 | <Option compilerVar="CC" /> |
| 217 | </Unit> | 226 | </Unit> |
src/include/config.h.in
| @@ -50,7 +50,6 @@ | @@ -50,7 +50,6 @@ | ||
| 50 | #undef HAVE_LDAP | 50 | #undef HAVE_LDAP |
| 51 | #undef HAVE_LIBSSL | 51 | #undef HAVE_LIBSSL |
| 52 | #undef SSL_ALLOW_SELF_SIGNED_CERT | 52 | #undef SSL_ALLOW_SELF_SIGNED_CERT |
| 53 | - #undef SSL_ENABLE_CRL_CHECK | ||
| 54 | 53 | ||
| 55 | /* Windows Options */ | 54 | /* Windows Options */ |
| 56 | #ifdef WIN32 | 55 | #ifdef WIN32 |
src/include/lib3270/macros.h
| @@ -30,7 +30,10 @@ | @@ -30,7 +30,10 @@ | ||
| 30 | * | 30 | * |
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | - #define LIB3270_MACRO( name ) LIB3270_EXPORT char * lib3270_macro_ ## name (H3270 *hSession, int argc, const char **argv) | 33 | + #error Deprecated |
| 34 | 34 | ||
| 35 | - LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv); | 35 | + |
| 36 | + // #define LIB3270_MACRO( name ) LIB3270_EXPORT char * lib3270_macro_ ## name (H3270 *hSession, int argc, const char **argv) | ||
| 37 | + | ||
| 38 | +// LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv); | ||
| 36 | 39 |
src/lib3270/Makefile.in
| @@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@ | @@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@ | ||
| 30 | 30 | ||
| 31 | SOURCES= \ | 31 | SOURCES= \ |
| 32 | $(wildcard *.c) \ | 32 | $(wildcard *.c) \ |
| 33 | + $(wildcard ssl/*.c) \ | ||
| 33 | $(wildcard @OSNAME@/*.c) \ | 34 | $(wildcard @OSNAME@/*.c) \ |
| 34 | $(wildcard @OSNAME@/*.rc) \ | 35 | $(wildcard @OSNAME@/*.rc) \ |
| 35 | $(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c | 36 | $(BASEDIR)/.tmp/$(LIBNAME)/fallbacks.c |
src/lib3270/connect.c
| @@ -129,7 +129,7 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d | @@ -129,7 +129,7 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d | ||
| 129 | hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0); | 129 | hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0); |
| 130 | 130 | ||
| 131 | #if defined(HAVE_LIBSSL) | 131 | #if defined(HAVE_LIBSSL) |
| 132 | - if(hSession->ssl_con && hSession->secure == LIB3270_SSL_UNDEFINED) | 132 | + if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED) |
| 133 | { | 133 | { |
| 134 | if(ssl_negotiate(hSession)) | 134 | if(ssl_negotiate(hSession)) |
| 135 | return; | 135 | return; |
| @@ -333,12 +333,12 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d | @@ -333,12 +333,12 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d | ||
| 333 | #endif | 333 | #endif |
| 334 | 334 | ||
| 335 | hSession->ever_3270 = False; | 335 | hSession->ever_3270 = False; |
| 336 | - hSession->ssl_host = 0; | 336 | + hSession->ssl.host = 0; |
| 337 | 337 | ||
| 338 | if(hSession->options&LIB3270_OPTION_SSL) | 338 | if(hSession->options&LIB3270_OPTION_SSL) |
| 339 | { | 339 | { |
| 340 | #if defined(HAVE_LIBSSL) | 340 | #if defined(HAVE_LIBSSL) |
| 341 | - hSession->ssl_host = 1; | 341 | + hSession->ssl.host = 1; |
| 342 | ssl_init(hSession); | 342 | ssl_init(hSession); |
| 343 | #else | 343 | #else |
| 344 | lib3270_popup_dialog( hSession, | 344 | lib3270_popup_dialog( hSession, |
src/lib3270/host.c
| @@ -144,7 +144,7 @@ void lib3270_set_disconnected(H3270 *hSession) | @@ -144,7 +144,7 @@ void lib3270_set_disconnected(H3270 *hSession) | ||
| 144 | 144 | ||
| 145 | hSession->cstate = LIB3270_NOT_CONNECTED; | 145 | hSession->cstate = LIB3270_NOT_CONNECTED; |
| 146 | hSession->starting = 0; | 146 | hSession->starting = 0; |
| 147 | - hSession->secure = LIB3270_SSL_UNDEFINED; | 147 | + hSession->ssl.state = LIB3270_SSL_UNDEFINED; |
| 148 | 148 | ||
| 149 | set_status(hSession,OIA_FLAG_UNDERA,False); | 149 | set_status(hSession,OIA_FLAG_UNDERA,False); |
| 150 | 150 | ||
| @@ -155,7 +155,7 @@ void lib3270_set_disconnected(H3270 *hSession) | @@ -155,7 +155,7 @@ void lib3270_set_disconnected(H3270 *hSession) | ||
| 155 | if(hSession->cbk.update_connect) | 155 | if(hSession->cbk.update_connect) |
| 156 | hSession->cbk.update_connect(hSession,0); | 156 | hSession->cbk.update_connect(hSession,0); |
| 157 | 157 | ||
| 158 | - hSession->cbk.update_ssl(hSession,hSession->secure); | 158 | + hSession->cbk.update_ssl(hSession,hSession->ssl.state); |
| 159 | 159 | ||
| 160 | } | 160 | } |
| 161 | 161 |
src/lib3270/kybd.c
| @@ -399,7 +399,7 @@ void kybd_inhibit(H3270 *session, Boolean inhibit) | @@ -399,7 +399,7 @@ void kybd_inhibit(H3270 *session, Boolean inhibit) | ||
| 399 | /* | 399 | /* |
| 400 | * Called when a host connects or disconnects. | 400 | * Called when a host connects or disconnects. |
| 401 | */ | 401 | */ |
| 402 | -void kybd_connect(H3270 *session, int connected, void *dunno) | 402 | +void kybd_connect(H3270 *session, int connected, void *dunno unused) |
| 403 | { | 403 | { |
| 404 | if (session->kybdlock & KL_DEFERRED_UNLOCK) | 404 | if (session->kybdlock & KL_DEFERRED_UNLOCK) |
| 405 | RemoveTimeOut(session, session->unlock_id); | 405 | RemoveTimeOut(session, session->unlock_id); |
| @@ -421,7 +421,7 @@ void kybd_connect(H3270 *session, int connected, void *dunno) | @@ -421,7 +421,7 @@ void kybd_connect(H3270 *session, int connected, void *dunno) | ||
| 421 | /* | 421 | /* |
| 422 | * Called when we switch between 3270 and ANSI modes. | 422 | * Called when we switch between 3270 and ANSI modes. |
| 423 | */ | 423 | */ |
| 424 | -void kybd_in3270(H3270 *hSession, int in3270 unused, void *dunno) | 424 | +void kybd_in3270(H3270 *hSession, int in3270 unused, void *dunno unused) |
| 425 | { | 425 | { |
| 426 | if (hSession->kybdlock & KL_DEFERRED_UNLOCK) | 426 | if (hSession->kybdlock & KL_DEFERRED_UNLOCK) |
| 427 | RemoveTimeOut(hSession, hSession->unlock_id); | 427 | RemoveTimeOut(hSession, hSession->unlock_id); |
| @@ -694,7 +694,7 @@ static Boolean ins_prep(H3270 *hSession, int faddr, int baddr, int count) | @@ -694,7 +694,7 @@ static Boolean ins_prep(H3270 *hSession, int faddr, int baddr, int count) | ||
| 694 | #define GE_WFLAG 0x100 | 694 | #define GE_WFLAG 0x100 |
| 695 | #define PASTE_WFLAG 0x200 | 695 | #define PASTE_WFLAG 0x200 |
| 696 | 696 | ||
| 697 | -static void key_Character_wrapper(H3270 *hSession, const char *param1, const char *param2) | 697 | +static void key_Character_wrapper(H3270 *hSession, const char *param1, const char *param2 unused) |
| 698 | { | 698 | { |
| 699 | int code; | 699 | int code; |
| 700 | Boolean with_ge = False; | 700 | Boolean with_ge = False; |
src/lib3270/macros.c
| @@ -30,6 +30,7 @@ | @@ -30,6 +30,7 @@ | ||
| 30 | * | 30 | * |
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | +/* | ||
| 33 | #ifdef WIN32 | 34 | #ifdef WIN32 |
| 34 | #include <winsock2.h> | 35 | #include <winsock2.h> |
| 35 | #include <windows.h> | 36 | #include <windows.h> |
| @@ -46,17 +47,21 @@ | @@ -46,17 +47,21 @@ | ||
| 46 | #include "private.h" | 47 | #include "private.h" |
| 47 | #include "utilc.h" | 48 | #include "utilc.h" |
| 48 | #include "api.h" | 49 | #include "api.h" |
| 50 | + */ | ||
| 49 | 51 | ||
| 50 | /*--[ Structs & Defines ]----------------------------------------------------------------------------*/ | 52 | /*--[ Structs & Defines ]----------------------------------------------------------------------------*/ |
| 51 | 53 | ||
| 54 | +/* | ||
| 52 | struct macro_list | 55 | struct macro_list |
| 53 | { | 56 | { |
| 54 | const char *name; | 57 | const char *name; |
| 55 | char *(*exec)(H3270 *session, int argc, const char **argv); | 58 | char *(*exec)(H3270 *session, int argc, const char **argv); |
| 56 | }; | 59 | }; |
| 60 | +*/ | ||
| 57 | 61 | ||
| 58 | /*--[ Implement ]------------------------------------------------------------------------------------*/ | 62 | /*--[ Implement ]------------------------------------------------------------------------------------*/ |
| 59 | 63 | ||
| 64 | +/* | ||
| 60 | static const char * get_state(H3270 *h) | 65 | static const char * get_state(H3270 *h) |
| 61 | { | 66 | { |
| 62 | #define DECLARE_XLAT_STATE(x) { x, #x } | 67 | #define DECLARE_XLAT_STATE(x) { x, #x } |
| @@ -106,33 +111,6 @@ | @@ -106,33 +111,6 @@ | ||
| 106 | buffer = lib3270_get_string_at_address(hSession,0,-1,'\n'); | 111 | buffer = lib3270_get_string_at_address(hSession,0,-1,'\n'); |
| 107 | break; | 112 | break; |
| 108 | 113 | ||
| 109 | -/* | ||
| 110 | - case 2: // Just size, get current cursor position | ||
| 111 | - start = 0; | ||
| 112 | - qtd = atoi(argv[1]); | ||
| 113 | - break; | ||
| 114 | - | ||
| 115 | - case 3: // Use start position | ||
| 116 | - start = atoi(argv[1]); | ||
| 117 | - qtd = atoi(argv[2]); | ||
| 118 | - break; | ||
| 119 | - | ||
| 120 | - case 4: // Get start position from row/col | ||
| 121 | - lib3270_get_screen_size(hSession,&rows,&cols); | ||
| 122 | - | ||
| 123 | - row = atoi(argv[1])-1; | ||
| 124 | - col = atoi(argv[2])-1; | ||
| 125 | - | ||
| 126 | - if(row < 0 || row > rows || col < 0 || col > cols) | ||
| 127 | - { | ||
| 128 | - errno = EINVAL; | ||
| 129 | - return NULL; | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - start = (row * cols) + col; | ||
| 133 | - qtd = atoi(argv[3]); | ||
| 134 | - break; | ||
| 135 | -*/ | ||
| 136 | default: | 114 | default: |
| 137 | errno = EINVAL; | 115 | errno = EINVAL; |
| 138 | } | 116 | } |
| @@ -317,9 +295,11 @@ | @@ -317,9 +295,11 @@ | ||
| 317 | return strdup(ret); | 295 | return strdup(ret); |
| 318 | 296 | ||
| 319 | } | 297 | } |
| 298 | +*/ | ||
| 320 | 299 | ||
| 321 | /*--[ Macro entry point ]----------------------------------------------------------------------------*/ | 300 | /*--[ Macro entry point ]----------------------------------------------------------------------------*/ |
| 322 | 301 | ||
| 302 | +/* | ||
| 323 | LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv) | 303 | LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv) |
| 324 | { | 304 | { |
| 325 | #define LIB3270_MACRO_ENTRY( name ) { #name, lib3270_macro_ ## name } | 305 | #define LIB3270_MACRO_ENTRY( name ) { #name, lib3270_macro_ ## name } |
| @@ -379,4 +359,4 @@ | @@ -379,4 +359,4 @@ | ||
| 379 | // Not found, return NULL | 359 | // Not found, return NULL |
| 380 | return NULL; | 360 | return NULL; |
| 381 | } | 361 | } |
| 382 | - | 362 | +*/ |
src/lib3270/private.h
| @@ -38,6 +38,10 @@ | @@ -38,6 +38,10 @@ | ||
| 38 | #include <lib3270/charset.h> | 38 | #include <lib3270/charset.h> |
| 39 | #include "api.h" | 39 | #include "api.h" |
| 40 | 40 | ||
| 41 | +#if defined(HAVE_LIBSSL) | ||
| 42 | + #include <openssl/ssl.h> | ||
| 43 | +#endif // HAVE_LIBSSL | ||
| 44 | + | ||
| 41 | #if defined(X3270_TN3270E) && !defined(X3270_ANSI) /*[*/ | 45 | #if defined(X3270_TN3270E) && !defined(X3270_ANSI) /*[*/ |
| 42 | #define X3270_ANSI 1 /* RFC2355 requires NVT mode */ | 46 | #define X3270_ANSI 1 /* RFC2355 requires NVT mode */ |
| 43 | #endif /*]*/ | 47 | #endif /*]*/ |
| @@ -341,8 +345,6 @@ struct _h3270 | @@ -341,8 +345,6 @@ struct _h3270 | ||
| 341 | 345 | ||
| 342 | char * oversize; | 346 | char * oversize; |
| 343 | 347 | ||
| 344 | - LIB3270_SSL_STATE secure; | ||
| 345 | - | ||
| 346 | struct lib3270_toggle | 348 | struct lib3270_toggle |
| 347 | { | 349 | { |
| 348 | char value; /**< toggle value */ | 350 | char value; /**< toggle value */ |
| @@ -406,7 +408,6 @@ struct _h3270 | @@ -406,7 +408,6 @@ struct _h3270 | ||
| 406 | char no_login_host; | 408 | char no_login_host; |
| 407 | char non_tn3270e_host; | 409 | char non_tn3270e_host; |
| 408 | char passthru_host; | 410 | char passthru_host; |
| 409 | - char ssl_host; | ||
| 410 | char ever_3270; | 411 | char ever_3270; |
| 411 | 412 | ||
| 412 | // ctlr.c | 413 | // ctlr.c |
| @@ -602,8 +603,13 @@ struct _h3270 | @@ -602,8 +603,13 @@ struct _h3270 | ||
| 602 | void * ns_exception_id; | 603 | void * ns_exception_id; |
| 603 | 604 | ||
| 604 | // SSL Data (Always defined to maintain the structure size) | 605 | // SSL Data (Always defined to maintain the structure size) |
| 605 | - unsigned long ssl_error; | ||
| 606 | - SSL * ssl_con; | 606 | + struct |
| 607 | + { | ||
| 608 | + char host; | ||
| 609 | + LIB3270_SSL_STATE state; | ||
| 610 | + unsigned long error; | ||
| 611 | + SSL * con; | ||
| 612 | + } ssl; | ||
| 607 | 613 | ||
| 608 | timeout_t * timeouts; | 614 | timeout_t * timeouts; |
| 609 | input_t * inputs; | 615 | input_t * inputs; |
| @@ -649,6 +655,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | @@ -649,6 +655,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | ||
| 649 | 655 | ||
| 650 | #if defined(HAVE_LIBSSL) /*[*/ | 656 | #if defined(HAVE_LIBSSL) /*[*/ |
| 651 | 657 | ||
| 658 | + LIB3270_INTERNAL int ssl_ctx_init(void); | ||
| 652 | LIB3270_INTERNAL int ssl_init(H3270 *session); | 659 | LIB3270_INTERNAL int ssl_init(H3270 *session); |
| 653 | LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); | 660 | LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); |
| 654 | LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); | 661 | LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); |
| @@ -662,5 +669,17 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | @@ -662,5 +669,17 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | ||
| 662 | 669 | ||
| 663 | LIB3270_INTERNAL void ssl_info_callback(INFO_CONST SSL *s, int where, int ret); | 670 | LIB3270_INTERNAL void ssl_info_callback(INFO_CONST SSL *s, int where, int ret); |
| 664 | 671 | ||
| 672 | + /** | ||
| 673 | + * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections. | ||
| 674 | + * | ||
| 675 | + */ | ||
| 676 | + LIB3270_INTERNAL SSL_CTX * ssl_ctx; | ||
| 677 | + | ||
| 678 | + /** | ||
| 679 | + * @brief Index of h3270 handle in SSL session. | ||
| 680 | + * | ||
| 681 | + */ | ||
| 682 | + LIB3270_INTERNAL int ssl_3270_ex_index; | ||
| 683 | + | ||
| 665 | #endif /*]*/ | 684 | #endif /*]*/ |
| 666 | 685 |
src/lib3270/ssl.c
| @@ -1,514 +0,0 @@ | @@ -1,514 +0,0 @@ | ||
| 1 | -/* | ||
| 2 | - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | - * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | - * | ||
| 6 | - * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | - * | ||
| 8 | - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | ||
| 10 | - * Free Software Foundation. | ||
| 11 | - * | ||
| 12 | - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | - * obter mais detalhes. | ||
| 16 | - * | ||
| 17 | - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | - * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | - * | ||
| 21 | - * Este programa está nomeado como ssl.c e possui - linhas de código. | ||
| 22 | - * | ||
| 23 | - * Contatos: | ||
| 24 | - * | ||
| 25 | - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | ||
| 27 | - * licinio@bb.com.br (Licínio Luis Branco) | ||
| 28 | - * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | ||
| 29 | - * | ||
| 30 | - * | ||
| 31 | - * References: | ||
| 32 | - * | ||
| 33 | - * http://www.openssl.org/docs/ssl/ | ||
| 34 | - * | ||
| 35 | - */ | ||
| 36 | - | ||
| 37 | - | ||
| 38 | -#include <config.h> | ||
| 39 | -#if defined(HAVE_LIBSSL) | ||
| 40 | - #include <openssl/ssl.h> | ||
| 41 | - #include <openssl/err.h> | ||
| 42 | - #include <openssl/x509_vfy.h> | ||
| 43 | - | ||
| 44 | - #ifndef SSL_ST_OK | ||
| 45 | - #define SSL_ST_OK 3 | ||
| 46 | - #endif // !SSL_ST_OK | ||
| 47 | - | ||
| 48 | -#endif | ||
| 49 | - | ||
| 50 | -#include "private.h" | ||
| 51 | -#include <errno.h> | ||
| 52 | -#include <lib3270.h> | ||
| 53 | -#include <lib3270/internals.h> | ||
| 54 | -#include <lib3270/trace.h> | ||
| 55 | -#include "trace_dsc.h" | ||
| 56 | - | ||
| 57 | -#if defined(HAVE_LIBSSL) | ||
| 58 | - | ||
| 59 | -static int ssl_3270_ex_index = -1; /**< Index of h3270 handle in SSL session */ | ||
| 60 | -#endif // HAVE_LIBSSL | ||
| 61 | - | ||
| 62 | -/*--[ Implement ]------------------------------------------------------------------------------------*/ | ||
| 63 | - | ||
| 64 | -#if defined(HAVE_LIBSSL) | ||
| 65 | -int ssl_negotiate(H3270 *hSession) | ||
| 66 | -{ | ||
| 67 | - int rv; | ||
| 68 | - | ||
| 69 | - trace("%s",__FUNCTION__); | ||
| 70 | - | ||
| 71 | - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | ||
| 72 | - non_blocking(hSession,False); | ||
| 73 | - | ||
| 74 | - /* Initialize the SSL library. */ | ||
| 75 | - if(ssl_init(hSession)) | ||
| 76 | - { | ||
| 77 | - /* Failed. */ | ||
| 78 | - lib3270_disconnect(hSession); | ||
| 79 | - return -1; | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - /* Set up the TLS/SSL connection. */ | ||
| 83 | - if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1) | ||
| 84 | - { | ||
| 85 | - trace_dsn(hSession,"%s","SSL_set_fd failed!\n"); | ||
| 86 | - | ||
| 87 | - lib3270_popup_dialog( | ||
| 88 | - hSession, | ||
| 89 | - LIB3270_NOTIFY_ERROR, | ||
| 90 | - N_( "Security error" ), | ||
| 91 | - N_( "SSL negotiation failed" ), | ||
| 92 | - "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." ) | ||
| 93 | - ); | ||
| 94 | - | ||
| 95 | - lib3270_disconnect(hSession); | ||
| 96 | - return -1; | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | - trace("%s: Running SSL_connect",__FUNCTION__); | ||
| 100 | - rv = SSL_connect(hSession->ssl_con); | ||
| 101 | - trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv); | ||
| 102 | - | ||
| 103 | - if (rv != 1) | ||
| 104 | - { | ||
| 105 | - int ssl_error = SSL_get_error(hSession->ssl_con,rv); | ||
| 106 | - const char * msg = ""; | ||
| 107 | - | ||
| 108 | - if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl_error) | ||
| 109 | - ssl_error = hSession->ssl_error; | ||
| 110 | - | ||
| 111 | - msg = ERR_lib_error_string(ssl_error); | ||
| 112 | - | ||
| 113 | - trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl_error)); | ||
| 114 | - | ||
| 115 | - lib3270_popup_dialog( | ||
| 116 | - hSession, | ||
| 117 | - LIB3270_NOTIFY_ERROR, | ||
| 118 | - N_( "Security error" ), | ||
| 119 | - N_( "SSL Connect failed" ), | ||
| 120 | - "%s",msg ? msg : "" | ||
| 121 | - ); | ||
| 122 | - | ||
| 123 | - lib3270_disconnect(hSession); | ||
| 124 | - return -1; | ||
| 125 | - } | ||
| 126 | - | ||
| 127 | - /* Success. */ | ||
| 128 | - X509 * peer = NULL; | ||
| 129 | - rv = SSL_get_verify_result(hSession->ssl_con); | ||
| 130 | - | ||
| 131 | - switch(rv) | ||
| 132 | - { | ||
| 133 | - case X509_V_OK: | ||
| 134 | - peer = SSL_get_peer_certificate(hSession->ssl_con); | ||
| 135 | -/* | ||
| 136 | -#if defined(SSL_ENABLE_CRL_CHECK) | ||
| 137 | - trace_dsn(hSession,"TLS/SSL negotiated connection complete with CRL validation. Peer certificate %s presented.\n", peer ? "was" : "was not"); | ||
| 138 | -#else | ||
| 139 | - trace_dsn(hSession,"TLS/SSL negotiated connection complete without CRL validation. Peer certificate %s presented.\n", peer ? "was" : "was not"); | ||
| 140 | -#endif // SSL_ENABLE_CRL_CHECK | ||
| 141 | -*/ | ||
| 142 | - break; | ||
| 143 | - | ||
| 144 | - case X509_V_ERR_UNABLE_TO_GET_CRL: | ||
| 145 | - trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" ); | ||
| 146 | - lib3270_disconnect(hSession); | ||
| 147 | - lib3270_popup_dialog( hSession, | ||
| 148 | - LIB3270_NOTIFY_ERROR, | ||
| 149 | - _( "SSL error" ), | ||
| 150 | - _( "Unable to get certificate CRL." ), | ||
| 151 | - _( "The Certificate revocation list (CRL) of a certificate could not be found." ) | ||
| 152 | - ); | ||
| 153 | - return -1; | ||
| 154 | - | ||
| 155 | - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: | ||
| 156 | - peer = SSL_get_peer_certificate(hSession->ssl_con); | ||
| 157 | - trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" ); | ||
| 158 | - | ||
| 159 | -#ifdef SSL_ALLOW_SELF_SIGNED_CERT | ||
| 160 | - break; | ||
| 161 | -#else | ||
| 162 | - lib3270_disconnect(hSession); | ||
| 163 | - lib3270_popup_dialog( hSession, | ||
| 164 | - LIB3270_NOTIFY_ERROR, | ||
| 165 | - _( "SSL error" ), | ||
| 166 | - _( "The SSL certificate for this host is not trusted." ), | ||
| 167 | - _( "The security certificate presented by this host was not issued by a trusted certificate authority." ) | ||
| 168 | - ); | ||
| 169 | - | ||
| 170 | - return -1; | ||
| 171 | -#endif // SSL_ALLOW_SELF_SIGNED_CERT | ||
| 172 | - | ||
| 173 | - default: | ||
| 174 | - trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | ||
| 178 | - { | ||
| 179 | - char buffer[4096]; | ||
| 180 | - int alg_bits = 0; | ||
| 181 | - const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con); | ||
| 182 | - | ||
| 183 | - trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); | ||
| 184 | - SSL_CIPHER_get_bits(cipher, &alg_bits); | ||
| 185 | - trace_dsn(hSession,"%s version %s with %d bits\n", | ||
| 186 | - SSL_CIPHER_get_name(cipher), | ||
| 187 | - SSL_CIPHER_get_version(cipher), | ||
| 188 | - alg_bits); | ||
| 189 | - } | ||
| 190 | - | ||
| 191 | - | ||
| 192 | - if(peer) | ||
| 193 | - { | ||
| 194 | - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | ||
| 195 | - { | ||
| 196 | - BIO * out = BIO_new(BIO_s_mem()); | ||
| 197 | - unsigned char * data; | ||
| 198 | - unsigned char * text; | ||
| 199 | - int n; | ||
| 200 | - | ||
| 201 | - X509_print(out,peer); | ||
| 202 | - | ||
| 203 | - n = BIO_get_mem_data(out, &data); | ||
| 204 | - text = (unsigned char *) malloc (n+1); | ||
| 205 | - text[n] ='\0'; | ||
| 206 | - memcpy(text,data,n); | ||
| 207 | - | ||
| 208 | - trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text); | ||
| 209 | - | ||
| 210 | - free(text); | ||
| 211 | - BIO_free(out); | ||
| 212 | - | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - hSession->cbk.set_peer_certificate(peer); | ||
| 216 | - | ||
| 217 | - set_ssl_state(hSession,LIB3270_SSL_SECURE); | ||
| 218 | - X509_free(peer); | ||
| 219 | - } | ||
| 220 | - | ||
| 221 | - | ||
| 222 | - /* Tell the world that we are (still) connected, now in secure mode. */ | ||
| 223 | - lib3270_set_connected_initial(hSession); | ||
| 224 | - non_blocking(hSession,True); | ||
| 225 | - | ||
| 226 | - return 0; | ||
| 227 | -} | ||
| 228 | -#endif // HAVE_LIBSSL | ||
| 229 | - | ||
| 230 | -#if defined(HAVE_LIBSSL) /*[*/ | ||
| 231 | - | ||
| 232 | -/** | ||
| 233 | - * Initializa openssl library. | ||
| 234 | - * | ||
| 235 | - * @param hSession lib3270 session handle. | ||
| 236 | - * | ||
| 237 | - * @return 0 if ok, non zero if fails. | ||
| 238 | - * | ||
| 239 | - */ | ||
| 240 | -int ssl_init(H3270 *hSession) | ||
| 241 | -{ | ||
| 242 | - static SSL_CTX *ssl_ctx = NULL; | ||
| 243 | - | ||
| 244 | - hSession->ssl_error = 0; | ||
| 245 | - set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | ||
| 246 | - | ||
| 247 | - if(ssl_ctx == NULL) | ||
| 248 | - { | ||
| 249 | - lib3270_write_log(hSession,"SSL","%s","Initializing SSL context"); | ||
| 250 | - | ||
| 251 | - SSL_load_error_strings(); | ||
| 252 | - SSL_library_init(); | ||
| 253 | - | ||
| 254 | - ssl_ctx = SSL_CTX_new(SSLv23_method()); | ||
| 255 | - if(ssl_ctx == NULL) | ||
| 256 | - { | ||
| 257 | - int ssl_error = ERR_get_error(); | ||
| 258 | - | ||
| 259 | - lib3270_popup_dialog( | ||
| 260 | - hSession, | ||
| 261 | - LIB3270_NOTIFY_ERROR, | ||
| 262 | - N_( "Security error" ), | ||
| 263 | - N_( "SSL_CTX_new() has failed" ), | ||
| 264 | - "%s",ERR_reason_error_string(ssl_error) | ||
| 265 | - ); | ||
| 266 | - | ||
| 267 | - set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | ||
| 268 | - | ||
| 269 | - hSession->ssl_host = False; | ||
| 270 | - return -1; | ||
| 271 | - } | ||
| 272 | - SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); | ||
| 273 | - SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); | ||
| 274 | - SSL_CTX_set_default_verify_paths(ssl_ctx); | ||
| 275 | - | ||
| 276 | -#if defined(_WIN32) | ||
| 277 | - { | ||
| 278 | - HKEY hKey = 0; | ||
| 279 | - | ||
| 280 | - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) | ||
| 281 | - { | ||
| 282 | - char data[4096]; | ||
| 283 | - unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) | ||
| 284 | - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) | ||
| 285 | - | ||
| 286 | - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) | ||
| 287 | - { | ||
| 288 | - strncat(data,"\\certs",4095); | ||
| 289 | - | ||
| 290 | - trace("Loading certs from \"%s\"",data); | ||
| 291 | - if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data)) | ||
| 292 | - { | ||
| 293 | - char buffer[4096]; | ||
| 294 | - int ssl_error = ERR_get_error(); | ||
| 295 | - | ||
| 296 | - snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data); | ||
| 297 | - | ||
| 298 | - lib3270_popup_dialog( | ||
| 299 | - hSession, | ||
| 300 | - LIB3270_NOTIFY_ERROR, | ||
| 301 | - N_( "Security error" ), | ||
| 302 | - buffer, | ||
| 303 | - N_( "%s" ),ERR_lib_error_string(ssl_error) | ||
| 304 | - ); | ||
| 305 | - } | ||
| 306 | - } | ||
| 307 | - RegCloseKey(hKey); | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | - | ||
| 311 | - } | ||
| 312 | -#else | ||
| 313 | - static const char * ssldir[] = | ||
| 314 | - { | ||
| 315 | -#ifdef DATAROOTDIR | ||
| 316 | - DATAROOTDIR "/" PACKAGE_NAME "/certs", | ||
| 317 | -#endif // DATAROOTDIR | ||
| 318 | -#ifdef SYSCONFDIR | ||
| 319 | - SYSCONFDIR "/ssl/certs", | ||
| 320 | - SYSCONFDIR "/certs", | ||
| 321 | -#endif | ||
| 322 | - "/etc/ssl/certs" | ||
| 323 | - }; | ||
| 324 | - | ||
| 325 | - size_t f; | ||
| 326 | - | ||
| 327 | - for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++) | ||
| 328 | - { | ||
| 329 | - if(!access(ssldir[f],R_OK) && SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f])) | ||
| 330 | - { | ||
| 331 | - trace_dsn(hSession,"Checking %s for trusted CA certificates.\n",ssldir[f]); | ||
| 332 | - break; | ||
| 333 | - } | ||
| 334 | - } | ||
| 335 | - | ||
| 336 | -#endif // _WIN32 | ||
| 337 | - | ||
| 338 | -#if defined(SSL_ENABLE_CRL_CHECK) | ||
| 339 | - // Set up CRL validation | ||
| 340 | - // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now | ||
| 341 | - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); | ||
| 342 | - | ||
| 343 | - // Enable CRL checking | ||
| 344 | - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); | ||
| 345 | - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); | ||
| 346 | - X509_STORE_set1_param(store, param); | ||
| 347 | - X509_VERIFY_PARAM_free(param); | ||
| 348 | - | ||
| 349 | - // X509_STORE_free(store); | ||
| 350 | - | ||
| 351 | - trace_dsn(hSession,"CRL CHECK is enabled.\n"); | ||
| 352 | - | ||
| 353 | -#else | ||
| 354 | - | ||
| 355 | - trace_dsn(hSession,"CRL CHECK is disabled.\n"); | ||
| 356 | - | ||
| 357 | -#endif // SSL_ENABLE_CRL_CHECK | ||
| 358 | - | ||
| 359 | - ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); | ||
| 360 | - | ||
| 361 | - | ||
| 362 | - } | ||
| 363 | - | ||
| 364 | - if(hSession->ssl_con) | ||
| 365 | - SSL_free(hSession->ssl_con); | ||
| 366 | - | ||
| 367 | - hSession->ssl_con = SSL_new(ssl_ctx); | ||
| 368 | - if(hSession->ssl_con == NULL) | ||
| 369 | - { | ||
| 370 | - int ssl_error = ERR_get_error(); | ||
| 371 | - | ||
| 372 | - lib3270_popup_dialog( | ||
| 373 | - hSession, | ||
| 374 | - LIB3270_NOTIFY_ERROR, | ||
| 375 | - N_( "Security error" ), | ||
| 376 | - N_( "Cant create a new SSL structure for current connection." ), | ||
| 377 | - N_( "%s" ),ERR_lib_error_string(ssl_error) | ||
| 378 | - ); | ||
| 379 | - | ||
| 380 | - hSession->ssl_host = False; | ||
| 381 | - return -1; | ||
| 382 | - } | ||
| 383 | - | ||
| 384 | - SSL_set_ex_data(hSession->ssl_con,ssl_3270_ex_index,(char *) hSession); | ||
| 385 | - | ||
| 386 | -// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); | ||
| 387 | - SSL_set_verify(hSession->ssl_con, 0, NULL); | ||
| 388 | - | ||
| 389 | - return 0; | ||
| 390 | -} | ||
| 391 | - | ||
| 392 | -/* Callback for tracing protocol negotiation. */ | ||
| 393 | -void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | ||
| 394 | -{ | ||
| 395 | - H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index); | ||
| 396 | - | ||
| 397 | -#ifdef DEBUG | ||
| 398 | - if(hSession != lib3270_get_default_session_handle()) | ||
| 399 | - { | ||
| 400 | - trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle()); | ||
| 401 | - exit(-1); | ||
| 402 | - } | ||
| 403 | -#endif // DEBUG | ||
| 404 | - | ||
| 405 | - switch(where) | ||
| 406 | - { | ||
| 407 | - case SSL_CB_CONNECT_LOOP: | ||
| 408 | - trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s)); | ||
| 409 | - break; | ||
| 410 | - | ||
| 411 | - case SSL_CB_CONNECT_EXIT: | ||
| 412 | - | ||
| 413 | - trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__); | ||
| 414 | - | ||
| 415 | - if (ret == 0) | ||
| 416 | - { | ||
| 417 | - trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s)); | ||
| 418 | - } | ||
| 419 | - else if (ret < 0) | ||
| 420 | - { | ||
| 421 | - unsigned long e = ERR_get_error(); | ||
| 422 | - char err_buf[1024]; | ||
| 423 | - | ||
| 424 | - if(e != 0) | ||
| 425 | - { | ||
| 426 | - hSession->ssl_error = e; | ||
| 427 | - (void) ERR_error_string_n(e, err_buf, 1023); | ||
| 428 | - } | ||
| 429 | -#if defined(_WIN32) | ||
| 430 | - else if (GetLastError() != 0) | ||
| 431 | - { | ||
| 432 | - strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023); | ||
| 433 | - } | ||
| 434 | -#else | ||
| 435 | - else if (errno != 0) | ||
| 436 | - { | ||
| 437 | - strncpy(err_buf, strerror(errno),1023); | ||
| 438 | - } | ||
| 439 | -#endif | ||
| 440 | - else | ||
| 441 | - { | ||
| 442 | - err_buf[0] = '\0'; | ||
| 443 | - } | ||
| 444 | - | ||
| 445 | - trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n", | ||
| 446 | - ret, | ||
| 447 | - err_buf, | ||
| 448 | - SSL_state_string_long(s), | ||
| 449 | - SSL_alert_type_string_long(ret) | ||
| 450 | - ); | ||
| 451 | - | ||
| 452 | - } | ||
| 453 | - | ||
| 454 | - | ||
| 455 | - default: | ||
| 456 | - trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); | ||
| 457 | - } | ||
| 458 | - | ||
| 459 | -#ifdef DEBUG | ||
| 460 | - if(where & SSL_CB_EXIT) | ||
| 461 | - { | ||
| 462 | - trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret); | ||
| 463 | - } | ||
| 464 | -#endif | ||
| 465 | - | ||
| 466 | - if(where & SSL_CB_ALERT) | ||
| 467 | - trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret)); | ||
| 468 | - | ||
| 469 | - if(where & SSL_CB_HANDSHAKE_DONE) | ||
| 470 | - { | ||
| 471 | - trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s)); | ||
| 472 | - if(SSL_get_state(s) == SSL_ST_OK) | ||
| 473 | - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); | ||
| 474 | - else | ||
| 475 | - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | ||
| 476 | - } | ||
| 477 | -} | ||
| 478 | - | ||
| 479 | -#endif /*]*/ | ||
| 480 | - | ||
| 481 | -LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession) | ||
| 482 | -{ | ||
| 483 | - return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE; | ||
| 484 | -} | ||
| 485 | - | ||
| 486 | -LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession) | ||
| 487 | -{ | ||
| 488 | - CHECK_SESSION_HANDLE(hSession); | ||
| 489 | -#if defined(HAVE_LIBSSL) | ||
| 490 | - if(hSession->ssl_con) | ||
| 491 | - return SSL_get_verify_result(hSession->ssl_con); | ||
| 492 | -#endif // HAVE_LIBSSL | ||
| 493 | - return -1; | ||
| 494 | -} | ||
| 495 | - | ||
| 496 | -LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session) | ||
| 497 | -{ | ||
| 498 | - CHECK_SESSION_HANDLE(session); | ||
| 499 | - | ||
| 500 | - return session->secure; | ||
| 501 | -} | ||
| 502 | - | ||
| 503 | -void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state) | ||
| 504 | -{ | ||
| 505 | - CHECK_SESSION_HANDLE(session); | ||
| 506 | - | ||
| 507 | - if(state == session->secure) | ||
| 508 | - return; | ||
| 509 | - | ||
| 510 | - session->secure = state; | ||
| 511 | - trace_dsn(session,"SSL state changes to %d\n",(int) state); | ||
| 512 | - | ||
| 513 | - session->cbk.update_ssl(session,session->secure); | ||
| 514 | -} |
| @@ -0,0 +1,177 @@ | @@ -0,0 +1,177 @@ | ||
| 1 | +/* | ||
| 2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | + * | ||
| 6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | + * | ||
| 8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | ||
| 10 | + * Free Software Foundation. | ||
| 11 | + * | ||
| 12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | + * obter mais detalhes. | ||
| 16 | + * | ||
| 17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | + * | ||
| 21 | + * Este programa está nomeado como ssl.c e possui - linhas de código. | ||
| 22 | + * | ||
| 23 | + * Contatos: | ||
| 24 | + * | ||
| 25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | ||
| 27 | + * licinio@bb.com.br (Licínio Luis Branco) | ||
| 28 | + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | ||
| 29 | + * | ||
| 30 | + * | ||
| 31 | + * References: | ||
| 32 | + * | ||
| 33 | + * http://www.openssl.org/docs/ssl/ | ||
| 34 | + * | ||
| 35 | + */ | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * @brief OpenSSL initialization. | ||
| 39 | + * | ||
| 40 | + */ | ||
| 41 | + | ||
| 42 | +#include <config.h> | ||
| 43 | +#if defined(HAVE_LIBSSL) | ||
| 44 | + | ||
| 45 | +#include <openssl/ssl.h> | ||
| 46 | +#include <openssl/err.h> | ||
| 47 | +#include <openssl/x509_vfy.h> | ||
| 48 | + | ||
| 49 | +#ifndef SSL_ST_OK | ||
| 50 | + #define SSL_ST_OK 3 | ||
| 51 | +#endif // !SSL_ST_OK | ||
| 52 | + | ||
| 53 | +#include "../private.h" | ||
| 54 | +#include <errno.h> | ||
| 55 | +#include <lib3270.h> | ||
| 56 | +#include <lib3270/internals.h> | ||
| 57 | +#include <lib3270/trace.h> | ||
| 58 | +#include "trace_dsc.h" | ||
| 59 | + | ||
| 60 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | ||
| 61 | + | ||
| 62 | +/** | ||
| 63 | + * @brief Initialize openssl library. | ||
| 64 | + * | ||
| 65 | + * @return 0 if ok, non zero if fails. | ||
| 66 | + * | ||
| 67 | + */ | ||
| 68 | +int ssl_ctx_init(void) | ||
| 69 | +{ | ||
| 70 | + debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx); | ||
| 71 | + | ||
| 72 | + if(ssl_ctx != NULL) | ||
| 73 | + return 0; | ||
| 74 | + | ||
| 75 | + SSL_load_error_strings(); | ||
| 76 | + SSL_library_init(); | ||
| 77 | + | ||
| 78 | + ssl_ctx = SSL_CTX_new(SSLv23_method()); | ||
| 79 | + if(ssl_ctx == NULL) | ||
| 80 | + return -1; | ||
| 81 | + | ||
| 82 | + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); | ||
| 83 | + SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); | ||
| 84 | + SSL_CTX_set_default_verify_paths(ssl_ctx); | ||
| 85 | + | ||
| 86 | +#if defined(_WIN32) | ||
| 87 | + { | ||
| 88 | + HKEY hKey = 0; | ||
| 89 | + | ||
| 90 | + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) | ||
| 91 | + { | ||
| 92 | + char data[4096]; | ||
| 93 | + unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) | ||
| 94 | + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) | ||
| 95 | + | ||
| 96 | + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) | ||
| 97 | + { | ||
| 98 | + strncat(data,"\\certs",4095); | ||
| 99 | + | ||
| 100 | + trace("Loading certs from \"%s\"",data); | ||
| 101 | + if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data)) | ||
| 102 | + { | ||
| 103 | + char buffer[4096]; | ||
| 104 | + int ssl_error = ERR_get_error(); | ||
| 105 | + | ||
| 106 | + snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data); | ||
| 107 | + | ||
| 108 | + lib3270_popup_dialog( | ||
| 109 | + hSession, | ||
| 110 | + LIB3270_NOTIFY_ERROR, | ||
| 111 | + N_( "Security error" ), | ||
| 112 | + buffer, | ||
| 113 | + N_( "%s" ),ERR_lib_error_string(ssl_error) | ||
| 114 | + ); | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + RegCloseKey(hKey); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + | ||
| 121 | + } | ||
| 122 | +#else | ||
| 123 | + static const char * ssldir[] = | ||
| 124 | + { | ||
| 125 | +#ifdef DATAROOTDIR | ||
| 126 | + DATAROOTDIR "/" PACKAGE_NAME "/certs", | ||
| 127 | +#endif // DATAROOTDIR | ||
| 128 | +#ifdef SYSCONFDIR | ||
| 129 | + SYSCONFDIR "/ssl/certs", | ||
| 130 | + SYSCONFDIR "/certs", | ||
| 131 | +#endif | ||
| 132 | + "/etc/ssl/certs" | ||
| 133 | + }; | ||
| 134 | + | ||
| 135 | + size_t f; | ||
| 136 | + | ||
| 137 | + for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++) | ||
| 138 | + { | ||
| 139 | + SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | +#endif // _WIN32 | ||
| 143 | + | ||
| 144 | + // | ||
| 145 | + // Initialize CUSTOM CRL CHECK | ||
| 146 | + // | ||
| 147 | + | ||
| 148 | + | ||
| 149 | +/* | ||
| 150 | +#if defined(SSL_ENABLE_CRL_CHECK) | ||
| 151 | + // Set up CRL validation | ||
| 152 | + // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now | ||
| 153 | + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); | ||
| 154 | + | ||
| 155 | + // Enable CRL checking | ||
| 156 | + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); | ||
| 157 | + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); | ||
| 158 | + X509_STORE_set1_param(store, param); | ||
| 159 | + X509_VERIFY_PARAM_free(param); | ||
| 160 | + | ||
| 161 | + // X509_STORE_free(store); | ||
| 162 | + | ||
| 163 | + trace_dsn(hSession,"CRL CHECK is enabled.\n"); | ||
| 164 | + | ||
| 165 | +#else | ||
| 166 | + | ||
| 167 | + trace_dsn(hSession,"CRL CHECK is disabled.\n"); | ||
| 168 | + | ||
| 169 | +#endif // SSL_ENABLE_CRL_CHECK | ||
| 170 | +*/ | ||
| 171 | + | ||
| 172 | + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); | ||
| 173 | + | ||
| 174 | + return 0; | ||
| 175 | +} | ||
| 176 | + | ||
| 177 | +#endif // HAVE_LIBSSL |
| @@ -0,0 +1,378 @@ | @@ -0,0 +1,378 @@ | ||
| 1 | +/* | ||
| 2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | + * | ||
| 6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | + * | ||
| 8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | ||
| 10 | + * Free Software Foundation. | ||
| 11 | + * | ||
| 12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | + * obter mais detalhes. | ||
| 16 | + * | ||
| 17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | + * | ||
| 21 | + * Este programa está nomeado como ssl.c e possui - linhas de código. | ||
| 22 | + * | ||
| 23 | + * Contatos: | ||
| 24 | + * | ||
| 25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | ||
| 27 | + * licinio@bb.com.br (Licínio Luis Branco) | ||
| 28 | + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | ||
| 29 | + * | ||
| 30 | + * | ||
| 31 | + * References: | ||
| 32 | + * | ||
| 33 | + * http://www.openssl.org/docs/ssl/ | ||
| 34 | + * | ||
| 35 | + */ | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +#include <config.h> | ||
| 39 | +#if defined(HAVE_LIBSSL) | ||
| 40 | + #include <openssl/ssl.h> | ||
| 41 | + #include <openssl/err.h> | ||
| 42 | + #include <openssl/x509_vfy.h> | ||
| 43 | + | ||
| 44 | + #ifndef SSL_ST_OK | ||
| 45 | + #define SSL_ST_OK 3 | ||
| 46 | + #endif // !SSL_ST_OK | ||
| 47 | + | ||
| 48 | +#endif | ||
| 49 | + | ||
| 50 | +#include "../private.h" | ||
| 51 | +#include <errno.h> | ||
| 52 | +#include <lib3270.h> | ||
| 53 | +#include <lib3270/internals.h> | ||
| 54 | +#include <lib3270/trace.h> | ||
| 55 | +#include "trace_dsc.h" | ||
| 56 | + | ||
| 57 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | ||
| 58 | + | ||
| 59 | +#if defined(HAVE_LIBSSL) | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * @brief Index of h3270 handle in SSL session. | ||
| 63 | + * | ||
| 64 | + */ | ||
| 65 | + int ssl_3270_ex_index = -1; | ||
| 66 | + | ||
| 67 | +/** | ||
| 68 | + * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections. | ||
| 69 | + * | ||
| 70 | + */ | ||
| 71 | + SSL_CTX * ssl_ctx = NULL; | ||
| 72 | + | ||
| 73 | +/** | ||
| 74 | + * @brief Initialize openssl session. | ||
| 75 | + * | ||
| 76 | + * @param hSession lib3270 session handle. | ||
| 77 | + * | ||
| 78 | + * @return 0 if ok, non zero if fails. | ||
| 79 | + * | ||
| 80 | + */ | ||
| 81 | +int ssl_init(H3270 *hSession) | ||
| 82 | +{ | ||
| 83 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | ||
| 84 | + hSession->ssl.error = 0; | ||
| 85 | + hSession->ssl.host = False; | ||
| 86 | + | ||
| 87 | + if(ssl_ctx_init()) { | ||
| 88 | + | ||
| 89 | + hSession->ssl.error = ERR_get_error(); | ||
| 90 | + | ||
| 91 | + lib3270_popup_dialog( | ||
| 92 | + hSession, | ||
| 93 | + LIB3270_NOTIFY_ERROR, | ||
| 94 | + N_( "Security error" ), | ||
| 95 | + N_( "SSL initialization has failed" ), | ||
| 96 | + "%s",ERR_reason_error_string(hSession->ssl.error) | ||
| 97 | + ); | ||
| 98 | + | ||
| 99 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | ||
| 100 | + | ||
| 101 | + hSession->ssl.host = False; | ||
| 102 | + return -1; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + if(hSession->ssl.con) | ||
| 106 | + SSL_free(hSession->ssl.con); | ||
| 107 | + | ||
| 108 | + hSession->ssl.con = SSL_new(ssl_ctx); | ||
| 109 | + if(hSession->ssl.con == NULL) | ||
| 110 | + { | ||
| 111 | + hSession->ssl.error = ERR_get_error(); | ||
| 112 | + | ||
| 113 | + lib3270_popup_dialog( | ||
| 114 | + hSession, | ||
| 115 | + LIB3270_NOTIFY_ERROR, | ||
| 116 | + N_( "Security error" ), | ||
| 117 | + N_( "Cant create a new SSL structure for current connection." ), | ||
| 118 | + N_( "%s" ),ERR_lib_error_string(hSession->ssl.error) | ||
| 119 | + ); | ||
| 120 | + | ||
| 121 | + return -1; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + SSL_set_ex_data(hSession->ssl.con,ssl_3270_ex_index,(char *) hSession); | ||
| 125 | + | ||
| 126 | +// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); | ||
| 127 | + SSL_set_verify(hSession->ssl.con, 0, NULL); | ||
| 128 | + | ||
| 129 | + return 0; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +int ssl_negotiate(H3270 *hSession) | ||
| 133 | +{ | ||
| 134 | + int rv; | ||
| 135 | + | ||
| 136 | + trace("%s",__FUNCTION__); | ||
| 137 | + | ||
| 138 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | ||
| 139 | + non_blocking(hSession,False); | ||
| 140 | + | ||
| 141 | + /* Initialize the SSL library. */ | ||
| 142 | + if(ssl_init(hSession)) | ||
| 143 | + { | ||
| 144 | + /* Failed. */ | ||
| 145 | + lib3270_disconnect(hSession); | ||
| 146 | + return -1; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + /* Set up the TLS/SSL connection. */ | ||
| 150 | + if(SSL_set_fd(hSession->ssl.con, hSession->sock) != 1) | ||
| 151 | + { | ||
| 152 | + trace_dsn(hSession,"%s","SSL_set_fd failed!\n"); | ||
| 153 | + | ||
| 154 | + lib3270_popup_dialog( | ||
| 155 | + hSession, | ||
| 156 | + LIB3270_NOTIFY_ERROR, | ||
| 157 | + N_( "Security error" ), | ||
| 158 | + N_( "SSL negotiation failed" ), | ||
| 159 | + "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." ) | ||
| 160 | + ); | ||
| 161 | + | ||
| 162 | + lib3270_disconnect(hSession); | ||
| 163 | + return -1; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + trace("%s: Running SSL_connect",__FUNCTION__); | ||
| 167 | + rv = SSL_connect(hSession->ssl.con); | ||
| 168 | + trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv); | ||
| 169 | + | ||
| 170 | + if (rv != 1) | ||
| 171 | + { | ||
| 172 | + int ssl_error = SSL_get_error(hSession->ssl.con,rv); | ||
| 173 | + const char * msg = ""; | ||
| 174 | + | ||
| 175 | + if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl.error) | ||
| 176 | + ssl_error = hSession->ssl.error; | ||
| 177 | + | ||
| 178 | + msg = ERR_lib_error_string(ssl_error); | ||
| 179 | + | ||
| 180 | + trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl.error)); | ||
| 181 | + | ||
| 182 | + lib3270_popup_dialog( | ||
| 183 | + hSession, | ||
| 184 | + LIB3270_NOTIFY_ERROR, | ||
| 185 | + N_( "Security error" ), | ||
| 186 | + N_( "SSL Connect failed" ), | ||
| 187 | + "%s",msg ? msg : "" | ||
| 188 | + ); | ||
| 189 | + | ||
| 190 | + lib3270_disconnect(hSession); | ||
| 191 | + return -1; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + /* Success. */ | ||
| 195 | + X509 * peer = NULL; | ||
| 196 | + rv = SSL_get_verify_result(hSession->ssl.con); | ||
| 197 | + | ||
| 198 | + switch(rv) | ||
| 199 | + { | ||
| 200 | + case X509_V_OK: | ||
| 201 | + peer = SSL_get_peer_certificate(hSession->ssl.con); | ||
| 202 | + trace_dsn(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); | ||
| 203 | + break; | ||
| 204 | + | ||
| 205 | + case X509_V_ERR_UNABLE_TO_GET_CRL: | ||
| 206 | + trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" ); | ||
| 207 | + lib3270_disconnect(hSession); | ||
| 208 | + lib3270_popup_dialog( hSession, | ||
| 209 | + LIB3270_NOTIFY_ERROR, | ||
| 210 | + _( "SSL error" ), | ||
| 211 | + _( "Unable to get certificate CRL." ), | ||
| 212 | + _( "The Certificate revocation list (CRL) of a certificate could not be found." ) | ||
| 213 | + ); | ||
| 214 | + return -1; | ||
| 215 | + | ||
| 216 | + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: | ||
| 217 | + peer = SSL_get_peer_certificate(hSession->ssl.con); | ||
| 218 | + trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" ); | ||
| 219 | + | ||
| 220 | +#ifdef SSL_ALLOW_SELF_SIGNED_CERT | ||
| 221 | + break; | ||
| 222 | +#else | ||
| 223 | + lib3270_disconnect(hSession); | ||
| 224 | + lib3270_popup_dialog( hSession, | ||
| 225 | + LIB3270_NOTIFY_ERROR, | ||
| 226 | + _( "SSL error" ), | ||
| 227 | + _( "The SSL certificate for this host is not trusted." ), | ||
| 228 | + _( "The security certificate presented by this host was not issued by a trusted certificate authority." ) | ||
| 229 | + ); | ||
| 230 | + | ||
| 231 | + return -1; | ||
| 232 | +#endif // SSL_ALLOW_SELF_SIGNED_CERT | ||
| 233 | + | ||
| 234 | + default: | ||
| 235 | + trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | ||
| 239 | + { | ||
| 240 | + char buffer[4096]; | ||
| 241 | + int alg_bits = 0; | ||
| 242 | + const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl.con); | ||
| 243 | + | ||
| 244 | + trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); | ||
| 245 | + SSL_CIPHER_get_bits(cipher, &alg_bits); | ||
| 246 | + trace_dsn(hSession,"%s version %s with %d bits\n", | ||
| 247 | + SSL_CIPHER_get_name(cipher), | ||
| 248 | + SSL_CIPHER_get_version(cipher), | ||
| 249 | + alg_bits); | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + | ||
| 253 | + if(peer) | ||
| 254 | + { | ||
| 255 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | ||
| 256 | + { | ||
| 257 | + BIO * out = BIO_new(BIO_s_mem()); | ||
| 258 | + unsigned char * data; | ||
| 259 | + unsigned char * text; | ||
| 260 | + int n; | ||
| 261 | + | ||
| 262 | + X509_print(out,peer); | ||
| 263 | + | ||
| 264 | + n = BIO_get_mem_data(out, &data); | ||
| 265 | + text = (unsigned char *) malloc (n+1); | ||
| 266 | + text[n] ='\0'; | ||
| 267 | + memcpy(text,data,n); | ||
| 268 | + | ||
| 269 | + trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text); | ||
| 270 | + | ||
| 271 | + free(text); | ||
| 272 | + BIO_free(out); | ||
| 273 | + | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + hSession->cbk.set_peer_certificate(peer); | ||
| 277 | + | ||
| 278 | + set_ssl_state(hSession,LIB3270_SSL_SECURE); | ||
| 279 | + X509_free(peer); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + | ||
| 283 | + /* Tell the world that we are (still) connected, now in secure mode. */ | ||
| 284 | + lib3270_set_connected_initial(hSession); | ||
| 285 | + non_blocking(hSession,True); | ||
| 286 | + | ||
| 287 | + return 0; | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +/* Callback for tracing protocol negotiation. */ | ||
| 291 | +void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | ||
| 292 | +{ | ||
| 293 | + H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index); | ||
| 294 | + | ||
| 295 | +#ifdef DEBUG | ||
| 296 | + if(hSession != lib3270_get_default_session_handle()) | ||
| 297 | + { | ||
| 298 | + trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle()); | ||
| 299 | + exit(-1); | ||
| 300 | + } | ||
| 301 | +#endif // DEBUG | ||
| 302 | + | ||
| 303 | + switch(where) | ||
| 304 | + { | ||
| 305 | + case SSL_CB_CONNECT_LOOP: | ||
| 306 | + trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s)); | ||
| 307 | + break; | ||
| 308 | + | ||
| 309 | + case SSL_CB_CONNECT_EXIT: | ||
| 310 | + | ||
| 311 | + trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__); | ||
| 312 | + | ||
| 313 | + if (ret == 0) | ||
| 314 | + { | ||
| 315 | + trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s)); | ||
| 316 | + } | ||
| 317 | + else if (ret < 0) | ||
| 318 | + { | ||
| 319 | + unsigned long e = ERR_get_error(); | ||
| 320 | + char err_buf[1024]; | ||
| 321 | + | ||
| 322 | + if(e != 0) | ||
| 323 | + { | ||
| 324 | + hSession->ssl.error = e; | ||
| 325 | + (void) ERR_error_string_n(e, err_buf, 1023); | ||
| 326 | + } | ||
| 327 | +#if defined(_WIN32) | ||
| 328 | + else if (GetLastError() != 0) | ||
| 329 | + { | ||
| 330 | + strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023); | ||
| 331 | + } | ||
| 332 | +#else | ||
| 333 | + else if (errno != 0) | ||
| 334 | + { | ||
| 335 | + strncpy(err_buf, strerror(errno),1023); | ||
| 336 | + } | ||
| 337 | +#endif | ||
| 338 | + else | ||
| 339 | + { | ||
| 340 | + err_buf[0] = '\0'; | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n", | ||
| 344 | + ret, | ||
| 345 | + err_buf, | ||
| 346 | + SSL_state_string_long(s), | ||
| 347 | + SSL_alert_type_string_long(ret) | ||
| 348 | + ); | ||
| 349 | + | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + | ||
| 353 | + default: | ||
| 354 | + trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); | ||
| 355 | + } | ||
| 356 | + | ||
| 357 | +#ifdef DEBUG | ||
| 358 | + if(where & SSL_CB_EXIT) | ||
| 359 | + { | ||
| 360 | + trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret); | ||
| 361 | + } | ||
| 362 | +#endif | ||
| 363 | + | ||
| 364 | + if(where & SSL_CB_ALERT) | ||
| 365 | + trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret)); | ||
| 366 | + | ||
| 367 | + if(where & SSL_CB_HANDSHAKE_DONE) | ||
| 368 | + { | ||
| 369 | + trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s)); | ||
| 370 | + if(SSL_get_state(s) == SSL_ST_OK) | ||
| 371 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); | ||
| 372 | + else | ||
| 373 | + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | ||
| 374 | + } | ||
| 375 | +} | ||
| 376 | + | ||
| 377 | +#endif /*]*/ | ||
| 378 | + |
| @@ -0,0 +1,74 @@ | @@ -0,0 +1,74 @@ | ||
| 1 | +/* | ||
| 2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | + * | ||
| 6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | + * | ||
| 8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | ||
| 10 | + * Free Software Foundation. | ||
| 11 | + * | ||
| 12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | + * obter mais detalhes. | ||
| 16 | + * | ||
| 17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | + * | ||
| 21 | + * Este programa está nomeado como - e possui - linhas de código. | ||
| 22 | + * | ||
| 23 | + * Contatos: | ||
| 24 | + * | ||
| 25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | ||
| 27 | + * | ||
| 28 | + */ | ||
| 29 | + | ||
| 30 | +#include <config.h> | ||
| 31 | +#include "../private.h" | ||
| 32 | +#include <errno.h> | ||
| 33 | +#include <lib3270.h> | ||
| 34 | +#include <lib3270/internals.h> | ||
| 35 | +#include <lib3270/trace.h> | ||
| 36 | +#include <trace_dsc.h> | ||
| 37 | + | ||
| 38 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +LIB3270_EXPORT int lib3270_is_secure(H3270 *hSession) | ||
| 41 | +{ | ||
| 42 | + return lib3270_get_secure(hSession) == LIB3270_SSL_SECURE; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +LIB3270_EXPORT long lib3270_get_SSL_verify_result(H3270 *hSession) | ||
| 46 | +{ | ||
| 47 | + CHECK_SESSION_HANDLE(hSession); | ||
| 48 | +#if defined(HAVE_LIBSSL) | ||
| 49 | + if(hSession->ssl.con) | ||
| 50 | + return SSL_get_verify_result(hSession->ssl.con); | ||
| 51 | +#endif // HAVE_LIBSSL | ||
| 52 | + return -1; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *hSession) | ||
| 56 | +{ | ||
| 57 | + CHECK_SESSION_HANDLE(hSession); | ||
| 58 | + return hSession->ssl.state; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | ||
| 62 | +{ | ||
| 63 | + CHECK_SESSION_HANDLE(hSession); | ||
| 64 | + | ||
| 65 | + debug("%s: %d -> %d",__FUNCTION__,hSession->ssl.state,state); | ||
| 66 | + | ||
| 67 | + if(state == hSession->ssl.state) | ||
| 68 | + return; | ||
| 69 | + | ||
| 70 | + hSession->ssl.state = state; | ||
| 71 | + trace_dsn(hSession,"SSL state changes to %d\n",(int) state); | ||
| 72 | + | ||
| 73 | + hSession->cbk.update_ssl(hSession,hSession->ssl.state); | ||
| 74 | +} |
src/lib3270/telnet.c
| @@ -806,11 +806,11 @@ static int net_connected(H3270 *hSession) | @@ -806,11 +806,11 @@ static int net_connected(H3270 *hSession) | ||
| 806 | } | 806 | } |
| 807 | */ | 807 | */ |
| 808 | 808 | ||
| 809 | - trace_dsn(hSession,"Connected to %s%s.\n", hSession->host.current,hSession->ssl_host? " using SSL": ""); | 809 | + trace_dsn(hSession,"Connected to %s%s.\n", hSession->host.current,hSession->ssl.host? " using SSL": ""); |
| 810 | 810 | ||
| 811 | #if defined(HAVE_LIBSSL) | 811 | #if defined(HAVE_LIBSSL) |
| 812 | /* Set up SSL. */ | 812 | /* Set up SSL. */ |
| 813 | - if(hSession->ssl_con && hSession->secure == LIB3270_SSL_UNDEFINED) | 813 | + if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED) |
| 814 | { | 814 | { |
| 815 | if(ssl_negotiate(hSession)) | 815 | if(ssl_negotiate(hSession)) |
| 816 | return -1; | 816 | return -1; |
| @@ -899,11 +899,12 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) | @@ -899,11 +899,12 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) | ||
| 899 | trace("%s",__FUNCTION__); | 899 | trace("%s",__FUNCTION__); |
| 900 | 900 | ||
| 901 | #if defined(HAVE_LIBSSL) | 901 | #if defined(HAVE_LIBSSL) |
| 902 | - if(hSession->ssl_con != NULL) | 902 | + if(hSession->ssl.con != NULL) |
| 903 | { | 903 | { |
| 904 | - SSL_shutdown(hSession->ssl_con); | ||
| 905 | - SSL_free(hSession->ssl_con); | ||
| 906 | - hSession->ssl_con = NULL; | 904 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); |
| 905 | + SSL_shutdown(hSession->ssl.con); | ||
| 906 | + SSL_free(hSession->ssl.con); | ||
| 907 | + hSession->ssl.con = NULL; | ||
| 907 | } | 908 | } |
| 908 | #endif | 909 | #endif |
| 909 | 910 | ||
| @@ -1010,8 +1011,8 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void | @@ -1010,8 +1011,8 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void | ||
| 1010 | #endif | 1011 | #endif |
| 1011 | 1012 | ||
| 1012 | #if defined(HAVE_LIBSSL) | 1013 | #if defined(HAVE_LIBSSL) |
| 1013 | - if (hSession->ssl_con != NULL) | ||
| 1014 | - nr = SSL_read(hSession->ssl_con, (char *) buffer, BUFSZ); | 1014 | + if (hSession->ssl.con != NULL) |
| 1015 | + nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); | ||
| 1015 | else | 1016 | else |
| 1016 | nr = recv(hSession->sock, (char *) buffer, BUFSZ, 0); | 1017 | nr = recv(hSession->sock, (char *) buffer, BUFSZ, 0); |
| 1017 | #else | 1018 | #else |
| @@ -1024,7 +1025,7 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void | @@ -1024,7 +1025,7 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void | ||
| 1024 | return; | 1025 | return; |
| 1025 | 1026 | ||
| 1026 | #if defined(HAVE_LIBSSL) /*[*/ | 1027 | #if defined(HAVE_LIBSSL) /*[*/ |
| 1027 | - if(hSession->ssl_con != NULL) | 1028 | + if(hSession->ssl.con != NULL) |
| 1028 | { | 1029 | { |
| 1029 | unsigned long e; | 1030 | unsigned long e; |
| 1030 | char err_buf[120]; | 1031 | char err_buf[120]; |
| @@ -1991,8 +1992,8 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | @@ -1991,8 +1992,8 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | ||
| 1991 | int rc; | 1992 | int rc; |
| 1992 | 1993 | ||
| 1993 | #if defined(HAVE_LIBSSL) | 1994 | #if defined(HAVE_LIBSSL) |
| 1994 | - if(hSession->ssl_con != NULL) | ||
| 1995 | - rc = SSL_write(hSession->ssl_con, (const char *) buf, len); | 1995 | + if(hSession->ssl.con != NULL) |
| 1996 | + rc = SSL_write(hSession->ssl.con, (const char *) buf, len); | ||
| 1996 | else | 1997 | else |
| 1997 | rc = send(hSession->sock, (const char *) buf, len, 0); | 1998 | rc = send(hSession->sock, (const char *) buf, len, 0); |
| 1998 | #else | 1999 | #else |
| @@ -2005,7 +2006,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | @@ -2005,7 +2006,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | ||
| 2005 | // Recv error, notify | 2006 | // Recv error, notify |
| 2006 | 2007 | ||
| 2007 | #if defined(HAVE_LIBSSL) | 2008 | #if defined(HAVE_LIBSSL) |
| 2008 | - if(hSession->ssl_con != NULL) | 2009 | + if(hSession->ssl.con != NULL) |
| 2009 | { | 2010 | { |
| 2010 | unsigned long e; | 2011 | unsigned long e; |
| 2011 | char err_buf[120]; | 2012 | char err_buf[120]; |