Commit f904a1f79449cc98b4af57ac9c7f5c6de0248803

Authored by Perry Werneck
1 parent fa435363

Working on SSL API isolation.

lib3270.cbp
... ... @@ -212,7 +212,7 @@
212 212 <Unit filename="src/lib3270/sf.c">
213 213 <Option compilerVar="CC" />
214 214 </Unit>
215   - <Unit filename="src/lib3270/ssl/init.c">
  215 + <Unit filename="src/lib3270/ssl/ctx_init.c">
216 216 <Option compilerVar="CC" />
217 217 </Unit>
218 218 <Unit filename="src/lib3270/ssl/negotiate.c">
... ... @@ -250,6 +250,9 @@
250 250 </Unit>
251 251 <Unit filename="src/lib3270/windows/resources.rc" />
252 252 <Unit filename="src/lib3270/windows/resources.rc.in" />
  253 + <Unit filename="src/lib3270/windows/util.c">
  254 + <Option compilerVar="CC" />
  255 + </Unit>
253 256 <Extensions>
254 257 <code_completion />
255 258 <envvars />
... ...
src/include/lib3270.h
... ... @@ -804,6 +804,7 @@
804 804  
805 805 LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata );
806 806 LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id);
  807 + LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled);
807 808  
808 809 LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd);
809 810 LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag);
... ... @@ -823,6 +824,7 @@
823 824  
824 825 void * (*add_poll)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata);
825 826 void (*remove_poll)(H3270 *session, void *id);
  827 + void (*set_poll_state)(H3270 *session, void *id, int enabled);
826 828  
827 829 int (*Wait)(H3270 *hSession, int seconds);
828 830 int (*event_dispatcher)(H3270 *session, int wait);
... ...
src/lib3270/connect.c
... ... @@ -84,10 +84,10 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u
84 84 int err;
85 85 socklen_t len = sizeof(err);
86 86  
87   - if(hSession->ns_write_id) {
88   - trace("%s write=%p",__FUNCTION__,hSession->ns_write_id);
89   - lib3270_remove_poll(hSession, hSession->ns_write_id);
90   - hSession->ns_write_id = NULL;
  87 + if(hSession->xio.write) {
  88 + trace("%s write=%p",__FUNCTION__,hSession->xio.write);
  89 + lib3270_remove_poll(hSession, hSession->xio.write);
  90 + hSession->xio.write = NULL;
91 91 }
92 92  
93 93 if(getsockopt(hSession->sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0)
... ... @@ -125,8 +125,8 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u
125 125 return;
126 126 }
127 127  
128   - hSession->ns_exception_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
129   - hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0);
  128 + hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
  129 + hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0);
130 130  
131 131 #if defined(HAVE_LIBSSL)
132 132 if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)
... ... @@ -512,7 +512,7 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u
512 512 hSession->cstate = LIB3270_PENDING;
513 513 lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True);
514 514  
515   - hSession->ns_write_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_WRITE,net_connected,0);
  515 + hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_WRITE,net_connected,0);
516 516 // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected);
517 517  
518 518 trace("%s: Connection in progress",__FUNCTION__);
... ... @@ -558,57 +558,3 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u
558 558  
559 559 }
560 560  
561   -int non_blocking(H3270 *hSession, Boolean on)
562   -{
563   -#ifdef WIN32
564   - WSASetLastError(0);
565   - u_long iMode= on ? 1 : 0;
566   -
567   - if(ioctlsocket(hSession->sock,FIONBIO,&iMode))
568   - {
569   - lib3270_popup_dialog( hSession,
570   - LIB3270_NOTIFY_ERROR,
571   - _( "Connection error" ),
572   - _( "ioctlsocket(FIONBIO) failed." ),
573   - "%s", lib3270_win32_strerror(GetLastError()));
574   - return -1;
575   - }
576   -#else
577   -
578   - int f;
579   -
580   - if ((f = fcntl(hSession->sock, F_GETFL, 0)) == -1)
581   - {
582   - lib3270_popup_dialog( hSession,
583   - LIB3270_NOTIFY_ERROR,
584   - _( "Socket error" ),
585   - _( "fcntl() error when getting socket state." ),
586   - _( "%s" ), strerror(errno)
587   - );
588   -
589   - return -1;
590   - }
591   -
592   - if (on)
593   - f |= O_NDELAY;
594   - else
595   - f &= ~O_NDELAY;
596   -
597   - if (fcntl(hSession->sock, F_SETFL, f) < 0)
598   - {
599   - lib3270_popup_dialog( hSession,
600   - LIB3270_NOTIFY_ERROR,
601   - _( "Socket error" ),
602   - on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),
603   - _( "%s" ), strerror(errno)
604   - );
605   - return -1;
606   - }
607   -
608   -#endif
609   -
610   - trace("Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking");
611   -
612   - return 0;
613   -}
614   -
... ...
src/lib3270/iocalls.c
... ... @@ -36,6 +36,19 @@
36 36 #include "telnetc.h"
37 37 #include "utilc.h"
38 38  
  39 +#if defined(_WIN32)
  40 + #include <ws2tcpip.h>
  41 +#else
  42 + #include <sys/types.h>
  43 + #include <sys/socket.h>
  44 + #include <sys/ioctl.h>
  45 + #include <netinet/in.h>
  46 + #include <netdb.h>
  47 + #include <unistd.h>
  48 + #include <fcntl.h>
  49 +#endif
  50 +
  51 +
