Commit 889dfbb24a4dfb839bb3d1d3392fcc0007a426e6

Authored by Perry Werneck
1 parent 7a87d265

Implementing openssl network module.

lib3270.cbp
... ... @@ -310,6 +310,9 @@
310 310 <Unit filename="src/network_modules/linux/connect.c">
311 311 <Option compilerVar="CC" />
312 312 </Unit>
  313 + <Unit filename="src/network_modules/openssl.c">
  314 + <Option compilerVar="CC" />
  315 + </Unit>
313 316 <Unit filename="src/network_modules/private.h" />
314 317 <Unit filename="src/network_modules/unsecure.c">
315 318 <Option compilerVar="CC" />
... ...
src/core/connect.c
... ... @@ -54,23 +54,6 @@
54 54  
55 55 }
56 56  
57   -
58   -#if defined(HAVE_LIBSSL)
59   -
60   - static int background_ssl_init(H3270 *hSession, void *ssl_error)
61   - {
62   - if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) ssl_error))
63   - return -1;
64   -
65   -#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
66   - lib3270_crl_free_if_expired(hSession);
67   -#endif // defined(SSL_ENABLE_CRL_CHECK)
68   -
69   - return 0;
70   - }
71   -
72   -#endif // HAVE_LIBSSL
73   -
74 57 /*
75 58 void connection_failed(H3270 *hSession, const char *message)
76 59 {
... ... @@ -141,28 +124,13 @@
141 124 return errno == 0 ? -1 : errno;
142 125 }
143 126  
144   -#if defined(HAVE_LIBSSL)
145   - debug("%s: TLS/SSL is %s",__FUNCTION__,hSession->ssl.enabled ? "ENABLED" : "DISABLED")
146   - trace_dsn(hSession,"TLS/SSL is %s\n", hSession->ssl.enabled ? "enabled" : "disabled" );
147   -
148   - if(hSession->ssl.enabled)
149   - {
150   - SSL_ERROR_MESSAGE ssl_error;
151   - memset(&ssl_error,0,sizeof(ssl_error));
  127 +// debug("%s: TLS/SSL is %s",__FUNCTION__,hSession->ssl.enabled ? "ENABLED" : "DISABLED")
  128 +// trace_dsn(hSession,"TLS/SSL is %s\n", hSession->ssl.enabled ? "enabled" : "disabled" );
152 129  
153   - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
154   - int rc = lib3270_run_task(hSession, background_ssl_init, &ssl_error);
155   -
156   - if(rc && popup_ssl_error(hSession, rc, &ssl_error))
157   - return errno = rc;
158   -
159   - set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
160   - hSession->ssl.host = 0;
161   - }
162   -#endif // HAVE_LIBSSL
  130 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
  131 + // hSession->ssl.host = 0;
163 132  
164 133 snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num);
165   -
166 134 lib3270_write_event_trace(hSession,"Reconnecting to %s\n",lib3270_get_url(hSession));
167 135  
168 136 hSession->ever_3270 = False;
... ... @@ -175,32 +143,34 @@
175 143 {
176 144 int rc = 0;
177 145  
178   - if(hSession->network.module->start_tls,required)
179   - {
180   - LIB3270_NETWORK_STATE state;
181   - memset(&state,0,sizeof(state));
  146 + hSession->ssl.required = (required ? 1 : 0);
182 147  
183   - non_blocking(hSession,False);
  148 + LIB3270_NETWORK_STATE state;
  149 + memset(&state,0,sizeof(state));
184 150  
185   - rc = lib3270_run_task(
186   - hSession,
187   - (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
188   - &state
189   - );
  151 + non_blocking(hSession,False);
190 152  
191   - if(state.popup) {
192   - if(lib3270_popup(hSession,state.popup,1)) {
193   - lib3270_disconnect(hSession);
194   - return rc;
195   - }
  153 + rc = lib3270_run_task(
  154 + hSession,
  155 + (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
  156 + &state
  157 + );
196 158  
197   - // User has selected "continue", ignore error.
198   - return 0;
199   - }
  159 + if(required && rc) {
  160 +
  161 + // SSL is required and TLS/SSL has failed, abort.
  162 +
  163 + lib3270_popup(hSession,state.popup,0);
  164 + lib3270_disconnect(hSession);
  165 + return rc;
200 166  
201 167 }
202 168  
203   - return rc;
  169 + // Not required or success
  170 +
  171 + non_blocking(hSession,True);
  172 +
  173 + return 0;
204 174 }
205 175  
206 176  
... ...
src/core/telnet.c
... ... @@ -707,13 +707,13 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
707 707 }
708 708 else if (nr == 0)
709 709 {
710   - /* Host disconnected. */
  710 + // Host disconnected.
