Commit 89cac419068459c8b9090d65f85861a95eb0c8da

Authored by perry.werneck@gmail.com
1 parent f3c2e279

Melhorando tratamento do SSL

Showing 3 changed files with 155 additions and 63 deletions   Show diff stats
@@ -28,14 +28,6 @@ @@ -28,14 +28,6 @@
28 28
29 PACKAGE=@PACKAGE_NAME@ 29 PACKAGE=@PACKAGE_NAME@
30 30
31 -CFLAGS=@CFLAGS@ @DLL_CFLAGS@ -DDATAROOTDIR=\"$(datarootdir)\" -I../include  
32 -SSL_CFLAGS=@LIBSSL_CFLAGS@  
33 -  
34 -DLL_FLAGS=@DLL_FLAGS@  
35 -LDFLAGS=@LDFLAGS@  
36 -  
37 -LIBS=@LIBS@ @LIBSSL_LIBS@ @INTL_LIBS@ @SOCKET_LIBS@  
38 -  
39 DEBUG_CFLAGS=-DDEBUG=1 -g -Wall 31 DEBUG_CFLAGS=-DDEBUG=1 -g -Wall
40 DEPENDS ?= *.h ../include/*.h ../include/lib3270/*.h Makefile 32 DEPENDS ?= *.h ../include/*.h ../include/lib3270/*.h Makefile
41 33
@@ -46,6 +38,18 @@ exec_prefix=@exec_prefix@ @@ -46,6 +38,18 @@ exec_prefix=@exec_prefix@
46 libdir=@libdir@ 38 libdir=@libdir@
47 includedir=@includedir@ 39 includedir=@includedir@
48 localedir=@localedir@ 40 localedir=@localedir@
  41 +datarootdir=@datarootdir@
  42 +sysconfdir=@sysconfdir@
  43 +
  44 +#---[ Tools ]------------------------------------------------------------------
  45 +
  46 +CFLAGS=@CFLAGS@ @DLL_CFLAGS@ -DDATAROOTDIR=\"$(datarootdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -I../include
  47 +SSL_CFLAGS=@LIBSSL_CFLAGS@
  48 +
  49 +DLL_FLAGS=@DLL_FLAGS@
  50 +LDFLAGS=@LDFLAGS@
  51 +
  52 +LIBS=@LIBS@ @LIBSSL_LIBS@ @INTL_LIBS@ @SOCKET_LIBS@
49 53
50 #---[ Tools ]------------------------------------------------------------------ 54 #---[ Tools ]------------------------------------------------------------------
51 55
@@ -253,7 +253,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); @@ -253,7 +253,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
253 253
254 #if defined(HAVE_LIBSSL) /*[*/ 254 #if defined(HAVE_LIBSSL) /*[*/
255 255
256 - LIB3270_INTERNAL void ssl_init(H3270 *session); 256 + LIB3270_INTERNAL int ssl_init(H3270 *session);
257 LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession); 257 LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession);
258 LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state); 258 LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
259 259
@@ -27,6 +27,11 @@ @@ -27,6 +27,11 @@
27 * licinio@bb.com.br (Licínio Luis Branco) 27 * licinio@bb.com.br (Licínio Luis Branco)
28 * kraucer@bb.com.br (Kraucer Fernandes Mazuco) 28 * kraucer@bb.com.br (Kraucer Fernandes Mazuco)
29 * 29 *
  30 + *
  31 + * References:
  32 + *
  33 + * http://www.openssl.org/docs/ssl/
  34 + *
30 */ 35 */
31 36
32 37
@@ -38,6 +43,7 @@ @@ -38,6 +43,7 @@
38 43
39 #include "globals.h" 44 #include "globals.h"
40 #include <errno.h> 45 #include <errno.h>
  46 +#include <lib3270.h>