39 52 #define MILLION 1000000L
40 53 //
41 54 //#if defined(_WIN32)
... ... @@ -51,6 +64,8 @@
51 64 static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata );
52 65 static void internal_remove_poll(H3270 *session, void *id);
53 66  
  67 + static void internal_set_poll_state(H3270 *session, void *id, int enabled);
  68 +
54 69 static int internal_wait(H3270 *session, int seconds);
55 70  
56 71 static void internal_ring_bell(H3270 *session);
... ... @@ -71,6 +86,9 @@
71 86 static void (*remove_poll)(H3270 *session, void *id)
72 87 = internal_remove_poll;
73 88  
  89 + static void (*set_poll_state)(H3270 *session, void *id, int enabled)
  90 + = internal_set_poll_state;
  91 +
74 92 static int (*wait)(H3270 *session, int seconds)
75 93 = internal_wait;
76 94  
... ... @@ -246,11 +264,37 @@ static void internal_remove_poll(H3270 *session, void *id)
246 264 session->inputs_changed = 1;
247 265 }
248 266  
249   -LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) {
250   - debug("%s %p",__FUNCTION__,id);
  267 + static void internal_set_poll_state(H3270 *session, void *id, int enabled)
  268 + {
  269 + input_t *ip;
  270 + input_t *prev = (input_t *)NULL;
  271 +
  272 + for (ip = session->inputs; ip != (input_t *) NULL; ip = (input_t *) ip->next)
  273 + {
  274 + if (ip == (input_t *)id)
  275 + {
  276 + ip->enabled = enabled ? 1 : 0;
  277 + break;
  278 + }
  279 +
  280 + prev = ip;
  281 + }
  282 +
  283 + }
  284 +
  285 +
  286 +LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id)
  287 +{
  288 + debug("%s(%d,%p)",__FUNCTION__,session->sock,id);
251 289 remove_poll(session, id);
252 290 }
253 291  
  292 +LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled)
  293 +{
  294 + debug("%s(%d,%p,%d)",__FUNCTION__,session->sock,id,enabled);
  295 + set_poll_state(session, id, enabled);
  296 +}
  297 +
254 298 LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd)
255 299 {
256 300  
... ... @@ -288,6 +332,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_F
288 332 }
289 333  
290 334 LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ) {
  335 + debug("%s(%d)",__FUNCTION__,session->sock);
291 336 return add_poll(session,fd,flag,call,userdata);
292 337 }
293 338  
... ... @@ -330,39 +375,39 @@ void RemoveTimeOut(H3270 *session, void * timer)
330 375  
331 376 void x_except_on(H3270 *h)
332 377 {
333   - int reading = (h->ns_read_id != NULL);
  378 + int reading = (h->xio.read != NULL);
334 379  
335 380 debug("%s",__FUNCTION__);
336   - if(h->ns_exception_id)
  381 + if(h->xio.except)
337 382 return;
338 383  
339 384 if(reading)
340   - lib3270_remove_poll(h,h->ns_read_id);
  385 + lib3270_remove_poll(h,h->xio.read);
341 386  
342   - h->ns_exception_id = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
  387 + h->xio.except = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
343 388  
344 389 if(reading)
345   - h->ns_read_id = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_READ,net_input,0);
  390 + h->xio.read = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_READ,net_input,0);
