Commit 5da874ff252d453dbbf8f957177438650a97b15c
1 parent
19d4f4f6
Exists in
master
and in
3 other branches
Reorganizing SSL methods.
Showing
15 changed files
with
697 additions
and
582 deletions
Show diff stats
configure.ac
... | ... | @@ -332,18 +332,6 @@ if test "$app_cv_self_signed_certs" == "yes"; then |
332 | 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
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
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 | -} |
... | ... | @@ -0,0 +1,177 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como ssl.c e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * licinio@bb.com.br (Licínio Luis Branco) | |
28 | + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | |
29 | + * | |
30 | + * | |
31 | + * References: | |
32 | + * | |
33 | + * http://www.openssl.org/docs/ssl/ | |
34 | + * | |
35 | + */ | |
36 | + | |
37 | +/** | |
38 | + * @brief OpenSSL initialization. | |
39 | + * | |
40 | + */ | |
41 | + | |
42 | +#include <config.h> | |
43 | +#if defined(HAVE_LIBSSL) | |
44 | + | |
45 | +#include <openssl/ssl.h> | |
46 | +#include <openssl/err.h> | |
47 | +#include <openssl/x509_vfy.h> | |
48 | + | |
49 | +#ifndef SSL_ST_OK | |
50 | + #define SSL_ST_OK 3 | |
51 | +#endif // !SSL_ST_OK | |
52 | + | |
53 | +#include "../private.h" | |
54 | +#include <errno.h> | |
55 | +#include <lib3270.h> | |
56 | +#include <lib3270/internals.h> | |
57 | +#include <lib3270/trace.h> | |
58 | +#include "trace_dsc.h" | |
59 | + | |
60 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | |
61 | + | |
62 | +/** | |
63 | + * @brief Initialize openssl library. | |
64 | + * | |
65 | + * @return 0 if ok, non zero if fails. | |
66 | + * | |
67 | + */ | |
68 | +int ssl_ctx_init(void) | |
69 | +{ | |
70 | + debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx); | |
71 | + | |
72 | + if(ssl_ctx != NULL) | |
73 | + return 0; | |
74 | + | |
75 | + SSL_load_error_strings(); | |
76 | + SSL_library_init(); | |
77 | + | |
78 | + ssl_ctx = SSL_CTX_new(SSLv23_method()); | |
79 | + if(ssl_ctx == NULL) | |
80 | + return -1; | |
81 | + | |
82 | + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); | |
83 | + SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); | |
84 | + SSL_CTX_set_default_verify_paths(ssl_ctx); | |
85 | + | |
86 | +#if defined(_WIN32) | |
87 | + { | |
88 | + HKEY hKey = 0; | |
89 | + | |
90 | + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) | |
91 | + { | |
92 | + char data[4096]; | |
93 | + unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) | |
94 | + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) | |
95 | + | |
96 | + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) | |
97 | + { | |
98 | + strncat(data,"\\certs",4095); | |
99 | + | |
100 | + trace("Loading certs from \"%s\"",data); | |
101 | + if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data)) | |
102 | + { | |
103 | + char buffer[4096]; | |
104 | + int ssl_error = ERR_get_error(); | |
105 | + | |
106 | + snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data); | |
107 | + | |
108 | + lib3270_popup_dialog( | |
109 | + hSession, | |
110 | + LIB3270_NOTIFY_ERROR, | |
111 | + N_( "Security error" ), | |
112 | + buffer, | |
113 | + N_( "%s" ),ERR_lib_error_string(ssl_error) | |
114 | + ); | |
115 | + } | |
116 | + } | |
117 | + RegCloseKey(hKey); | |
118 | + } | |
119 | + | |
120 | + | |
121 | + } | |
122 | +#else | |
123 | + static const char * ssldir[] = | |
124 | + { | |
125 | +#ifdef DATAROOTDIR | |
126 | + DATAROOTDIR "/" PACKAGE_NAME "/certs", | |
127 | +#endif // DATAROOTDIR | |
128 | +#ifdef SYSCONFDIR | |
129 | + SYSCONFDIR "/ssl/certs", | |
130 | + SYSCONFDIR "/certs", | |
131 | +#endif | |
132 | + "/etc/ssl/certs" | |
133 | + }; | |
134 | + | |
135 | + size_t f; | |
136 | + | |
137 | + for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++) | |
138 | + { | |
139 | + SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]); | |
140 | + } | |
141 | + | |
142 | +#endif // _WIN32 | |
143 | + | |
144 | + // | |
145 | + // Initialize CUSTOM CRL CHECK | |
146 | + // | |
147 | + | |
148 | + | |
149 | +/* | |
150 | +#if defined(SSL_ENABLE_CRL_CHECK) | |
151 | + // Set up CRL validation | |
152 | + // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now | |
153 | + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); | |
154 | + | |
155 | + // Enable CRL checking | |
156 | + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); | |
157 | + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); | |
158 | + X509_STORE_set1_param(store, param); | |
159 | + X509_VERIFY_PARAM_free(param); | |
160 | + | |
161 | + // X509_STORE_free(store); | |
162 | + | |
163 | + trace_dsn(hSession,"CRL CHECK is enabled.\n"); | |
164 | + | |
165 | +#else | |
166 | + | |
167 | + trace_dsn(hSession,"CRL CHECK is disabled.\n"); | |
168 | + | |
169 | +#endif // SSL_ENABLE_CRL_CHECK | |
170 | +*/ | |
171 | + | |
172 | + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); | |
173 | + | |
174 | + return 0; | |
175 | +} | |
176 | + | |
177 | +#endif // HAVE_LIBSSL | ... | ... |
... | ... | @@ -0,0 +1,378 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como ssl.c e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * licinio@bb.com.br (Licínio Luis Branco) | |
28 | + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) | |
29 | + * | |
30 | + * | |
31 | + * References: | |
32 | + * | |
33 | + * http://www.openssl.org/docs/ssl/ | |
34 | + * | |
35 | + */ | |
36 | + | |
37 | + | |
38 | +#include <config.h> | |
39 | +#if defined(HAVE_LIBSSL) | |
40 | + #include <openssl/ssl.h> | |
41 | + #include <openssl/err.h> | |
42 | + #include <openssl/x509_vfy.h> | |
43 | + | |
44 | + #ifndef SSL_ST_OK | |
45 | + #define SSL_ST_OK 3 | |
46 | + #endif // !SSL_ST_OK | |
47 | + | |
48 | +#endif | |
49 | + | |
50 | +#include "../private.h" | |
51 | +#include <errno.h> | |
52 | +#include <lib3270.h> | |
53 | +#include <lib3270/internals.h> | |
54 | +#include <lib3270/trace.h> | |
55 | +#include "trace_dsc.h" | |
56 | + | |
57 | +/*--[ Implement ]------------------------------------------------------------------------------------*/ | |
58 | + | |
59 | +#if defined(HAVE_LIBSSL) | |
60 | + | |
61 | + /** | |
62 | + * @brief Index of h3270 handle in SSL session. | |
63 | + * | |
64 | + */ | |
65 | + int ssl_3270_ex_index = -1; | |
66 | + | |
67 | +/** | |
68 | + * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections. | |
69 | + * | |
70 | + */ | |
71 | + SSL_CTX * ssl_ctx = NULL; | |
72 | + | |
73 | +/** | |
74 | + * @brief Initialize openssl session. | |
75 | + * | |
76 | + * @param hSession lib3270 session handle. | |
77 | + * | |
78 | + * @return 0 if ok, non zero if fails. | |
79 | + * | |
80 | + */ | |
81 | +int ssl_init(H3270 *hSession) | |
82 | +{ | |
83 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | |
84 | + hSession->ssl.error = 0; | |
85 | + hSession->ssl.host = False; | |
86 | + | |
87 | + if(ssl_ctx_init()) { | |
88 | + | |
89 | + hSession->ssl.error = ERR_get_error(); | |
90 | + | |
91 | + lib3270_popup_dialog( | |
92 | + hSession, | |
93 | + LIB3270_NOTIFY_ERROR, | |
94 | + N_( "Security error" ), | |
95 | + N_( "SSL initialization has failed" ), | |
96 | + "%s",ERR_reason_error_string(hSession->ssl.error) | |
97 | + ); | |
98 | + | |
99 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | |
100 | + | |
101 | + hSession->ssl.host = False; | |
102 | + return -1; | |
103 | + } | |
104 | + | |
105 | + if(hSession->ssl.con) | |
106 | + SSL_free(hSession->ssl.con); | |
107 | + | |
108 | + hSession->ssl.con = SSL_new(ssl_ctx); | |
109 | + if(hSession->ssl.con == NULL) | |
110 | + { | |
111 | + hSession->ssl.error = ERR_get_error(); | |
112 | + | |
113 | + lib3270_popup_dialog( | |
114 | + hSession, | |
115 | + LIB3270_NOTIFY_ERROR, | |
116 | + N_( "Security error" ), | |
117 | + N_( "Cant create a new SSL structure for current connection." ), | |
118 | + N_( "%s" ),ERR_lib_error_string(hSession->ssl.error) | |
119 | + ); | |
120 | + | |
121 | + return -1; | |
122 | + } | |
123 | + | |
124 | + SSL_set_ex_data(hSession->ssl.con,ssl_3270_ex_index,(char *) hSession); | |
125 | + | |
126 | +// SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); | |
127 | + SSL_set_verify(hSession->ssl.con, 0, NULL); | |
128 | + | |
129 | + return 0; | |
130 | +} | |
131 | + | |
132 | +int ssl_negotiate(H3270 *hSession) | |
133 | +{ | |
134 | + int rv; | |
135 | + | |
136 | + trace("%s",__FUNCTION__); | |
137 | + | |
138 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); | |
139 | + non_blocking(hSession,False); | |
140 | + | |
141 | + /* Initialize the SSL library. */ | |
142 | + if(ssl_init(hSession)) | |
143 | + { | |
144 | + /* Failed. */ | |
145 | + lib3270_disconnect(hSession); | |
146 | + return -1; | |
147 | + } | |
148 | + | |
149 | + /* Set up the TLS/SSL connection. */ | |
150 | + if(SSL_set_fd(hSession->ssl.con, hSession->sock) != 1) | |
151 | + { | |
152 | + trace_dsn(hSession,"%s","SSL_set_fd failed!\n"); | |
153 | + | |
154 | + lib3270_popup_dialog( | |
155 | + hSession, | |
156 | + LIB3270_NOTIFY_ERROR, | |
157 | + N_( "Security error" ), | |
158 | + N_( "SSL negotiation failed" ), | |
159 | + "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." ) | |
160 | + ); | |
161 | + | |
162 | + lib3270_disconnect(hSession); | |
163 | + return -1; | |
164 | + } | |
165 | + | |
166 | + trace("%s: Running SSL_connect",__FUNCTION__); | |
167 | + rv = SSL_connect(hSession->ssl.con); | |
168 | + trace("%s: SSL_connect exits with rc=%d",__FUNCTION__,rv); | |
169 | + | |
170 | + if (rv != 1) | |
171 | + { | |
172 | + int ssl_error = SSL_get_error(hSession->ssl.con,rv); | |
173 | + const char * msg = ""; | |
174 | + | |
175 | + if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl.error) | |
176 | + ssl_error = hSession->ssl.error; | |
177 | + | |
178 | + msg = ERR_lib_error_string(ssl_error); | |
179 | + | |
180 | + trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl.error)); | |
181 | + | |
182 | + lib3270_popup_dialog( | |
183 | + hSession, | |
184 | + LIB3270_NOTIFY_ERROR, | |
185 | + N_( "Security error" ), | |
186 | + N_( "SSL Connect failed" ), | |
187 | + "%s",msg ? msg : "" | |
188 | + ); | |
189 | + | |
190 | + lib3270_disconnect(hSession); | |
191 | + return -1; | |
192 | + } | |
193 | + | |
194 | + /* Success. */ | |
195 | + X509 * peer = NULL; | |
196 | + rv = SSL_get_verify_result(hSession->ssl.con); | |
197 | + | |
198 | + switch(rv) | |
199 | + { | |
200 | + case X509_V_OK: | |
201 | + peer = SSL_get_peer_certificate(hSession->ssl.con); | |
202 | + trace_dsn(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not"); | |
203 | + break; | |
204 | + | |
205 | + case X509_V_ERR_UNABLE_TO_GET_CRL: | |
206 | + trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" ); | |
207 | + lib3270_disconnect(hSession); | |
208 | + lib3270_popup_dialog( hSession, | |
209 | + LIB3270_NOTIFY_ERROR, | |
210 | + _( "SSL error" ), | |
211 | + _( "Unable to get certificate CRL." ), | |
212 | + _( "The Certificate revocation list (CRL) of a certificate could not be found." ) | |
213 | + ); | |
214 | + return -1; | |
215 | + | |
216 | + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: | |
217 | + peer = SSL_get_peer_certificate(hSession->ssl.con); | |
218 | + trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" ); | |
219 | + | |
220 | +#ifdef SSL_ALLOW_SELF_SIGNED_CERT | |
221 | + break; | |
222 | +#else | |
223 | + lib3270_disconnect(hSession); | |
224 | + lib3270_popup_dialog( hSession, | |
225 | + LIB3270_NOTIFY_ERROR, | |
226 | + _( "SSL error" ), | |
227 | + _( "The SSL certificate for this host is not trusted." ), | |
228 | + _( "The security certificate presented by this host was not issued by a trusted certificate authority." ) | |
229 | + ); | |
230 | + | |
231 | + return -1; | |
232 | +#endif // SSL_ALLOW_SELF_SIGNED_CERT | |
233 | + | |
234 | + default: | |
235 | + trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv); | |
236 | + } | |
237 | + | |
238 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | |
239 | + { | |
240 | + char buffer[4096]; | |
241 | + int alg_bits = 0; | |
242 | + const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl.con); | |
243 | + | |
244 | + trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); | |
245 | + SSL_CIPHER_get_bits(cipher, &alg_bits); | |
246 | + trace_dsn(hSession,"%s version %s with %d bits\n", | |
247 | + SSL_CIPHER_get_name(cipher), | |
248 | + SSL_CIPHER_get_version(cipher), | |
249 | + alg_bits); | |
250 | + } | |
251 | + | |
252 | + | |
253 | + if(peer) | |
254 | + { | |
255 | + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) | |
256 | + { | |
257 | + BIO * out = BIO_new(BIO_s_mem()); | |
258 | + unsigned char * data; | |
259 | + unsigned char * text; | |
260 | + int n; | |
261 | + | |
262 | + X509_print(out,peer); | |
263 | + | |
264 | + n = BIO_get_mem_data(out, &data); | |
265 | + text = (unsigned char *) malloc (n+1); | |
266 | + text[n] ='\0'; | |
267 | + memcpy(text,data,n); | |
268 | + | |
269 | + trace_dsn(hSession,"TLS/SSL peer certificate:\n%s\n",text); | |
270 | + | |
271 | + free(text); | |
272 | + BIO_free(out); | |
273 | + | |
274 | + } | |
275 | + | |
276 | + hSession->cbk.set_peer_certificate(peer); | |
277 | + | |
278 | + set_ssl_state(hSession,LIB3270_SSL_SECURE); | |
279 | + X509_free(peer); | |
280 | + } | |
281 | + | |
282 | + | |
283 | + /* Tell the world that we are (still) connected, now in secure mode. */ | |
284 | + lib3270_set_connected_initial(hSession); | |
285 | + non_blocking(hSession,True); | |
286 | + | |
287 | + return 0; | |
288 | +} | |
289 | + | |
290 | +/* Callback for tracing protocol negotiation. */ | |
291 | +void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) | |
292 | +{ | |
293 | + H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index); | |
294 | + | |
295 | +#ifdef DEBUG | |
296 | + if(hSession != lib3270_get_default_session_handle()) | |
297 | + { | |
298 | + trace("%s: hsession=%p, session=%p",__FUNCTION__,hSession,lib3270_get_default_session_handle()); | |
299 | + exit(-1); | |
300 | + } | |
301 | +#endif // DEBUG | |
302 | + | |
303 | + switch(where) | |
304 | + { | |
305 | + case SSL_CB_CONNECT_LOOP: | |
306 | + trace_dsn(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s)); | |
307 | + break; | |
308 | + | |
309 | + case SSL_CB_CONNECT_EXIT: | |
310 | + | |
311 | + trace_dsn(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__); | |
312 | + | |
313 | + if (ret == 0) | |
314 | + { | |
315 | + trace_dsn(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s)); | |
316 | + } | |
317 | + else if (ret < 0) | |
318 | + { | |
319 | + unsigned long e = ERR_get_error(); | |
320 | + char err_buf[1024]; | |
321 | + | |
322 | + if(e != 0) | |
323 | + { | |
324 | + hSession->ssl.error = e; | |
325 | + (void) ERR_error_string_n(e, err_buf, 1023); | |
326 | + } | |
327 | +#if defined(_WIN32) | |
328 | + else if (GetLastError() != 0) | |
329 | + { | |
330 | + strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023); | |
331 | + } | |
332 | +#else | |
333 | + else if (errno != 0) | |
334 | + { | |
335 | + strncpy(err_buf, strerror(errno),1023); | |
336 | + } | |
337 | +#endif | |
338 | + else | |
339 | + { | |
340 | + err_buf[0] = '\0'; | |
341 | + } | |
342 | + | |
343 | + trace_dsn(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n", | |
344 | + ret, | |
345 | + err_buf, | |
346 | + SSL_state_string_long(s), | |
347 | + SSL_alert_type_string_long(ret) | |
348 | + ); | |
349 | + | |
350 | + } | |
351 | + | |
352 | + | |
353 | + default: | |
354 | + trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); | |
355 | + } | |
356 | + | |
357 | +#ifdef DEBUG | |
358 | + if(where & SSL_CB_EXIT) | |
359 | + { | |
360 | + trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret); | |
361 | + } | |
362 | +#endif | |
363 | + | |
364 | + if(where & SSL_CB_ALERT) | |
365 | + trace_dsn(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret)); | |
366 | + | |
367 | + if(where & SSL_CB_HANDSHAKE_DONE) | |
368 | + { | |
369 | + trace_dsn(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s)); | |
370 | + if(SSL_get_state(s) == SSL_ST_OK) | |
371 | + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED); | |
372 | + else | |
373 | + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | |
374 | + } | |
375 | +} | |
376 | + | |
377 | +#endif /*]*/ | |
378 | + | ... | ... |
... | ... | @@ -0,0 +1,74 @@ |
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]; | ... | ... |