711 711 trace_dsn(hSession,"RCVD disconnect\n");
712 712 host_disconnect(hSession,False);
713 713 return;
714 714 }
715 715  
716   - /* Process the data. */
  716 + // Process the data.
717 717 if (HALF_CONNECTED)
718 718 {
719 719 if (non_blocking(hSession,False) < 0)
... ...
src/include/internals.h
... ... @@ -666,34 +666,6 @@ struct _h3270
666 666 void * except;
667 667 } xio;
668 668  
669   -#ifdef HAVE_LIBSSL
670   - /// @brief SSL Data.
671   - struct
672   - {
673   - char enabled;
674   - char host;
675   - LIB3270_SSL_STATE state;
676   - unsigned long error;
677   -
678   - struct
679   - {
680   - int min_version; ///< @brief The minimum supported protocol version.
681   - int max_version; ///< @brief The maximum supported protocol version.
682   - } protocol;
683   -
684   -#ifdef SSL_ENABLE_CRL_CHECK
685   - struct
686   - {
687   - char download; ///< @brief Non zero to download CRL.
688   - char * prefer; ///< @brief Prefered protocol for CRL.
689   - char * url; ///< @brief URL for CRL download.
690   - X509_CRL * cert; ///< @brief Loaded CRL (can be null).
691   - } crl;
692   -#endif // SSL_ENABLE_CRL_CHECK
693   - SSL * con;
694   - } ssl;
695   -#endif // HAVE_LIBSSL
696   -
697 669 struct lib3270_linked_list_head timeouts;
698 670  
699 671 struct
... ... @@ -709,6 +681,13 @@ struct _h3270
709 681 void *userdata;
710 682 } trace;
711 683  
  684 + struct
  685 + {
  686 + int error; ///< @brief OpenSSL error.
  687 + unsigned char required; ///< @brief Non zero if SSL is required.
  688 + LIB3270_SSL_STATE state;
  689 + } ssl;
  690 +
712 691 /// @brief Event Listeners.
713 692 struct
714 693 {
... ... @@ -795,6 +774,9 @@ LIB3270_INTERNAL int check_offline_session(const H3270 *hSession);
795 774  
796 775 LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
797 776  
  777 +LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
  778 +
  779 +/*
798 780 #if defined(HAVE_LIBSSL)
799 781  
800 782 typedef struct ssl_status_msg
... ... @@ -820,44 +802,25 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
820 802 LIB3270_INTERNAL int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE *message);
821 803 LIB3270_INTERNAL int ssl_init(H3270 *session);
822 804 LIB3270_INTERNAL int ssl_negotiate(H3270 *hSession);
823   - LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
824 805 LIB3270_INTERNAL const struct ssl_status_msg * ssl_get_status_from_error_code(long id);
825 806  
826 807  
827   - #if OPENSSL_VERSION_NUMBER >= 0x00907000L
828   - #define INFO_CONST const
829   - #else
830   - #define INFO_CONST
831   - #endif
832 808  
833 809 LIB3270_INTERNAL void ssl_info_callback(INFO_CONST SSL *s, int where, int ret);
834 810  
835   - /**
836   - * @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections.
837   - *
838   - */
  811 + // @brief Global SSL_CTX object as framework to establish TLS/SSL or DTLS enabled connections.
839 812 LIB3270_INTERNAL SSL_CTX * ssl_ctx;
840 813  
841   - /**
842   - * @brief Index of h3270 handle in SSL session.
843   - *
844   - */
845   - LIB3270_INTERNAL int ssl_3270_ex_index;
846 814  
847   - /**
848   - * @brief Emit popup on ssl error.
849   - *
850   - */
  815 +
  816 + /// @brief Emit popup on ssl error.
851 817 LIB3270_INTERNAL int popup_ssl_error(H3270 *session, int rc, const SSL_ERROR_MESSAGE *message);
852 818  
853   - /**
854   - * @brief Emits SSL popup.
855   - *
856   - *
857   - */
  819 + /// @brief Emits SSL popup.
858 820 LIB3270_INTERNAL void ssl_popup_message(H3270 *hSession, const SSL_ERROR_MESSAGE *msg);
859 821  
860 822 #endif
  823 +*/
861 824  
862 825 /// @brief Clear element at adress.
863 826 LIB3270_INTERNAL void clear_chr(H3270 *hSession, int baddr);
... ...
src/include/networking.h
... ... @@ -76,7 +76,7 @@
76 76 ///
77 77 int (*disconnect)(H3270 *hSession);
78 78  
79   - int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg, unsigned char required);
  79 + int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg);