346 391 debug("%s",__FUNCTION__);
347 392  
348 393 }
349 394  
350 395 void remove_input_calls(H3270 *session)
351 396 {
352   - if(session->ns_read_id)
  397 + if(session->xio.read)
353 398 {
354   - lib3270_remove_poll(session,session->ns_read_id);
355   - session->ns_read_id = NULL;
  399 + lib3270_remove_poll(session,session->xio.read);
  400 + session->xio.read = NULL;
356 401 }
357   - if(session->ns_exception_id)
  402 + if(session->xio.except)
358 403 {
359   - lib3270_remove_poll(session,session->ns_exception_id);
360   - session->ns_exception_id = NULL;
  404 + lib3270_remove_poll(session,session->xio.except);
  405 + session->xio.except = NULL;
361 406 }
362   - if(session->ns_write_id)
  407 + if(session->xio.write)
363 408 {
364   - lib3270_remove_poll(session,session->ns_write_id);
365   - session->ns_write_id = NULL;
  409 + lib3270_remove_poll(session,session->xio.write);
  410 + session->xio.write = NULL;
366 411 }
367 412 }
368 413  
... ... @@ -478,6 +523,65 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo
478 523  
479 524 }
480 525  
  526 +int non_blocking(H3270 *hSession, Boolean on)
  527 +{
  528 +
  529 + if(hSession->sock < 0)
  530 + return 0;
  531 +
  532 +#ifdef WIN32
  533 +
  534 + WSASetLastError(0);
  535 + u_long iMode= on ? 1 : 0;
  536 +
  537 + if(ioctlsocket(hSession->sock,FIONBIO,&iMode))
  538 + {
  539 + lib3270_popup_dialog( hSession,
  540 + LIB3270_NOTIFY_ERROR,
  541 + _( "Connection error" ),
  542 + _( "ioctlsocket(FIONBIO) failed." ),
  543 + "%s", lib3270_win32_strerror(GetLastError()));
  544 + return -1;
  545 + }
  546 +
  547 +#else
  548 +
  549 + int f;
  550 +
  551 + if ((f = fcntl(hSession->sock, F_GETFL, 0)) == -1)
  552 + {
  553 + lib3270_popup_dialog( hSession,
  554 + LIB3270_NOTIFY_ERROR,
  555 + _( "Socket error" ),
  556 + _( "fcntl() error when getting socket state." ),
  557 + _( "%s" ), strerror(errno)
  558 + );
  559 +
  560 + return -1;
  561 + }
  562 +
  563 + if (on)
  564 + f |= O_NDELAY;
  565 + else
  566 + f &= ~O_NDELAY;
  567 +
  568 + if (fcntl(hSession->sock, F_SETFL, f) < 0)
  569 + {
  570 + lib3270_popup_dialog( hSession,
  571 + LIB3270_NOTIFY_ERROR,
  572 + _( "Socket error" ),
  573 + on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),
  574 + _( "%s" ), strerror(errno)
  575 + );
  576 + return -1;
  577 + }
  578 +
  579 +#endif
  580 +
  581 + trace("Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking");
  582 +
  583 + return 0;
  584 +}
481 585  
482 586  
483 587  
... ...
src/lib3270/private.h
... ... @@ -599,9 +599,11 @@ struct _h3270
599 599 unsigned char saved_bg;
600 600  
601 601 // xio
602   - void * ns_read_id;
603   - void * ns_write_id;
604   - void * ns_exception_id;
  602 + struct {
  603 + void * read;
  604 + void * write;
  605 + void * except;
  606 + } xio;
