Commit 5da874ff252d453dbbf8f957177438650a97b15c

Authored by Perry Werneck
1 parent 19d4f4f6

Reorganizing SSL methods.

configure.ac
... ... @@ -332,18 +332,6 @@ if test "$app_cv_self_signed_certs" == "yes"; then
332 332 AC_DEFINE(SSL_ALLOW_SELF_SIGNED_CERT)
333 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 335 dnl ---------------------------------------------------------------------------
348 336 dnl Check for pic
349 337 dnl ---------------------------------------------------------------------------
... ...
lib3270.cbp
... ... @@ -212,6 +212,15 @@
212 212 <Unit filename="src/lib3270/ssl.c">
213 213 <Option compilerVar="CC" />
214 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 224 <Unit filename="src/lib3270/state.c">
216 225 <Option compilerVar="CC" />
217 226 </Unit>
... ...
src/include/config.h.in
... ... @@ -50,7 +50,6 @@
50 50 #undef HAVE_LDAP
51 51 #undef HAVE_LIBSSL
52 52 #undef SSL_ALLOW_SELF_SIGNED_CERT
53   - #undef SSL_ENABLE_CRL_CHECK
54 53  
55 54 /* Windows Options */
56 55 #ifdef WIN32
... ...
src/include/lib3270/macros.h
... ... @@ -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 30  
31 31 SOURCES= \
32 32 $(wildcard *.c) \
  33 + $(wildcard ssl/*.c) \
33 34 $(wildcard @OSNAME@/*.c) \
34 35 $(wildcard @OSNAME@/*.rc) \
35 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 129 hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0);
130 130  
131 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 134 if(ssl_negotiate(hSession))
135 135 return;
... ... @@ -333,12 +333,12 @@ static void net_connected(H3270 *hSession, int fd, LIB3270_IO_FLAG flag, void *d
333 333 #endif
334 334  
335 335 hSession->ever_3270 = False;
336   - hSession->ssl_host = 0;
  336 + hSession->ssl.host = 0;
337 337  
338 338 if(hSession->options&LIB3270_OPTION_SSL)
339 339 {
340 340 #if defined(HAVE_LIBSSL)
341   - hSession->ssl_host = 1;
  341 + hSession->ssl.host = 1;
342 342 ssl_init(hSession);
343 343 #else
344 344 lib3270_popup_dialog( hSession,
... ...
src/lib3270/host.c
... ... @@ -144,7 +144,7 @@ void lib3270_set_disconnected(H3270 *hSession)
144 144  
145 145 hSession->cstate = LIB3270_NOT_CONNECTED;
146 146 hSession->starting = 0;
147   - hSession->secure = LIB3270_SSL_UNDEFINED;
  147 + hSession->ssl.state = LIB3270_SSL_UNDEFINED;
148 148  
149 149 set_status(hSession,OIA_FLAG_UNDERA,False);
150 150  
... ... @@ -155,7 +155,7 @@ void lib3270_set_disconnected(H3270 *hSession)
155 155 if(hSession->cbk.update_connect)
156 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 399 /*
400 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 404 if (session->kybdlock & KL_DEFERRED_UNLOCK)
405 405 RemoveTimeOut(session, session->unlock_id);
... ... @@ -421,7 +421,7 @@ void kybd_connect(H3270 *session, int connected, void *dunno)
421 421 /*
422 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 426 if (hSession->kybdlock & KL_DEFERRED_UNLOCK)
427 427 RemoveTimeOut(hSession, hSession->unlock_id);
... ... @@ -694,7 +694,7 @@ static Boolean ins_prep(H3270 *hSession, int faddr, int baddr, int count)
694 694 #define GE_WFLAG 0x100
695 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 699 int code;
700 700 Boolean with_ge = False;
... ...
src/lib3270/macros.c
... ... @@ -30,6 +30,7 @@
30 30 *
31 31 */
32 32  
  33 +/*
33 34 #ifdef WIN32
34 35 #include <winsock2.h>
35 36 #include <windows.h>
... ... @@ -46,17 +47,21 @@
46 47 #include "private.h"
47 48 #include "utilc.h"
48 49 #include "api.h"
  50 + */
49 51  
50 52 /*--[ Structs & Defines ]----------------------------------------------------------------------------*/
51 53  
  54 +/*
52 55 struct macro_list
53 56 {
54 57 const char *name;
55 58 char *(*exec)(H3270 *session, int argc, const char **argv);
56 59 };
  60 +*/
57 61  
58 62 /*--[ Implement ]------------------------------------------------------------------------------------*/
59 63  
  64 +/*
60 65 static const char * get_state(H3270 *h)
61 66 {
62 67 #define DECLARE_XLAT_STATE(x) { x, #x }
... ... @@ -106,33 +111,6 @@
106 111 buffer = lib3270_get_string_at_address(hSession,0,-1,'\n');
107 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 114 default:
137 115 errno = EINVAL;
138 116 }
... ... @@ -317,9 +295,11 @@
317 295 return strdup(ret);
318 296  
319 297 }
  298 +*/
320 299  
321 300 /*--[ Macro entry point ]----------------------------------------------------------------------------*/
322 301  
  302 +/*
323 303 LIB3270_EXPORT char * lib3270_run_macro(H3270 *session, const char **argv)
324 304 {
325 305 #define LIB3270_MACRO_ENTRY( name ) { #name, lib3270_macro_ ## name }
... ... @@ -379,4 +359,4 @@
379 359 // Not found, return NULL
380 360 return NULL;
381 361 }
382   -
  362 +*/
... ...
src/lib3270/private.h
... ... @@ -38,6 +38,10 @@
38 38 #include <lib3270/charset.h>
39 39 #include "api.h"
40 40  
  41 +#if defined(HAVE_LIBSSL)
  42 + #include <openssl/ssl.h>
  43 +#endif // HAVE_LIBSSL
  44 +
41 45 #if defined(X3270_TN3270E) && !defined(X3270_ANSI) /*[*/
42 46 #define X3270_ANSI 1 /* RFC2355 requires NVT mode */
43 47 #endif /*]*/
... ... @@ -341,8 +345,6 @@ struct _h3270
341 345  
342 346 char * oversize;
343 347  
344   - LIB3270_SSL_STATE secure;
345   -
346 348 struct lib3270_toggle
347 349 {
348 350 char value; /**< toggle value */
... ... @@ -406,7 +408,6 @@ struct _h3270
406 408 char no_login_host;
407 409 char non_tn3270e_host;
408 410 char passthru_host;
409   - char ssl_host;
410 411 char ever_3270;
411 412  
412 413 // ctlr.c
... ... @@ -602,8 +603,13 @@ struct _h3270
602 603 void * ns_exception_id;
603 604  
604 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 614 timeout_t * timeouts;
609 615 input_t * inputs;
... ... @@ -649,6 +655,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
649 655  
650 656 #if defined(HAVE_LIBSSL) /*[*/
651 657  
  658 + LIB3270_INTERNAL int ssl_ctx_init(void);
652 659 LIB3270_INTERNAL int ssl_init(H3270 *session);
653 660 LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession);
654 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 669  
663 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 684 #endif /*]*/
666 685  
... ...
src/lib3270/ssl.c
... ... @@ -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 @@
  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 @@
  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 @@
  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 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 811 #if defined(HAVE_LIBSSL)
812 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 815 if(ssl_negotiate(hSession))
816 816 return -1;
... ... @@ -899,11 +899,12 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
899 899 trace("%s",__FUNCTION__);
900 900  
901 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 909 #endif
909 910  
... ... @@ -1010,8 +1011,8 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void
1010 1011 #endif
1011 1012  
1012 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 1016 else
1016 1017 nr = recv(hSession->sock, (char *) buffer, BUFSZ, 0);
1017 1018 #else
... ... @@ -1024,7 +1025,7 @@ void net_input(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag unused, void
1024 1025 return;
1025 1026  
1026 1027 #if defined(HAVE_LIBSSL) /*[*/
1027   - if(hSession->ssl_con != NULL)
  1028 + if(hSession->ssl.con != NULL)
1028 1029 {
1029 1030 unsigned long e;
1030 1031 char err_buf[120];
... ... @@ -1991,8 +1992,8 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
1991 1992 int rc;
1992 1993  
1993 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 1997 else
1997 1998 rc = send(hSession->sock, (const char *) buf, len, 0);
1998 1999 #else
... ... @@ -2005,7 +2006,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
2005 2006 // Recv error, notify
2006 2007  
2007 2008 #if defined(HAVE_LIBSSL)
2008   - if(hSession->ssl_con != NULL)
  2009 + if(hSession->ssl.con != NULL)
2009 2010 {
2010 2011 unsigned long e;
2011 2012 char err_buf[120];
... ...