41 #include <lib3270/internals.h> 47 #include <lib3270/internals.h>
42 #include <lib3270/trace.h> 48 #include <lib3270/trace.h>
43 #include "trace_dsc.h" 49 #include "trace_dsc.h"
@@ -57,11 +63,9 @@ int ssl_negotiate(H3270 *hSession) @@ -57,11 +63,9 @@ int ssl_negotiate(H3270 *hSession)
57 non_blocking(hSession,False); 63 non_blocking(hSession,False);
58 64
59 /* Initialize the SSL library. */ 65 /* Initialize the SSL library. */
60 - ssl_init(hSession);  
61 - if(hSession->ssl_con == NULL) 66 + if(ssl_init(hSession))
62 { 67 {
63 /* Failed. */ 68 /* Failed. */
64 - popup_an_error(hSession,_( "SSL init failed!"));  
65 lib3270_disconnect(hSession); 69 lib3270_disconnect(hSession);
66 return -1; 70 return -1;
67 } 71 }
@@ -69,10 +73,17 @@ int ssl_negotiate(H3270 *hSession) @@ -69,10 +73,17 @@ int ssl_negotiate(H3270 *hSession)
69 /* Set up the TLS/SSL connection. */ 73 /* Set up the TLS/SSL connection. */
70 if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1) 74 if(SSL_set_fd(hSession->ssl_con, hSession->sock) != 1)
71 { 75 {
72 - trace_dsn(hSession,"SSL_set_fd failed!\n");  
73 - #warning Show a better popup here  
74 - // popup_an_error(hSession,_( "SSL_set_fd failed!"));  
75 - lib32070_disconnect(hSession); 76 + trace_dsn(hSession,"%s","SSL_set_fd failed!\n");
  77 +
  78 + lib3270_popup_dialog(
  79 + hSession,
  80 + LIB3270_NOTIFY_ERROR,
  81 + N_( "Security error" ),
  82 + N_( "SSL negotiation failed" ),
  83 + "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." )
  84 + );
  85 +
  86 + lib3270_disconnect(hSession);
76 return -1; 87 return -1;
77 } 88 }
78 89
@@ -84,51 +95,60 @@ int ssl_negotiate(H3270 *hSession) @@ -84,51 +95,60 @@ int ssl_negotiate(H3270 *hSession)
84 { 95 {
85 int ssl_error = SSL_get_error(hSession->ssl_con,rv); 96 int ssl_error = SSL_get_error(hSession->ssl_con,rv);
86 97
87 - if(ssl_error == SSL_ERROR_SYSCALL)  
88 - {  
89 - if(!hSession->ssl_error)  
90 - {  
91 - trace_dsn(hSession,"SSL_connect failed (ssl_error=%lu)\n",hSession->ssl_error);  
92 - popup_an_error(hSession,_( "SSL connect failed!"));  
93 - }  
94 - else  
95 - {  
96 - trace_dsn(hSession,"SSL_connect failed: %s %s\n",  
97 - ERR_lib_error_string(hSession->ssl_error),  
98 - ERR_reason_error_string(hSession->ssl_error));  
99 - popup_an_error(hSession,"%s",_( ERR_reason_error_string(hSession->ssl_error) ));  
100 - } 98 + if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl_error)
  99 + ssl_error = hSession->ssl_error;
101 100
102 - }  
103 - else  
104 - {  
105 - trace_dsn(hSession,"SSL_connect failed (ssl_error=%d errno=%d)\n",ssl_error,errno);  
106 - popup_an_error(hSession,_( "SSL connect failed!"));  
107 - } 101 + trace_dsn(hSession,"SSL_connect failed: %s %s\n",ERR_lib_error_string(hSession->ssl_error),ERR_reason_error_string(hSession->ssl_error));
  102 +
  103 + lib3270_popup_dialog(
  104 + hSession,
  105 + LIB3270_NOTIFY_ERROR,
  106 + N_( "Security error" ),
  107 + N_( "SSL Connect failed" ),
  108 + "%s",ERR_lib_error_string(ssl_error)
  109 + );
108 110
109 lib3270_disconnect(hSession); 111 lib3270_disconnect(hSession);
110 return -1; 112 return -1;
111 } 113 }
112 114
113 /* Success. */ 115 /* Success. */
  116 + X509 * peer = NULL;
  117 + rv = SSL_get_verify_result(hSession->ssl_con);
  118 +
  119 + switch(rv)
  120 + {
  121 + case X509_V_OK:
  122 + peer = SSL_get_peer_certificate(hSession->ssl_con);
  123 + trace_dsn(hSession,"TLS/SSL negotiated connection complete. Peer certificate %s presented.\n", peer ? "was" : "was not");
  124 + break;
  125 +
  126 + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
  127 + trace_dsn(hSession,"%s","TLS/SSL negotiated connection complete with self signed certificate in certificate chain\n" );
  128 + break;
  129 +
  130 + default:
  131 + trace_dsn(hSession,"Unexpected or invalid TLS/SSL verify result %d\n",rv);
  132 + }
  133 +