605 607  
606 608 // SSL Data (Always defined to maintain the structure size)
607 609 struct
... ...
src/lib3270/ssl/ctx_init.c 0 → 100644
... ... @@ -0,0 +1,175 @@
  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(H3270 *hSession)
  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 + hSession->ssl.error = ERR_get_error();
  104 +
  105 + lib3270_write_log(
  106 + hSession,
  107 + "ssl",
  108 + "Cant set default locations for trusted CA certificates to %s\n%s",
  109 + data,
  110 + ERR_lib_error_string(hSession->ssl.error)
  111 + );
  112 +
  113 + }
  114 + }
  115 + RegCloseKey(hKey);
  116 + }
  117 +
  118 +
  119 + }
  120 +#else
  121 + static const char * ssldir[] =
  122 + {
  123 +#ifdef DATAROOTDIR
  124 + DATAROOTDIR "/" PACKAGE_NAME "/certs",
  125 +#endif // DATAROOTDIR
  126 +#ifdef SYSCONFDIR
  127 + SYSCONFDIR "/ssl/certs",
  128 + SYSCONFDIR "/certs",
  129 +#endif
  130 + "/etc/ssl/certs"
  131 + };
  132 +
  133 + size_t f;
  134 +
  135 + for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++)
  136 + {
  137 + SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]);
  138 + }
  139 +
  140 +#endif // _WIN32
  141 +
  142 + //
  143 + // Initialize CUSTOM CRL CHECK
  144 + //
  145 +
  146 +
  147 +/*
  148 +#if defined(SSL_ENABLE_CRL_CHECK)
  149 + // Set up CRL validation
  150 + // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
  151 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  152 +
  153 + // Enable CRL checking
  154 + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
  155 + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
  156 + X509_STORE_set1_param(store, param);
  157 + X509_VERIFY_PARAM_free(param);
  158 +
  159 + // X509_STORE_free(store);
  160 +
  161 + trace_dsn(hSession,"CRL CHECK is enabled.\n");
  162 +
  163 +#else
  164 +
  165 + trace_dsn(hSession,"CRL CHECK is disabled.\n");
  166 +
  167 +#endif // SSL_ENABLE_CRL_CHECK
  168 +*/
  169 +
  170 + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
  171 +
  172 + return 0;
  173 +}
  174 +
  175 +#endif // HAVE_LIBSSL
... ...
src/lib3270/ssl/init.c
... ... @@ -1,177 +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   - * @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(H3270 *hSession)
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
... ... @@ -70,6 +70,15 @@
70 70 */
71 71 SSL_CTX * ssl_ctx = NULL;
72 72  
  73 +struct ssl_error_message
  74 +{
  75 + int error;
  76 + const char * title;
  77 + const char * text;
  78 + const char * description;
  79 +};
  80 +
  81 +
73 82 /**
74 83 * @brief Initialize openssl session.
75 84 *
... ... @@ -78,7 +87,8 @@
78 87 * @return 0 if ok, non zero if fails.
79 88 *
80 89 */
81   -int ssl_init(H3270 *hSession)
  90 +
  91 +static int background_ssl_init(H3270 *hSession, void *message)
82 92 {
83 93 set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
84 94 hSession->ssl.error = 0;
... ... @@ -86,21 +96,13 @@ int ssl_init(H3270 *hSession)
86 96  
87 97 if(ssl_ctx_init(hSession)) {
88 98  
89   - hSession->ssl.error = ERR_get_error();
90   -
91   - /*
92   - lib3270_popup_dialog(
93   - hSession,
94   - LIB3270_NOTIFY_ERROR,
95   - N_( "Security error" ),
96   - N_( "SSL initialization has failed" ),
97   - "%s",ERR_reason_error_string(hSession->ssl.error)
98   - );
99   - */
  99 + ((struct ssl_error_message *) message)->error = hSession->ssl.error = ERR_get_error();
  100 + ((struct ssl_error_message *) message)->title = N_( "Security error" );
  101 + ((struct ssl_error_message *) message)->text = N_( "SSL context initialization has failed" );
100 102  
101 103 set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
102   -
103 104 hSession->ssl.host = False;
  105 +
104 106 return -1;
105 107 }
106 108  
... ... @@ -110,43 +112,28 @@ int ssl_init(H3270 *hSession)
110 112 hSession->ssl.con = SSL_new(ssl_ctx);
111 113 if(hSession->ssl.con == NULL)
112 114 {
113   - hSession->ssl.error = ERR_get_error();
114   -
115   - /*
116   - lib3270_popup_dialog(
117   - hSession,
118   - LIB3270_NOTIFY_ERROR,
119   - N_( "Security error" ),
120   - N_( "Cant create a new SSL structure for current connection." ),
121   - N_( "%s" ),ERR_lib_error_string(hSession->ssl.error)
122   - );
123   - */
124   -
  115 + ((struct ssl_error_message *) message)->error = hSession->ssl.error = ERR_get_error();
  116 + ((struct ssl_error_message *) message)->title = N_( "Security error" );
  117 + ((struct ssl_error_message *) message)->text = N_( "Cant create a new SSL structure for current connection." );
125 118 return -1;
126 119 }
127 120  
128 121 SSL_set_ex_data(hSession->ssl.con,ssl_3270_ex_index,(char *) hSession);
129   -
130 122 // SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
131 123 SSL_set_verify(hSession->ssl.con, 0, NULL);
132 124  
133 125 return 0;
134 126 }
135 127  
136   -int ssl_negotiate(H3270 *hSession)
  128 +static int background_ssl_negotiation(H3270 *hSession, void *message)
