diff --git a/lib3270.cbp b/lib3270.cbp index 7fa41dd..a0435ec 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -212,7 +212,7 @@ - + @@ -250,6 +250,9 @@ + + diff --git a/src/include/lib3270.h b/src/include/lib3270.h index f7592a6..4674d33 100644 --- a/src/include/lib3270.h +++ b/src/include/lib3270.h @@ -804,6 +804,7 @@ 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 ); LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id); + LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled); LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd); LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag); @@ -823,6 +824,7 @@ void * (*add_poll)(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata); void (*remove_poll)(H3270 *session, void *id); + void (*set_poll_state)(H3270 *session, void *id, int enabled); int (*Wait)(H3270 *hSession, int seconds); int (*event_dispatcher)(H3270 *session, int wait); diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c index c8a2fc6..c76fef4 100644 --- a/src/lib3270/connect.c +++ b/src/lib3270/connect.c @@ -84,10 +84,10 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u int err; socklen_t len = sizeof(err); - if(hSession->ns_write_id) { - trace("%s write=%p",__FUNCTION__,hSession->ns_write_id); - lib3270_remove_poll(hSession, hSession->ns_write_id); - hSession->ns_write_id = NULL; + if(hSession->xio.write) { + trace("%s write=%p",__FUNCTION__,hSession->xio.write); + lib3270_remove_poll(hSession, hSession->xio.write); + hSession->xio.write = NULL; } 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 return; } - hSession->ns_exception_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); - hSession->ns_read_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0); + hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); + hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_READ,net_input,0); #if defined(HAVE_LIBSSL) 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 hSession->cstate = LIB3270_PENDING; lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); - hSession->ns_write_id = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_WRITE,net_connected,0); + hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->sock,LIB3270_IO_FLAG_WRITE,net_connected,0); // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected); trace("%s: Connection in progress",__FUNCTION__); @@ -558,57 +558,3 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u } -int non_blocking(H3270 *hSession, Boolean on) -{ -#ifdef WIN32 - WSASetLastError(0); - u_long iMode= on ? 1 : 0; - - if(ioctlsocket(hSession->sock,FIONBIO,&iMode)) - { - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "Connection error" ), - _( "ioctlsocket(FIONBIO) failed." ), - "%s", lib3270_win32_strerror(GetLastError())); - return -1; - } -#else - - int f; - - if ((f = fcntl(hSession->sock, F_GETFL, 0)) == -1) - { - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "Socket error" ), - _( "fcntl() error when getting socket state." ), - _( "%s" ), strerror(errno) - ); - - return -1; - } - - if (on) - f |= O_NDELAY; - else - f &= ~O_NDELAY; - - if (fcntl(hSession->sock, F_SETFL, f) < 0) - { - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "Socket error" ), - on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ), - _( "%s" ), strerror(errno) - ); - return -1; - } - -#endif - - trace("Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking"); - - return 0; -} - diff --git a/src/lib3270/iocalls.c b/src/lib3270/iocalls.c index 52cab24..6507af1 100644 --- a/src/lib3270/iocalls.c +++ b/src/lib3270/iocalls.c @@ -36,6 +36,19 @@ #include "telnetc.h" #include "utilc.h" +#if defined(_WIN32) + #include +#else + #include + #include + #include + #include + #include + #include + #include +#endif + + #define MILLION 1000000L // //#if defined(_WIN32) @@ -51,6 +64,8 @@ static void * internal_add_poll(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*proc)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ); static void internal_remove_poll(H3270 *session, void *id); + static void internal_set_poll_state(H3270 *session, void *id, int enabled); + static int internal_wait(H3270 *session, int seconds); static void internal_ring_bell(H3270 *session); @@ -71,6 +86,9 @@ static void (*remove_poll)(H3270 *session, void *id) = internal_remove_poll; + static void (*set_poll_state)(H3270 *session, void *id, int enabled) + = internal_set_poll_state; + static int (*wait)(H3270 *session, int seconds) = internal_wait; @@ -246,11 +264,37 @@ static void internal_remove_poll(H3270 *session, void *id) session->inputs_changed = 1; } -LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) { - debug("%s %p",__FUNCTION__,id); + static void internal_set_poll_state(H3270 *session, void *id, int enabled) + { + input_t *ip; + input_t *prev = (input_t *)NULL; + + for (ip = session->inputs; ip != (input_t *) NULL; ip = (input_t *) ip->next) + { + if (ip == (input_t *)id) + { + ip->enabled = enabled ? 1 : 0; + break; + } + + prev = ip; + } + + } + + +LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) +{ + debug("%s(%d,%p)",__FUNCTION__,session->sock,id); remove_poll(session, id); } +LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled) +{ + debug("%s(%d,%p,%d)",__FUNCTION__,session->sock,id,enabled); + set_poll_state(session, id, enabled); +} + LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd) { @@ -288,6 +332,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_F } 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 ) { + debug("%s(%d)",__FUNCTION__,session->sock); return add_poll(session,fd,flag,call,userdata); } @@ -330,39 +375,39 @@ void RemoveTimeOut(H3270 *session, void * timer) void x_except_on(H3270 *h) { - int reading = (h->ns_read_id != NULL); + int reading = (h->xio.read != NULL); debug("%s",__FUNCTION__); - if(h->ns_exception_id) + if(h->xio.except) return; if(reading) - lib3270_remove_poll(h,h->ns_read_id); + lib3270_remove_poll(h,h->xio.read); - h->ns_exception_id = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); + h->xio.except = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); if(reading) - h->ns_read_id = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_READ,net_input,0); + h->xio.read = lib3270_add_poll_fd(h,h->sock,LIB3270_IO_FLAG_READ,net_input,0); debug("%s",__FUNCTION__); } void remove_input_calls(H3270 *session) { - if(session->ns_read_id) + if(session->xio.read) { - lib3270_remove_poll(session,session->ns_read_id); - session->ns_read_id = NULL; + lib3270_remove_poll(session,session->xio.read); + session->xio.read = NULL; } - if(session->ns_exception_id) + if(session->xio.except) { - lib3270_remove_poll(session,session->ns_exception_id); - session->ns_exception_id = NULL; + lib3270_remove_poll(session,session->xio.except); + session->xio.except = NULL; } - if(session->ns_write_id) + if(session->xio.write) { - lib3270_remove_poll(session,session->ns_write_id); - session->ns_write_id = NULL; + lib3270_remove_poll(session,session->xio.write); + session->xio.write = NULL; } } @@ -478,6 +523,65 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo } +int non_blocking(H3270 *hSession, Boolean on) +{ + + if(hSession->sock < 0) + return 0; + +#ifdef WIN32 + + WSASetLastError(0); + u_long iMode= on ? 1 : 0; + + if(ioctlsocket(hSession->sock,FIONBIO,&iMode)) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Connection error" ), + _( "ioctlsocket(FIONBIO) failed." ), + "%s", lib3270_win32_strerror(GetLastError())); + return -1; + } + +#else + + int f; + + if ((f = fcntl(hSession->sock, F_GETFL, 0)) == -1) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Socket error" ), + _( "fcntl() error when getting socket state." ), + _( "%s" ), strerror(errno) + ); + + return -1; + } + + if (on) + f |= O_NDELAY; + else + f &= ~O_NDELAY; + + if (fcntl(hSession->sock, F_SETFL, f) < 0) + { + lib3270_popup_dialog( hSession, + LIB3270_NOTIFY_ERROR, + _( "Socket error" ), + on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ), + _( "%s" ), strerror(errno) + ); + return -1; + } + +#endif + + trace("Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking"); + + return 0; +} diff --git a/src/lib3270/private.h b/src/lib3270/private.h index 179d044..1aee4a0 100644 --- a/src/lib3270/private.h +++ b/src/lib3270/private.h @@ -599,9 +599,11 @@ struct _h3270 unsigned char saved_bg; // xio - void * ns_read_id; - void * ns_write_id; - void * ns_exception_id; + struct { + void * read; + void * write; + void * except; + } xio; // SSL Data (Always defined to maintain the structure size) struct diff --git a/src/lib3270/ssl/ctx_init.c b/src/lib3270/ssl/ctx_init.c new file mode 100644 index 0000000..fe85366 --- /dev/null +++ b/src/lib3270/ssl/ctx_init.c @@ -0,0 +1,175 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como ssl.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * licinio@bb.com.br (Licínio Luis Branco) + * kraucer@bb.com.br (Kraucer Fernandes Mazuco) + * + * + * References: + * + * http://www.openssl.org/docs/ssl/ + * + */ + +/** + * @brief OpenSSL initialization. + * + */ + +#include +#if defined(HAVE_LIBSSL) + +#include +#include +#include + +#ifndef SSL_ST_OK + #define SSL_ST_OK 3 +#endif // !SSL_ST_OK + +#include "../private.h" +#include +#include +#include +#include +#include "trace_dsc.h" + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +/** + * @brief Initialize openssl library. + * + * @return 0 if ok, non zero if fails. + * + */ +int ssl_ctx_init(H3270 *hSession) +{ + debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx); + + if(ssl_ctx != NULL) + return 0; + + SSL_load_error_strings(); + SSL_library_init(); + + ssl_ctx = SSL_CTX_new(SSLv23_method()); + if(ssl_ctx == NULL) + return -1; + + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); + SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); + SSL_CTX_set_default_verify_paths(ssl_ctx); + +#if defined(_WIN32) + { + HKEY hKey = 0; + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) + { + char data[4096]; + unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) + + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) + { + strncat(data,"\\certs",4095); + + trace("Loading certs from \"%s\"",data); + if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data)) + { + hSession->ssl.error = ERR_get_error(); + + lib3270_write_log( + hSession, + "ssl", + "Cant set default locations for trusted CA certificates to %s\n%s", + data, + ERR_lib_error_string(hSession->ssl.error) + ); + + } + } + RegCloseKey(hKey); + } + + + } +#else + static const char * ssldir[] = + { +#ifdef DATAROOTDIR + DATAROOTDIR "/" PACKAGE_NAME "/certs", +#endif // DATAROOTDIR +#ifdef SYSCONFDIR + SYSCONFDIR "/ssl/certs", + SYSCONFDIR "/certs", +#endif + "/etc/ssl/certs" + }; + + size_t f; + + for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++) + { + SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]); + } + +#endif // _WIN32 + + // + // Initialize CUSTOM CRL CHECK + // + + +/* +#if defined(SSL_ENABLE_CRL_CHECK) + // Set up CRL validation + // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); + + // Enable CRL checking + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); + X509_STORE_set1_param(store, param); + X509_VERIFY_PARAM_free(param); + + // X509_STORE_free(store); + + trace_dsn(hSession,"CRL CHECK is enabled.\n"); + +#else + + trace_dsn(hSession,"CRL CHECK is disabled.\n"); + +#endif // SSL_ENABLE_CRL_CHECK +*/ + + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); + + return 0; +} + +#endif // HAVE_LIBSSL diff --git a/src/lib3270/ssl/init.c b/src/lib3270/ssl/init.c deleted file mode 100644 index e877a4e..0000000 --- a/src/lib3270/ssl/init.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como ssl.c e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * licinio@bb.com.br (Licínio Luis Branco) - * kraucer@bb.com.br (Kraucer Fernandes Mazuco) - * - * - * References: - * - * http://www.openssl.org/docs/ssl/ - * - */ - -/** - * @brief OpenSSL initialization. - * - */ - -#include -#if defined(HAVE_LIBSSL) - -#include -#include -#include - -#ifndef SSL_ST_OK - #define SSL_ST_OK 3 -#endif // !SSL_ST_OK - -#include "../private.h" -#include -#include -#include -#include -#include "trace_dsc.h" - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -/** - * @brief Initialize openssl library. - * - * @return 0 if ok, non zero if fails. - * - */ -int ssl_ctx_init(H3270 *hSession) -{ - debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx); - - if(ssl_ctx != NULL) - return 0; - - SSL_load_error_strings(); - SSL_library_init(); - - ssl_ctx = SSL_CTX_new(SSLv23_method()); - if(ssl_ctx == NULL) - return -1; - - SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL); - SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback); - SSL_CTX_set_default_verify_paths(ssl_ctx); - -#if defined(_WIN32) - { - HKEY hKey = 0; - - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\" PACKAGE_NAME,0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) - { - char data[4096]; - unsigned long datalen = sizeof(data); // data field length(in), data returned length(out) - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) - - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) data,&datalen) == ERROR_SUCCESS) - { - strncat(data,"\\certs",4095); - - trace("Loading certs from \"%s\"",data); - if(!SSL_CTX_load_verify_locations(ssl_ctx,NULL,data)) - { - char buffer[4096]; - int ssl_error = ERR_get_error(); - - snprintf(buffer,4095,_("Cant set default locations for trusted CA certificates to\n%s"),data); - - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - N_( "Security error" ), - buffer, - N_( "%s" ),ERR_lib_error_string(ssl_error) - ); - } - } - RegCloseKey(hKey); - } - - - } -#else - static const char * ssldir[] = - { -#ifdef DATAROOTDIR - DATAROOTDIR "/" PACKAGE_NAME "/certs", -#endif // DATAROOTDIR -#ifdef SYSCONFDIR - SYSCONFDIR "/ssl/certs", - SYSCONFDIR "/certs", -#endif - "/etc/ssl/certs" - }; - - size_t f; - - for(f = 0;f < sizeof(ssldir) / sizeof(ssldir[0]);f++) - { - SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssldir[f]); - } - -#endif // _WIN32 - - // - // Initialize CUSTOM CRL CHECK - // - - -/* -#if defined(SSL_ENABLE_CRL_CHECK) - // Set up CRL validation - // https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now - X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); - - // Enable CRL checking - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); - X509_STORE_set1_param(store, param); - X509_VERIFY_PARAM_free(param); - - // X509_STORE_free(store); - - trace_dsn(hSession,"CRL CHECK is enabled.\n"); - -#else - - trace_dsn(hSession,"CRL CHECK is disabled.\n"); - -#endif // SSL_ENABLE_CRL_CHECK -*/ - - ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); - - return 0; -} - -#endif // HAVE_LIBSSL diff --git a/src/lib3270/ssl/negotiate.c b/src/lib3270/ssl/negotiate.c index 46edc51..310b491 100644 --- a/src/lib3270/ssl/negotiate.c +++ b/src/lib3270/ssl/negotiate.c @@ -70,6 +70,15 @@ */ SSL_CTX * ssl_ctx = NULL; +struct ssl_error_message +{ + int error; + const char * title; + const char * text; + const char * description; +}; + + /** * @brief Initialize openssl session. * @@ -78,7 +87,8 @@ * @return 0 if ok, non zero if fails. * */ -int ssl_init(H3270 *hSession) + +static int background_ssl_init(H3270 *hSession, void *message) { set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); hSession->ssl.error = 0; @@ -86,21 +96,13 @@ int ssl_init(H3270 *hSession) if(ssl_ctx_init(hSession)) { - hSession->ssl.error = ERR_get_error(); - - /* - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - N_( "Security error" ), - N_( "SSL initialization has failed" ), - "%s",ERR_reason_error_string(hSession->ssl.error) - ); - */ + ((struct ssl_error_message *) message)->error = hSession->ssl.error = ERR_get_error(); + ((struct ssl_error_message *) message)->title = N_( "Security error" ); + ((struct ssl_error_message *) message)->text = N_( "SSL context initialization has failed" ); set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); - hSession->ssl.host = False; + return -1; } @@ -110,43 +112,28 @@ int ssl_init(H3270 *hSession) hSession->ssl.con = SSL_new(ssl_ctx); if(hSession->ssl.con == NULL) { - hSession->ssl.error = ERR_get_error(); - - /* - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - N_( "Security error" ), - N_( "Cant create a new SSL structure for current connection." ), - N_( "%s" ),ERR_lib_error_string(hSession->ssl.error) - ); - */ - + ((struct ssl_error_message *) message)->error = hSession->ssl.error = ERR_get_error(); + ((struct ssl_error_message *) message)->title = N_( "Security error" ); + ((struct ssl_error_message *) message)->text = N_( "Cant create a new SSL structure for current connection." ); return -1; } SSL_set_ex_data(hSession->ssl.con,ssl_3270_ex_index,(char *) hSession); - // SSL_set_verify(session->ssl_con, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); SSL_set_verify(hSession->ssl.con, 0, NULL); return 0; } -int ssl_negotiate(H3270 *hSession) +static int background_ssl_negotiation(H3270 *hSession, void *message) { int rv; trace("%s",__FUNCTION__); - set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); - non_blocking(hSession,False); - /* Initialize the SSL library. */ - if(ssl_init(hSession)) + if(background_ssl_init(hSession,message)) { - /* Failed. */ - lib3270_disconnect(hSession); return -1; } @@ -155,15 +142,10 @@ int ssl_negotiate(H3270 *hSession) { trace_dsn(hSession,"%s","SSL_set_fd failed!\n"); - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - N_( "Security error" ), - N_( "SSL negotiation failed" ), - "%s",_( "Cant set the file descriptor for the input/output facility for the TLS/SSL (encrypted) side of ssl." ) - ); + ((struct ssl_error_message *) message)->title = N_( "Security error" ); + ((struct ssl_error_message *) message)->text = N_( "SSL negotiation failed" ); + ((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." ); - lib3270_disconnect(hSession); return -1; } @@ -173,29 +155,24 @@ int ssl_negotiate(H3270 *hSession) if (rv != 1) { - int ssl_error = SSL_get_error(hSession->ssl.con,rv); const char * msg = ""; - if(ssl_error == SSL_ERROR_SYSCALL && hSession->ssl.error) - ssl_error = hSession->ssl.error; + ((struct ssl_error_message *) message)->error = SSL_get_error(hSession->ssl.con,rv); + if(((struct ssl_error_message *) message)->error == SSL_ERROR_SYSCALL && hSession->ssl.error) + ((struct ssl_error_message *) message)->error = hSession->ssl.error; - msg = ERR_lib_error_string(ssl_error); + msg = ERR_lib_error_string(((struct ssl_error_message *) message)->error); trace_dsn(hSession,"SSL_connect failed: %s %s\n",msg,ERR_reason_error_string(hSession->ssl.error)); - lib3270_popup_dialog( - hSession, - LIB3270_NOTIFY_ERROR, - N_( "Security error" ), - N_( "SSL Connect failed" ), - "%s",msg ? msg : "" - ); - + ((struct ssl_error_message *) message)->title = N_( "Security error" ); + ((struct ssl_error_message *) message)->text = N_( "SSL Connect failed" ); lib3270_disconnect(hSession); return -1; + } - /* Success. */ + // Success. X509 * peer = NULL; rv = SSL_get_verify_result(hSession->ssl.con); @@ -208,13 +185,11 @@ int ssl_negotiate(H3270 *hSession) case X509_V_ERR_UNABLE_TO_GET_CRL: trace_dsn(hSession,"%s","The CRL of a certificate could not be found.\n" ); - lib3270_disconnect(hSession); - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "SSL error" ), - _( "Unable to get certificate CRL." ), - _( "The Certificate revocation list (CRL) of a certificate could not be found." ) - ); + + ((struct ssl_error_message *) message)->title = _( "SSL error" ); + ((struct ssl_error_message *) message)->text = _( "Unable to get certificate CRL." ); + ((struct ssl_error_message *) message)->description = _( "The Certificate revocation list (CRL) of a certificate could not be found." ); + return -1; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: @@ -224,14 +199,9 @@ int ssl_negotiate(H3270 *hSession) #ifdef SSL_ALLOW_SELF_SIGNED_CERT break; #else - lib3270_disconnect(hSession); - lib3270_popup_dialog( hSession, - LIB3270_NOTIFY_ERROR, - _( "SSL error" ), - _( "The SSL certificate for this host is not trusted." ), - _( "The security certificate presented by this host was not issued by a trusted certificate authority." ) - ); - + ((struct ssl_error_message *) message)->title = _( "SSL error" ); + ((struct ssl_error_message *) message)->text = _( "The SSL certificate for this host is not trusted." ); + ((struct ssl_error_message *) message)->description = _( "The security certificate presented by this host was not issued by a trusted certificate authority." ); return -1; #endif // SSL_ALLOW_SELF_SIGNED_CERT @@ -286,11 +256,65 @@ int ssl_negotiate(H3270 *hSession) /* Tell the world that we are (still) connected, now in secure mode. */ lib3270_set_connected_initial(hSession); - non_blocking(hSession,True); return 0; } +int ssl_negotiate(H3270 *hSession) +{ + int rc; + struct ssl_error_message msg; + + memset(&msg,0,sizeof(msg)); + + set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); + non_blocking(hSession,False); + + rc = lib3270_run_task(hSession, background_ssl_negotiation, &msg); + if(rc) + { + // SSL Negotiation has failed. + if(msg.description) + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description); + else + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); + + lib3270_disconnect(hSession); + + } + + non_blocking(hSession,True); + + return rc; +} + +int ssl_init(H3270 *hSession) { + + int rc; + struct ssl_error_message msg; + + memset(&msg,0,sizeof(msg)); + + non_blocking(hSession,False); + + rc = lib3270_run_task(hSession, background_ssl_init, &msg); + if(rc) + { + // SSL init has failed. + if(msg.description) + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", msg.description); + else + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, msg.title, msg.text, "%s", ERR_reason_error_string(msg.error)); + + lib3270_disconnect(hSession); + } + + non_blocking(hSession,True); + + return rc; + +} + /* Callback for tracing protocol negotiation. */ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) { @@ -352,7 +376,7 @@ void ssl_info_callback(INFO_CONST SSL *s, int where, int ret) ); } - + break; default: trace_dsn(hSession,"SSL Current state is \"%s\"\n",SSL_state_string_long(s)); diff --git a/src/lib3270/telnet.c b/src/lib3270/telnet.c index 5417b93..6aff19b 100644 --- a/src/lib3270/telnet.c +++ b/src/lib3270/telnet.c @@ -908,10 +908,10 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) } #endif - if(hSession->ns_write_id) + if(hSession->xio.write) { - lib3270_remove_poll(hSession, hSession->ns_write_id); - hSession->ns_write_id = 0; + lib3270_remove_poll(hSession, hSession->xio.write); + hSession->xio.write = 0; } if(hSession->sock >= 0) @@ -1964,10 +1964,10 @@ void net_exception(H3270 *session, int fd unused, LIB3270_IO_FLAG flag unused, v { session->syncing = 1; - if(session->ns_exception_id) + if(session->xio.except) { - lib3270_remove_poll(session, session->ns_exception_id); - session->ns_exception_id = NULL; + lib3270_remove_poll(session, session->xio.except); + session->xio.except = NULL; } } } diff --git a/src/lib3270/util.c b/src/lib3270/util.c index 1feace9..e0ec00b 100644 --- a/src/lib3270/util.c +++ b/src/lib3270/util.c @@ -35,21 +35,9 @@ #define _GNU_SOURCE #include "private.h" -// #include - -//#ifdef HAVE_ICONV -// #include -//#endif // HAVE_ICONV - -//#include -// #include "resources.h" - #include "utilc.h" -//#include "popupsc.h" -//#include "api.h" - -//#include -//#include +#include "popupsc.h" +#include #define my_isspace(c) isspace((unsigned char)c) -- libgit2 0.21.2