114 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE)) 134 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
115 { 135 {
116 char buffer[4096]; 136 char buffer[4096];
117 int alg_bits = 0; 137 int alg_bits = 0;
118 const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con); 138 const SSL_CIPHER * cipher = SSL_get_current_cipher(hSession->ssl_con);
119 - X509 * peer = SSL_get_peer_certificate(hSession->ssl_con);  
120 -  
121 - trace_dsn(hSession,"TLS/SSL negotiated connection complete. Connection is now secure.\n");  
122 139
123 trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095)); 140 trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095));
124 SSL_CIPHER_get_bits(cipher, &alg_bits); 141 SSL_CIPHER_get_bits(cipher, &alg_bits);
125 - trace_dsn(hSession,"%s version %s with %d bits verify=%ld\n", 142 + trace_dsn(hSession,"%s version %s with %d bits\n",
126 SSL_CIPHER_get_name(cipher), 143 SSL_CIPHER_get_name(cipher),
127 SSL_CIPHER_get_version(cipher), 144 SSL_CIPHER_get_version(cipher),
128 - alg_bits,  
129 - SSL_get_verify_result(hSession->ssl_con)); 145 + alg_bits);
  146 + }
130 147
131 - if(peer) 148 +
  149 + if(peer)
  150 + {
  151 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
132 { 152 {
133 BIO * out = BIO_new(BIO_s_mem()); 153 BIO * out = BIO_new(BIO_s_mem());
134 unsigned char * data; 154 unsigned char * data;
@@ -149,10 +169,11 @@ int ssl_negotiate(H3270 *hSession) @@ -149,10 +169,11 @@ int ssl_negotiate(H3270 *hSession)
149 X509_free(peer); 169 X509_free(peer);
150 170
151 } 171 }
152 - }  
153 172
154 - if(!SSL_get_verify_result(hSession->ssl_con))  
155 set_ssl_state(hSession,LIB3270_SSL_SECURE); 173 set_ssl_state(hSession,LIB3270_SSL_SECURE);
  174 + X509_free(peer);
  175 + }
  176 +
156 177
157 /* Tell the world that we are (still) connected, now in secure mode. */ 178 /* Tell the world that we are (still) connected, now in secure mode. */
158 lib3270_set_connected(hSession); 179 lib3270_set_connected(hSession);
@@ -162,25 +183,45 @@ int ssl_negotiate(H3270 *hSession) @@ -162,25 +183,45 @@ int ssl_negotiate(H3270 *hSession)
162 183
163 #if defined(HAVE_LIBSSL) /*[*/ 184 #if defined(HAVE_LIBSSL) /*[*/
164 185
165 -/* Initialize the OpenSSL library. */  
166 -void ssl_init(H3270 *session) 186 +/**
  187 + * Initializa openssl library.
  188 + *
  189 + * @param hSession lib3270 session handle.
  190 + *
  191 + * @return 0 if ok, non zero if fails.
  192 + *
  193 + */
  194 +int ssl_init(H3270 *hSession)