137 129 {
138 130 int rv;
139 131  
140 132 trace("%s",__FUNCTION__);
141 133  
142   - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
143   - non_blocking(hSession,False);
144   -
145 134 /* Initialize the SSL library. */
146   - if(ssl_init(hSession))
  135 + if(background_ssl_init(hSession,message))
147 136 {
148   - /* Failed. */
149   - lib3270_disconnect(hSession);
150 137 return -1;
151 138 }
152 139  
... ... @@ -155,15 +142,10 @@ int ssl_negotiate(H3270 *hSession)
155 142 {
156 143 trace_dsn(hSession,"%s","SSL_set_fd failed!\n");
157 144  
158   - lib3270_popup_dialog(
159   - hSession,
160   - LIB3270_NOTIFY_ERROR,
161   - N_( "Security error" ),
162   - N_( "SSL negotiation failed" ),
163   - "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." )
164   - );
  145 + ((struct ssl_error_message *) message)->title = N_( "Security error" );
  146 + ((struct ssl_error_message *) message)->text = N_( "SSL negotiation failed" );
  147 + ((struct ssl_error_message *) message)->description = N_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." );
165 148  
166   - lib3270_disconnect(hSession);
167 149 return -1;
168 150 }
169 151  
... ... @@ -173,29 +155,24 @@ int ssl_negotiate(H3270 *hSession)
173 155  
174 156 if (rv != 1)
175 157 {
176   - int ssl_error = SSL_get_error(hSession->ssl.con,rv);
177 158 const char * msg = "";
178 159  
179   - if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl.error)
180   - ssl_error = hSession->ssl.error;
  160 + ((struct ssl_error_message *) message)->error = SSL_get_error(hSession->ssl.con,rv);
  161 + if(((struct ssl_error_message *) message)->error == SSL_ERROR_SYSCALL && hSession->ssl.error)
  162 + ((struct ssl_error_message *) message)->error = hSession->ssl.error;
181 163  
182   - msg = ERR_lib_error_string(ssl_error);
  164 + msg = ERR_lib_error_string(((struct ssl_error_message *) message)->error);
183 165  
184 166 trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl.error));
185 167  
186   - lib3270_popup_dialog(
187   - hSession,
188   - LIB3270_NOTIFY_ERROR,
189   - N_( "Security error" ),
190   - N_( "SSL Connect failed" ),
191   - "%s",msg ? msg : ""
192   - );
193   -
  168 + ((struct ssl_error_message *) message)->title = N_( "Security error" );
  169 + ((struct ssl_error_message *) message)->text = N_( "SSL Connect failed" );
194 170 lib3270_disconnect(hSession);
195 171 return -1;
  172 +
196 173 }
197 174  
198   - /* Success. */
  175 + // Success.
199 176 X509 * peer = NULL;
200 177 rv = SSL_get_verify_result(hSession->ssl.con);
201 178  
... ... @@ -208,13 +185,11 @@ int ssl_negotiate(H3270 *hSession)
208 185  
209 186 case X509_V_ERR_UNABLE_TO_GET_CRL:
210 187 trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" );
211   - lib3270_disconnect(hSession);
212   - lib3270_popup_dialog( hSession,
213   - LIB3270_NOTIFY_ERROR,
214   - _( "SSL error" ),
215   - _( "Unable to get certificate CRL." ),
216   - _( "The Certificate revocation list (CRL) of a certificate could not be found." )
217   - );
  188 +
  189 + ((struct ssl_error_message *) message)->title = _( "SSL error" );
  190 + ((struct ssl_error_message *) message)->text = _( "Unable to get certificate CRL." );
  191 + ((struct ssl_error_message *) message)->description = _( "The Certificate revocation list (CRL) of a certificate could not be found." );
  192 +
