Commit 5da874ff252d453dbbf8f957177438650a97b15c

Authored by Perry Werneck
1 parent 19d4f4f6

Reorganizing SSL methods.

@@ -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 ---------------------------------------------------------------------------
@@ -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 -}  
src/lib3270/ssl/init.c 0 → 100644
@@ -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
src/lib3270/ssl/negotiate.c 0 → 100644
@@ -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 +
src/lib3270/ssl/state.c 0 → 100644
@@ -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];