167 { 195 {
168 static SSL_CTX *ssl_ctx = NULL; 196 static SSL_CTX *ssl_ctx = NULL;
169 197
170 - session->ssl_error = 0;  
171 - set_ssl_state(session,LIB3270_SSL_UNDEFINED); 198 + hSession->ssl_error = 0;
  199 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
172 200
173 if(ssl_ctx == NULL) 201 if(ssl_ctx == NULL)
174 { 202 {
175 - lib3270_write_log(session,"SSL","%s","Initializing SSL context"); 203 + lib3270_write_log(hSession,"SSL","%s","Initializing SSL context");
  204 +
176 SSL_load_error_strings(); 205 SSL_load_error_strings();
177 SSL_library_init(); 206 SSL_library_init();
  207 +
178 ssl_ctx = SSL_CTX_new(SSLv23_method()); 208 ssl_ctx = SSL_CTX_new(SSLv23_method());
179 if(ssl_ctx == NULL) 209 if(ssl_ctx == NULL)
180 { 210 {
181 - popup_an_error(session,"SSL_CTX_new failed");  
182 - session->ssl_host = False;  
183 - return; 211 + int ssl_error = ERR_get_error();
  212 +
  213 + lib3270_popup_dialog(
  214 + hSession,
  215 + LIB3270_NOTIFY_ERROR,
  216 + N_( "Security error" ),
  217 + N_( "SSL_CTX_new() has failed" ),
  218 + "%s",ERR_reason_error_string(ssl_error)
  219 + );
  220 +
  221 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
  222 +
  223 + hSession->ssl_host = False;
  224 + return -1;
184 } 225 }
185 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); 226 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
186 SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); 227 SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
@@ -201,13 +242,50 @@ void ssl_init(H3270 *session) @@ -201,13 +242,50 @@ void ssl_init(H3270 *session)
201 strncat(data,"\\certs",4095); 242 strncat(data,"\\certs",4095);
202 243
203 trace("Loading certs from \"%s\"",data); 244 trace("Loading certs from \"%s\"",data);
204 - SSL_CTX_load_verify_locations(ssl_ctx,NULL,data); 245 + if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data))
  246 + {
  247 + char buffer[4096];
  248 + int ssl_error = ERR_get_error();
  249 +
  250 + snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data);
  251 +
  252 + lib3270_popup_dialog(
  253 + hSession,
  254 + LIB3270_NOTIFY_ERROR,
  255 + N_( "Security error" ),
  256 + buffer,
  257 + N_( "%s" ),ERR_lib_error_string(ssl_error)
  258 + );
  259 + }
205 } 260 }
206 RegCloseKey(hKey); 261 RegCloseKey(hKey);
207 } 262 }
208 263
209 264
210 } 265 }
  266 +#else
  267 + static const char * ssldir[] =
  268 + {
  269 +#ifdef DATAROOTDIR
  270 + DATAROOTDIR "/" PACKAGE_NAME "/certs",
  271 +#endif // DATAROOTDIR
  272 +#ifdef SYSCONFDIR
  273 + SYSCONFDIR "/ssl/certs",
  274 + SYSCONFDIR "/certs",
  275 +#endif
  276 + "/etc/ssl/certs"
  277 + };
  278 +
  279 + int f;
  280 +
  281 + for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++)
  282 + {
  283 + if(!access(ssldir[f],R_OK) && SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]))
  284 + {
  285 + trace_dsn(hSession,"Checking %s for trusted CA certificates.\n",ssldir[f]);
  286 + break;
  287 + }
  288 + }
211 289
212 #endif // _WIN32 290 #endif // _WIN32
213 291
@@ -216,22 +294,32 @@ void ssl_init(H3270 *session) @@ -216,22 +294,32 @@ void ssl_init(H3270 *session)
216 294
217 } 295 }
218 296
219 - if(session->ssl_con)  
220 - SSL_free(session->ssl_con); 297 + if(hSession->ssl_con)
  298 + SSL_free(hSession->ssl_con);
221 299
222 - session->ssl_con = SSL_new(ssl_ctx);  
223 - if(session->ssl_con == NULL) 300 + hSession->ssl_con = SSL_new(ssl_ctx);
  301 + if(hSession->ssl_con == NULL)
224 { 302 {
225 - popup_an_error(session,"SSL_new failed");  
226 - session->ssl_host = False;  
227 - return; 303 + int ssl_error = ERR_get_error();
  304 +
  305 + lib3270_popup_dialog(
  306 + hSession,
  307 + LIB3270_NOTIFY_ERROR,
  308 + N_( "Security error" ),
  309 + N_( "Cant create a new SSL structure for current connection." ),
  310 + N_( "%s" ),ERR_lib_error_string(ssl_error)
  311 + );
  312 +
  313 + hSession->ssl_host = False;
  314 + return -1;
228 } 315 }
229 316
230 - SSL_set_ex_data(session->ssl_con,ssl_3270_ex_index,(char *) session); 317 + SSL_set_ex_data(hSession->ssl_con,ssl_3270_ex_index,(char *) hSession);
231 318
232 // SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); 319 // SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
233 - SSL_set_verify(session->ssl_con, 0, NULL); 320 + SSL_set_verify(hSession->ssl_con, 0, NULL);
234 321
  322 + return 0;
235 } 323 }
236 324
237 /* Callback for tracing protocol negotiation. */ 325 /* Callback for tracing protocol negotiation. */