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
Makefile.in
... ... @@ -28,14 +28,6 @@
28 28  
29 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 31 DEBUG_CFLAGS=-DDEBUG=1 -g -Wall
40 32 DEPENDS ?= *.h ../include/*.h ../include/lib3270/*.h Makefile
41 33  
... ... @@ -46,6 +38,18 @@ exec_prefix=@exec_prefix@
46 38 libdir=@libdir@
47 39 includedir=@includedir@
48 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 54 #---[ Tools ]------------------------------------------------------------------
51 55  
... ...
globals.h
... ... @@ -253,7 +253,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
253 253  
254 254 #if defined(HAVE_LIBSSL) /*[*/
255 255  
256   - LIB3270_INTERNAL void ssl_init(H3270 *session);
  256 + LIB3270_INTERNAL int ssl_init(H3270 *session);
257 257 LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession);
258 258 LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
259 259  
... ...
ssl.c
... ... @@ -27,6 +27,11 @@
27 27 * licinio@bb.com.br (Licínio Luis Branco)
28 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 43  
39 44 #include "globals.h"
40 45 #include <errno.h>
  46 +#include <lib3270.h>
41 47 #include <lib3270/internals.h>
42 48 #include <lib3270/trace.h>
43 49 #include "trace_dsc.h"
... ... @@ -57,11 +63,9 @@ int ssl_negotiate(H3270 *hSession)
57 63 non_blocking(hSession,False);
58 64  
59 65 /* Initialize the SSL library. */
60   - ssl_init(hSession);
61   - if(hSession->ssl_con == NULL)
  66 + if(ssl_init(hSession))
62 67 {
63 68 /* Failed. */
64   - popup_an_error(hSession,_( "SSL init failed!"));
65 69 lib3270_disconnect(hSession);
66 70 return -1;
67 71 }
... ... @@ -69,10 +73,17 @@ int ssl_negotiate(H3270 *hSession)
69 73 /* Set up the TLS/SSL connection. */
70 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 87 return -1;
77 88 }
78 89  
... ... @@ -84,51 +95,60 @@ int ssl_negotiate(H3270 *hSession)
84 95 {
85 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 111 lib3270_disconnect(hSession);
110 112 return -1;
111 113 }
112 114  
113 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 134 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_DS_TRACE))
115 135 {
116 136 char buffer[4096];
117 137 int alg_bits = 0;
118 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 140 trace_dsn(hSession,"TLS/SSL cipher description: %s",SSL_CIPHER_description((SSL_CIPHER *) cipher, buffer, 4095));
124 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 143 SSL_CIPHER_get_name(cipher),
127 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 153 BIO * out = BIO_new(BIO_s_mem());
134 154 unsigned char * data;
... ... @@ -149,10 +169,11 @@ int ssl_negotiate(H3270 *hSession)
149 169 X509_free(peer);
150 170  
151 171 }
152   - }
153 172  
154   - if(!SSL_get_verify_result(hSession->ssl_con))
155 173 set_ssl_state(hSession,LIB3270_SSL_SECURE);
  174 + X509_free(peer);
  175 + }
  176 +
156 177  
157 178 /* Tell the world that we are (still) connected, now in secure mode. */
158 179 lib3270_set_connected(hSession);
... ... @@ -162,25 +183,45 @@ int ssl_negotiate(H3270 *hSession)
162 183  
163 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 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 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 205 SSL_load_error_strings();
177 206 SSL_library_init();
  207 +
178 208 ssl_ctx = SSL_CTX_new(SSLv23_method());
179 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 226 SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
186 227 SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
... ... @@ -201,13 +242,50 @@ void ssl_init(H3270 *session)
201 242 strncat(data,"\\certs",4095);
202 243  
203 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 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 290 #endif // _WIN32
213 291  
... ... @@ -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 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 325 /* Callback for tracing protocol negotiation. */
... ...