80 80  
81 81 /// @brief Send on network context.
82 82 ///
... ... @@ -104,7 +104,7 @@
104 104 /// @brief Check if the session is online.
105 105 ///
106 106 /// @retval 0 The session is offline.
107   - int (*is_connected)(H3270 *hSession);
  107 + int (*is_connected)(const H3270 *hSession);
108 108  
109 109 /// @brief get socket name.
110 110 ///
... ... @@ -136,5 +136,8 @@
136 136 */
137 137 LIB3270_INTERNAL int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state);
138 138  
  139 +
  140 + LIB3270_INTERNAL void * lib3270_get_openssl_context(H3270 *hSession, LIB3270_NETWORK_STATE *state);
  141 +
139 142 #endif // LIB3270_NETWORKING_H_INCLUDED
140 143  
... ...
src/network_modules/openssl.c 0 → 100644
... ... @@ -0,0 +1,213 @@
  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 ', 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 openssl.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 de Mendonça)
  27 + *
  28 + */
  29 +
  30 + /**
  31 + * @brief OpenSSL based networking methods.
  32 + *
  33 + */
  34 +
  35 + #include "private.h"
  36 +
  37 + #include <sys/types.h>
  38 + #include <sys/socket.h>
  39 + #include <netdb.h>
  40 + #include <openssl/ssl.h>
  41 + #include <openssl/x509.h>
  42 +
  43 + struct _lib3270_net_context {
  44 +
  45 + int sock; ///< @brief Session socket.
  46 +
  47 + SSL * con; ///< @brief SSL Connection handle.
  48 +
  49 + struct {
  50 + char download; ///< @brief Non zero to download CRL.
  51 + char * prefer; ///< @brief Prefered protocol for CRL.
  52 + char * url; ///< @brief URL for CRL download.
  53 + X509_CRL * cert; ///< @brief Loaded CRL (can be null).
  54 + } crl;
  55 +
  56 + };
  57 +
  58 +static void crl_free(LIB3270_NET_CONTEXT *context) {
  59 + if(context->crl.cert) {
  60 + X509_CRL_free(context->crl.cert);
  61 + context->crl.cert = NULL;
  62 + }
  63 +}
  64 +
  65 +static void openssl_network_finalize(H3270 *hSession) {
  66 +
  67 + debug("%s",__FUNCTION__);
  68 +
  69 +
  70 + if(hSession->network.context) {
  71 +
  72 + // Cleanupp
  73 + LIB3270_NET_CONTEXT *context = hSession->network.context;
  74 +
  75 + crl_free(context);
  76 +
  77 + // Release network context.
  78 + lib3270_free(hSession->network.context);
  79 + hSession->network.context = NULL;
  80 + }
  81 +
  82 +}
  83 +
  84 +static int openssl_network_disconnect(H3270 *hSession) {
  85 +
  86 +
  87 +}
  88 +
  89 +ssize_t openssl_network_send(H3270 *hSession, const void *buffer, size_t length) {
  90 +
  91 +}
  92 +
  93 +static ssize_t openssl_network_recv(H3270 *hSession, void *buf, size_t len) {
  94 +
  95 +}
  96 +
  97 +static int openssl_network_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
  98 +
  99 +}
  100 +
  101 +static void * openssl_network_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) {
  102 +
  103 +}
  104 +
  105 +static int openssl_network_non_blocking(H3270 *hSession, const unsigned char on) {
  106 +
  107 +}
  108 +
  109 +static int openssl_network_is_connected(H3270 *hSession) {
  110 +
  111 +}
  112 +
  113 +static int openssl_network_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) {
  114 +
  115 +}
  116 +
  117 +static int openssl_network_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) {
  118 +}
  119 +
  120 +static int openssl_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  121 +
  122 + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
  123 +
  124 + SSL_CTX * ctx_context = (SSL_CTX *) lib3270_get_openssl_context(state,state);
  125 + if(!ctx_context)
  126 + return -1;
  127 +
  128 + //
  129 + // Prepare for connection
  130 + //
  131 + LIB3270_NET_CONTEXT *context = hSession->network.context;
  132 +
  133 + if(context->crl.cert) {
  134 +
  135 + // Release CRL if expired.
  136 + // https://stackoverflow.com/questions/23407376/testing-x509-certificate-expiry-date-with-c
  137 + // X509_CRL_get_nextUpdate is deprecated in openssl 1.1.0
  138 +
  139 + #if OPENSSL_VERSION_NUMBER < 0x10100000L
  140 + const ASN1_TIME * next_update = X509_CRL_get_nextUpdate(context->crl.cert);
  141 + #else
  142 + const ASN1_TIME * next_update = X509_CRL_get0_nextUpdate(context->crl.cert);
  143 + #endif
  144 +
  145 + if(X509_cmp_current_time(next_update) == 1)
  146 + {
  147 + int day, sec;
  148 + if(ASN1_TIME_diff(&day, &sec, NULL, next_update))
  149 + {
  150 + trace_ssl(hSession,"CRL is valid for %d day(s) and %d second(s)\n",day,sec);
  151 + }
  152 + else
  153 + {
  154 + trace_ssl(hSession,"Can't get CRL next update, discarding it\n");
  155 + crl_free(context);
  156 + }
  157 +
  158 + }
  159 + else
  160 + {
  161 + trace_ssl(hSession,"CRL is no longer valid\n");
  162 + crl_free(context);
  163 + }
  164 +
  165 + }
  166 +
  167 + //
  168 + // Connect to host.
  169 + //
  170 + context->sock = lib3270_network_connect(hSession, state);
  171 +
  172 + return (context->sock < 0 ? -1 : 0);
  173 +
  174 +}
  175 +
  176 +static int openssl_network_start_tls(H3270 *hSession, LIB3270_NETWORK_STATE *msg) {
  177 +
  178 + LIB3270_NET_CONTEXT * context = hSession->network.context;
  179 +
  180 +
  181 +}
  182 +
  183 +void lib3270_set_openssl_network_module(H3270 *hSession) {
  184 +
  185 + static const LIB3270_NET_MODULE module = {
  186 + .finalize = openssl_network_finalize,
  187 + .connect = openssl_network_connect,
  188 + .disconnect = openssl_network_disconnect,
  189 + .start_tls = openssl_network_start_tls,
  190 + .send = openssl_network_send,
  191 + .recv = openssl_network_recv,
  192 + .add_poll = openssl_network_add_poll,
  193 + .non_blocking = openssl_network_non_blocking,
  194 + .is_connected = openssl_network_is_connected,
  195 + .getsockname = openssl_network_getsockname,
  196 + .setsockopt = openssl_network_setsockopt,
  197 + .getsockopt = openssl_network_getsockopt
  198 + };
  199 +
  200 + debug("%s",__FUNCTION__);
  201 +
  202 + if(hSession->network.context) {
  203 + // Has context, finalize it.
  204 + hSession->network.module->finalize(hSession);
  205 + }
  206 +
  207 + hSession->network.context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT));
  208 + memset(hSession->network.context,0,sizeof(LIB3270_NET_CONTEXT));
  209 +
  210 +
  211 +
  212 + hSession->network.module = &module;
  213 +}