218 193 return -1;
219 194  
220 195 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
... ... @@ -224,14 +199,9 @@ int ssl_negotiate(H3270 *hSession)
224 199 #ifdef SSL_ALLOW_SELF_SIGNED_CERT
225 200 break;
226 201 #else
227   - lib3270_disconnect(hSession);
228   - lib3270_popup_dialog( hSession,
229   - LIB3270_NOTIFY_ERROR,
230   - _( "SSL error" ),
231   - _( "The SSL certificate for this host is not trusted." ),
232   - _( "The security certificate presented by this host was not issued by a trusted certificate authority." )
233   - );
234   -
  202 + ((struct ssl_error_message *) message)->title = _( "SSL error" );
  203 + ((struct ssl_error_message *) message)->text = _( "The SSL certificate for this host is not trusted." );
  204 + ((struct ssl_error_message *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." );
235 205 return -1;
236 206 #endif // SSL_ALLOW_SELF_SIGNED_CERT
237 207  
... ... @@ -286,11 +256,65 @@ int ssl_negotiate(H3270 *hSession)
286 256  
287 257 /* Tell the world that we are (still) connected, now in secure mode. */
288 258 lib3270_set_connected_initial(hSession);
289   - non_blocking(hSession,True);
290 259  
291 260 return 0;
292 261 }
293 262  
  263 +int ssl_negotiate(H3270 *hSession)
  264 +{
  265 + int rc;
  266 + struct ssl_error_message msg;
  267 +
  268 + memset(&msg,0,sizeof(msg));
  269 +
  270 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
  271 + non_blocking(hSession,False);
  272 +
  273 + rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg);
  274 + if(rc)
  275 + {
  276 + // SSL Negotiation has failed.
  277 + if(msg.description)
  278 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description);
  279 + else
  280 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error));
  281 +
  282 + lib3270_disconnect(hSession);
  283 +
  284 + }
  285 +
  286 + non_blocking(hSession,True);
  287 +
  288 + return rc;
  289 +}
  290 +
  291 +int ssl_init(H3270 *hSession) {
  292 +
  293 + int rc;
  294 + struct ssl_error_message msg;
  295 +
  296 + memset(&msg,0,sizeof(msg));
  297 +
  298 + non_blocking(hSession,False);
  299 +
  300 + rc = lib3270_run_task(hSession, background_ssl_init, &msg);
  301 + if(rc)
  302 + {
  303 + // SSL init has failed.
  304 + if(msg.description)
  305 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description);
  306 + else
  307 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error));
  308 +
  309 + lib3270_disconnect(hSession);
  310 + }
  311 +
  312 + non_blocking(hSession,True);
  313 +
  314 + return rc;
  315 +
  316 +}
  317 +
294 318 /* Callback for tracing protocol negotiation. */
295 319 void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
296 320 {
... ... @@ -352,7 +376,7 @@ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
352 376 );
353 377  
354 378 }
355   -
  379 + break;
356 380  
357 381 default:
358 382 trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s));
... ...
src/lib3270/telnet.c
... ... @@ -908,10 +908,10 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
908 908 }
909 909 #endif
910 910  
911   - if(hSession->ns_write_id)
  911 + if(hSession->xio.write)
912 912 {
913   - lib3270_remove_poll(hSession, hSession->ns_write_id);
914   - hSession->ns_write_id = 0;
  913 + lib3270_remove_poll(hSession, hSession->xio.write);
  914 + hSession->xio.write = 0;
915 915 }
916 916  
917 917 if(hSession->sock >= 0)
... ... @@ -1964,10 +1964,10 @@ void net_exception(H3270 *session, int fd unused, LIB3270_IO_FLAG flag unused, v
1964 1964 {
1965 1965 session->syncing = 1;
1966 1966  
1967   - if(session->ns_exception_id)
  1967 + if(session->xio.except)
1968 1968 {
1969   - lib3270_remove_poll(session, session->ns_exception_id);
1970   - session->ns_exception_id = NULL;
  1969 + lib3270_remove_poll(session, session->xio.except);
  1970 + session->xio.except = NULL;
1971 1971 }
1972 1972 }
1973 1973 }
... ...
src/lib3270/util.c
... ... @@ -35,21 +35,9 @@
35 35 #define _GNU_SOURCE
36 36  
37 37 #include "private.h"
38   -// #include <pwd.h>
39   -
40   -//#ifdef HAVE_ICONV
41   -// #include <iconv.h>
42   -//#endif // HAVE_ICONV
43   -
44   -//#include <stdarg.h>
45   -// #include "resources.h"
46   -
47 38 #include "utilc.h"
48   -//#include "popupsc.h"
49   -//#include "api.h"
50   -
51   -//#include <lib3270/session.h>
52   -//#include <lib3270/selection.h>
  39 +#include "popupsc.h"
  40 +#include <lib3270/selection.h>
53 41  
54 42 #define my_isspace(c) isspace((unsigned char)c)
55 43  
... ...