... ...
src/network_modules/unsecure.c
... ... @@ -18,7 +18,7 @@
18 18 * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19 19 * St, Fifth Floor, Boston, MA 02110-1301 USA
20 20 *
21   - * Este programa está nomeado como networking.h e possui - linhas de código.
  21 + * Este programa está nomeado como unsecure.c e possui - linhas de código.
22 22 *
23 23 * Contatos:
24 24 *
... ... @@ -213,7 +213,7 @@ static int unsecure_network_non_blocking(H3270 *hSession, const unsigned char on
213 213 return 0;
214 214 }
215 215  
216   -static int unsecure_network_is_connected(H3270 *hSession) {
  216 +static int unsecure_network_is_connected(const H3270 *hSession) {
217 217 return hSession->network.context->sock > 0;
218 218 }
219 219  
... ... @@ -247,9 +247,9 @@ static int unsecure_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *stat
247 247 return 0;
248 248 }
249 249  
250   -static int unsecure_network_start_tls(H3270 GNUC_UNUSED(*hSession), LIB3270_NETWORK_STATE *msg, unsigned char required) {
  250 +static int unsecure_network_start_tls(H3270 GNUC_UNUSED(*hSession), LIB3270_NETWORK_STATE *msg) {
251 251  
252   - if(required) {
  252 + if(hSession->ssl.required) {
253 253  
254 254 // TODO: Replace network module with the openssl version, initialize and execute start_tls on it.
255 255  
... ...
src/ssl/crl.h
... ... @@ -66,9 +66,6 @@
66 66 /// @brief Unconditional release of the session CRL.
67 67 LIB3270_INTERNAL void lib3270_crl_free(H3270 *hSession);
68 68  
69   - /// @brief Release CRL if expired.
70   - LIB3270_INTERNAL void lib3270_crl_free_if_expired(H3270 *hSession);
71   -
72 69 /// @brief Load CRL from URL.
73 70 LIB3270_INTERNAL int lib3270_crl_new_from_url(H3270 *hSession, void *ssl_error, const char *url);
74 71  
... ...
src/ssl/linux/init.c
... ... @@ -35,13 +35,10 @@
35 35  
36 36 /**
37 37 * @brief OpenSSL initialization for linux.
38   - *
39 38 */
40 39  
41 40 #include <config.h>
42 41  
43   -#if defined(HAVE_LIBSSL)
44   -
45 42 #include <openssl/ssl.h>
46 43 #include <openssl/err.h>
47 44 #include <openssl/x509_vfy.h>
... ... @@ -51,63 +48,138 @@
51 48 #endif // !SSL_ST_OK
52 49  
53 50 #include <internals.h>
54   -#include <errno.h>
55   -#include <lib3270.h>
56   -#include <lib3270/internals.h>
57   -#include <lib3270/trace.h>
  51 +#include <networking.h>
58 52 #include <lib3270/log.h>
59   -#include "trace_dsc.h"
60 53  
61 54 #ifdef SSL_ENABLE_CRL_CHECK
62   - #include <openssl/x509.h>
63 55 #endif // SSL_ENABLE_CRL_CHECK
64 56  
  57 +#if OPENSSL_VERSION_NUMBER >= 0x00907000L
  58 + #define INFO_CONST const
  59 +#else
  60 + #define INFO_CONST
  61 +#endif
  62 +
65 63 /*--[ Implement ]------------------------------------------------------------------------------------*/
66 64  
67   -/**
68   - * @brief Initialize openssl library.
69   - *
70   - * @return 0 if ok, non zero if fails.
71   - *
72   - */
73   -int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
  65 +// @brief Index of h3270 handle in SSL session.
  66 +static int ssl_3270_ex_index;
  67 +
  68 +/// @brief Callback for tracing protocol negotiation.
  69 +static void info_callback(INFO_CONST SSL *s, int where, int ret)
74 70 {
75   - debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx);
  71 + H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index);
76 72  
77   - if(ssl_ctx)
78   - return 0;
  73 + switch(where)
  74 + {
  75 + case SSL_CB_CONNECT_LOOP:
  76 + trace_ssl(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s));
  77 + break;
  78 +
  79 + case SSL_CB_CONNECT_EXIT:
  80 +
  81 + trace_ssl(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__);
  82 +
  83 + if (ret == 0)
  84 + {
  85 + trace_ssl(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s));
  86 + }
  87 + else if (ret < 0)
  88 + {
  89 + unsigned long e = ERR_get_error();
  90 + char err_buf[1024];
  91 +
  92 + if(e != 0)
  93 + {
  94 + hSession->ssl.error = e;
  95 + (void) ERR_error_string_n(e, err_buf, 1023);
  96 + }
  97 +#if defined(_WIN32)
  98 + else if (GetLastError() != 0)
  99 + {
  100 + strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023);
  101 + }
  102 +#else
  103 + else if (errno != 0)
  104 + {
  105 + strncpy(err_buf, strerror(errno),1023);
  106 + }
  107 +#endif
  108 + else
  109 + {
  110 + err_buf[0] = '\0';
  111 + }
  112 +
  113 + trace_ssl(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n",
  114 + ret,
  115 + err_buf,
  116 + SSL_state_string_long(s),
  117 + SSL_alert_type_string_long(ret)
  118 + );
  119 +
  120 + }
  121 + break;
  122 +
  123 + default:
  124 + trace_ssl(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s));
  125 + }
  126 +
  127 +#ifdef DEBUG
  128 + if(where & SSL_CB_EXIT)
  129 + {
  130 + trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret);
  131 + }
  132 +#endif
  133 +
  134 + if(where & SSL_CB_ALERT)
  135 + trace_ssl(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret));
  136 +
  137 + if(where & SSL_CB_HANDSHAKE_DONE)
  138 + {
  139 + trace_ssl(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s));
  140 + if(SSL_get_state(s) == SSL_ST_OK)
  141 + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
  142 + else
  143 + set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
  144 + }
  145 +}
  146 +
  147 +void * lib3270_get_openssl_context(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
  148 +
  149 + static SSL_CTX * context = NULL;
  150 +
  151 + if(context)
  152 + return context;
79 153  
80 154 trace_ssl(hSession,"Initializing SSL context.\n");
81 155  
82 156 SSL_load_error_strings();
83 157 SSL_library_init();
84 158  
85   - ssl_ctx = SSL_CTX_new(SSLv23_method());
86   - if(ssl_ctx == NULL)
  159 + context = SSL_CTX_new(SSLv23_method());
  160 + if(context == NULL)
87 161 {
88 162 static const LIB3270_POPUP popup = {
89   - .name = "SSL-CTXERROR",
90 163 .type = LIB3270_NOTIFY_SECURE,
91   - .summary = N_( "Cant initialize the SSL context." )
  164 + .summary = N_( "Can't initialize the SSL context." )
92 165 };
93 166  
94   - message->code = hSession->ssl.error = ERR_get_error();
95   - message->popup = &popup;
  167 +// message->code = hSession->ssl.error = ERR_get_error();
  168 + state->popup = &popup;
96 169 return -1;
97 170 }
98 171  
99   - SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
100   - SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
  172 + SSL_CTX_set_options(context, SSL_OP_ALL);
  173 + SSL_CTX_set_info_callback(context, info_callback);
101 174  
102   - SSL_CTX_set_default_verify_paths(ssl_ctx);
  175 + SSL_CTX_set_default_verify_paths(context);
103 176  
104 177 ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
105 178  
106   -
107 179 #ifdef SSL_ENABLE_CRL_CHECK
108 180  
109 181 // Enable CRL check
110   - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  182 + X509_STORE *store = SSL_CTX_get_cert_store(context);
111 183 X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
112 184 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
113 185 X509_STORE_set1_param(store, param);
... ... @@ -117,8 +189,6 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
117 189  
118 190 #endif // SSL_ENABLE_CRL_CHECK
119 191  
120   - return 0;
  192 + return context;
121 193  
122 194 }
123   -
124   -#endif // HAVE_LIBSSL
... ...
src/ssl/negotiate.c
... ... @@ -535,85 +535,5 @@ int ssl_init(H3270 *hSession) {
535 535  
536 536 }
537 537  
538   -
539   -/* Callback for tracing protocol negotiation. */
540   -void ssl_info_callback(INFO_CONST SSL *s, int where, int ret)
541   -{
542   - H3270 *hSession = (H3270 *) SSL_get_ex_data(s,ssl_3270_ex_index);
543   -
544   - switch(where)
545   - {
546   - case SSL_CB_CONNECT_LOOP:
547   - trace_ssl(hSession,"SSL_connect: %s %s\n",SSL_state_string(s), SSL_state_string_long(s));
548   - break;
549   -
550   - case SSL_CB_CONNECT_EXIT:
551   -
552   - trace_ssl(hSession,"%s: SSL_CB_CONNECT_EXIT\n",__FUNCTION__);
553   -
554   - if (ret == 0)
555   - {
556   - trace_ssl(hSession,"SSL_connect: failed in %s\n",SSL_state_string_long(s));
557   - }
558   - else if (ret < 0)
559   - {
560   - unsigned long e = ERR_get_error();
561   - char err_buf[1024];
562   -
563   - if(e != 0)
564   - {
565   - hSession->ssl.error = e;
566   - (void) ERR_error_string_n(e, err_buf, 1023);
567   - }
568   -#if defined(_WIN32)
569   - else if (GetLastError() != 0)
570   - {
571   - strncpy(err_buf,lib3270_win32_strerror(GetLastError()),1023);
572   - }
573   -#else
574   - else if (errno != 0)
575   - {
576   - strncpy(err_buf, strerror(errno),1023);
577   - }
578   -#endif
579   - else
580   - {
581   - err_buf[0] = '\0';
582   - }
583   -
584   - trace_ssl(hSession,"SSL Connect error %d\nMessage: %s\nState: %s\nAlert: %s\n",
585   - ret,
586   - err_buf,
587   - SSL_state_string_long(s),
588   - SSL_alert_type_string_long(ret)
589   - );
590   -
591   - }
592   - break;
593   -
594   - default:
595   - trace_ssl(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s));
596   - }
597   -
598   -#ifdef DEBUG
599   - if(where & SSL_CB_EXIT)
600   - {
601   - trace("%s: SSL_CB_EXIT ret=%d\n",__FUNCTION__,ret);
602   - }
603   -#endif
604   -
605   - if(where & SSL_CB_ALERT)
606   - trace_ssl(hSession,"SSL ALERT: %s\n",SSL_alert_type_string_long(ret));
607   -
608   - if(where & SSL_CB_HANDSHAKE_DONE)
609   - {
610   - trace_ssl(hSession,"%s: SSL_CB_HANDSHAKE_DONE state=%04x\n",__FUNCTION__,SSL_get_state(s));
611   - if(SSL_get_state(s) == SSL_ST_OK)
612   - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATED);
613   - else
614   - set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
615   - }
616   -}
617   -
618 538 #endif /*]*/
619 539  
... ...
src/ssl/state.c
... ... @@ -70,7 +70,6 @@ LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_ssl_state(const H3270 *hSession)
70 70 #endif // HAVE_LIBSSL
71 71 }
72 72  
73   -#if defined(HAVE_LIBSSL)
74 73 void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state)
75 74 {
76 75 if(state == hSession->ssl.state)
... ... @@ -83,6 +82,9 @@ void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state)
83 82 hSession->cbk.update_ssl(hSession,hSession->ssl.state);
84 83 }
85 84  
  85 +
  86 +#if defined(HAVE_LIBSSL)
  87 +
86 88 static const struct ssl_status_msg status_msg[] =
87 89 {
88 90 // http://www.openssl.org/docs/apps/verify.html
... ...