Commit 43db012c224e25e341888e856f82c3985d68c8f4

Authored by André Breves
1 parent d6871657

Improves macOS support

configure.ac
... ... @@ -107,14 +107,15 @@ case "$host" in
107 107 *-apple-darwin*)
108 108 CFLAGS="$CFLAGS -pthread -DCONFDIR=\$(confdir) -DDATADIR=\$(datadir) -DLOCALEDIR=\$(localedir)"
109 109 LDFLAGS="$LDFLAGS -pthread"
110   - app_cv_osname="linux"
  110 + LIBS="$LIBS -framework CoreFoundation"
  111 + app_cv_osname="macos"
111 112 LOGDIR="/var/log"
112 113 DLLEXT=".so"
113 114 DLL_LDFLAGS="-shared -Wl,-install_name,\$(@F)"
114 115  
115 116 INSTALL_PACKAGES="linux-lib ${INSTALL_PACKAGES}"
116 117  
117   - app_cv_static='yes'
  118 + app_cv_static='no'
118 119  
119 120 ;;
120 121  
... ...
src/core/macos/connect.c 0 → 100644
... ... @@ -0,0 +1,312 @@
  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 - 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 + *
  28 + */
  29 +
  30 +#include <config.h>
  31 +#include <internals.h>
  32 +#include <errno.h>
  33 +#include <lib3270/trace.h>
  34 +#include <lib3270/toggle.h>
  35 +#include "kybdc.h"
  36 +
  37 +#include <sys/types.h>
  38 +#include <sys/socket.h>
  39 +#include <sys/ioctl.h>
  40 +#include <netinet/in.h>
  41 +#include <netdb.h>
  42 +#include <unistd.h>
  43 +#include <fcntl.h>
  44 +
  45 +#define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1;
  46 +
  47 +#include <stdlib.h>
  48 +
  49 +#include "hostc.h"
  50 +#include "trace_dsc.h"
  51 +#include "telnetc.h"
  52 +#include "screen.h"
  53 +
  54 +#include <lib3270/internals.h>
  55 +#include <lib3270/log.h>
  56 +#include <lib3270/trace.h>
  57 +
  58 +/*---[ Implement ]-------------------------------------------------------------------------------*/
  59 +
  60 +
  61 +static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno))
  62 +{
  63 + int err;
  64 + socklen_t len = sizeof(err);
  65 +
  66 + if(hSession->xio.write) {
  67 + trace("%s write=%p",__FUNCTION__,hSession->xio.write);
  68 + lib3270_remove_poll(hSession, hSession->xio.write);
  69 + hSession->xio.write = NULL;
  70 + }
  71 +
  72 + if(getsockopt(hSession->connection.sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0)
  73 + {
  74 + lib3270_disconnect(hSession);
  75 + lib3270_popup_dialog(
  76 + hSession,
  77 + LIB3270_NOTIFY_ERROR,
  78 + _( "Network error" ),
  79 + _( "Unable to get connection state." ),
  80 + _( "%s" ), strerror(errno)
  81 + );
  82 + return;
  83 + }
  84 + else if(err)
  85 + {
  86 + char buffer[4096];
  87 +
  88 + snprintf(buffer,4095,_( "Can't connect to %s" ), lib3270_get_url(hSession) );
  89 +
  90 + lib3270_disconnect(hSession);
  91 + lib3270_popup_dialog(
  92 + hSession,
  93 + LIB3270_NOTIFY_ERROR,
  94 + _( "Connection failed" ),
  95 + buffer,
  96 + _( "%s" ), strerror(err)
  97 + );
  98 + return;
  99 + }
  100 +
  101 + hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
  102 + hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_READ,net_input,0);
  103 +
  104 +#if defined(HAVE_LIBSSL)
  105 + if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)
  106 + {
  107 + if(ssl_negotiate(hSession))
  108 + return;
  109 + }
  110 +#endif
  111 +
  112 + lib3270_setup_session(hSession);
  113 + lib3270_set_connected_initial(hSession);
  114 +
  115 +}
  116 +
  117 + struct resolver
  118 + {
  119 + const char * message;
  120 + };
  121 +
  122 + static int background_connect(H3270 *hSession, void *host)
  123 + {
  124 +
  125 + struct addrinfo hints;
  126 + struct addrinfo * result = NULL;
  127 + struct addrinfo * rp = NULL;
  128 +
  129 + memset(&hints,0,sizeof(hints));
  130 + hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6
  131 + hints.ai_socktype = SOCK_STREAM; // Stream socket
  132 + hints.ai_flags = AI_PASSIVE; // For wildcard IP address
  133 + hints.ai_protocol = 0; // Any protocol
  134 +
  135 + status_resolving(hSession);
  136 +
  137 + int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result);
  138 + if(rc != 0)
  139 + {
  140 + ((struct resolver *) host)->message = gai_strerror(rc);
  141 + return -1;
  142 + }
  143 +
  144 + status_connecting(hSession);
  145 +
  146 + for(rp = result; hSession->connection.sock < 0 && rp != NULL; rp = rp->ai_next)
  147 + {
  148 + hSession->connection.sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  149 + if(hSession->connection.sock < 0)
  150 + {
  151 + ((struct resolver *) host)->message = strerror(errno);
  152 + continue;
  153 + }
  154 +
  155 + // Connected!
  156 + if(connect(hSession->connection.sock, rp->ai_addr, rp->ai_addrlen))
  157 + {
  158 + SOCK_CLOSE(hSession);
  159 + ((struct resolver *) host)->message = strerror(errno);
  160 + continue;
  161 + }
  162 +
  163 + }
  164 +
  165 + freeaddrinfo(result);
  166 +
  167 + return 0;
  168 +
  169 + }
  170 +
  171 + int net_reconnect(H3270 *hSession, int seconds)
  172 + {
  173 + struct resolver host;
  174 + memset(&host,0,sizeof(host));
  175 +
  176 + // Connect to host
  177 + if(lib3270_run_task(hSession, background_connect, &host) || hSession->connection.sock < 0)
  178 + {
  179 + char buffer[4096];
  180 + snprintf(buffer,4095,_( "Can't connect to %s:%s"), hSession->host.current, hSession->host.srvc);
  181 +
  182 + lib3270_popup_dialog( hSession,
  183 + LIB3270_NOTIFY_ERROR,
  184 + _( "Connection error" ),
  185 + buffer,
  186 + "%s",
  187 + host.message);
  188 +
  189 + lib3270_set_disconnected(hSession);
  190 + return errno = ENOTCONN;
  191 + }
  192 +
  193 + /* don't share the socket with our children */
  194 + (void) fcntl(hSession->connection.sock, F_SETFD, 1);
  195 +
  196 + hSession->ever_3270 = False;
  197 +
  198 +#if defined(HAVE_LIBSSL)
  199 + debug("%s: TLS/SSL is %s",__FUNCTION__,hSession->ssl.enabled ? "ENABLED" : "DISABLED")
  200 + trace_dsn(hSession,"TLS/SSL is %s\n", hSession->ssl.enabled ? "enabled" : "disabled" );
  201 + if(hSession->ssl.enabled)
  202 + {
  203 + hSession->ssl.host = 1;
  204 + if(ssl_init(hSession))
  205 + return errno = ENOTCONN;
  206 +
  207 + }
  208 +#endif // HAVE_LIBSSL
  209 +
  210 + // set options for inline out-of-band data and keepalives
  211 + int optval = 1;
  212 + if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0)
  213 + {
  214 + int rc = errno;
  215 + lib3270_popup_dialog( hSession,
  216 + LIB3270_NOTIFY_ERROR,
  217 + _( "Connection error" ),
  218 + _( "setsockopt(SO_OOBINLINE) has failed" ),
  219 + "%s",
  220 + strerror(rc));
  221 + SOCK_CLOSE(hSession);
  222 + return rc;
  223 + }
  224 +
  225 + optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0;
  226 + if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0)
  227 + {
  228 + int rc = errno;
  229 +
  230 + char buffer[4096];
  231 + snprintf(buffer,4095,_( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" ));
  232 +
  233 + lib3270_popup_dialog( hSession,
  234 + LIB3270_NOTIFY_ERROR,
  235 + _( "Connection error" ),
  236 + buffer,
  237 + "%s",
  238 + strerror(rc));
  239 + SOCK_CLOSE(hSession);
  240 + return rc;
  241 + }
  242 + else
  243 + {
  244 + trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );
  245 + }
  246 +
  247 +
  248 + /*
  249 +#if defined(OMTU)
  250 + else if (setsockopt(hSession->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0)
  251 + {
  252 + popup_a_sockerr(hSession, _( "setsockopt(%s)" ), "SO_SNDBUF");
  253 + SOCK_CLOSE(hSession);
  254 + }
  255 +#endif
  256 +
  257 + */
  258 +
  259 + // Connecting, set callbacks, wait for connection
  260 + lib3270_set_cstate(hSession, LIB3270_PENDING);
  261 + lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True);
  262 +
  263 + hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_WRITE,net_connected,0);
  264 + // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected);
  265 +
  266 + trace("%s: Connection in progress",__FUNCTION__);
  267 +
  268 + if(seconds)
  269 + {
  270 + time_t end = time(0)+seconds;
  271 +
  272 + while(time(0) < end)
  273 + {
  274 + lib3270_main_iterate(hSession,1);
  275 +
  276 + switch(hSession->connection.state)
  277 + {
  278 + case LIB3270_PENDING:
  279 + case LIB3270_CONNECTED_INITIAL:
  280 + case LIB3270_CONNECTED_ANSI:
  281 + case LIB3270_CONNECTED_3270:
  282 + case LIB3270_CONNECTED_INITIAL_E:
  283 + case LIB3270_CONNECTED_NVT:
  284 + case LIB3270_CONNECTED_SSCP:
  285 + case LIB3270_RESOLVING:
  286 + break;
  287 +
  288 + case LIB3270_NOT_CONNECTED:
  289 + return errno = ENOTCONN;
  290 +
  291 + case LIB3270_CONNECTED_TN3270E:
  292 + if(!hSession->starting)
  293 + return 0;
  294 + break;
  295 +
  296 + default:
  297 + lib3270_write_log(hSession,"connect", "%s: State changed to unexpected state %d",__FUNCTION__,hSession->connection.state);
  298 + return errno = EINVAL;
  299 + }
  300 +
  301 + }
  302 +
  303 + lib3270_disconnect(hSession);
  304 + lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT));
  305 +
  306 + return errno = ETIMEDOUT;
  307 + }
  308 +
  309 + return 0;
  310 +
  311 + }
  312 +
... ...
src/core/macos/curl.c 0 → 100644
... ... @@ -0,0 +1,231 @@
  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 - 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 + *
  28 + */
  29 +
  30 +#include <config.h>
  31 +
  32 +#if defined(HAVE_LIBCURL)
  33 +
  34 +#include <internals.h>
  35 +#include <lib3270.h>
  36 +#include <lib3270/log.h>
  37 +#include <lib3270/trace.h>
  38 +#include <curl/curl.h>
  39 +
  40 +#define CRL_DATA_LENGTH 2048
  41 +
  42 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  43 +
  44 +static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
  45 +{
  46 + debug("%s(%p)",__FUNCTION__,*ptr);
  47 + if(*ptr)
  48 + curl_easy_cleanup(*ptr);
  49 + *ptr = NULL;
  50 +}
  51 +
  52 +typedef struct _curldata
  53 +{
  54 + size_t length;
  55 + H3270 * hSession;
  56 + char errbuf[CURL_ERROR_SIZE];
  57 + struct {
  58 + size_t length;
  59 + unsigned char * contents;
  60 + } data;
  61 +} CURLDATA;
  62 +
  63 +static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr)
  64 +{
  65 + debug("%s(%p)",__FUNCTION__,*ptr);
  66 + if(*ptr)
  67 + {
  68 + CURLDATA *cdata = *ptr;
  69 +
  70 + if(cdata->data.contents) {
  71 + lib3270_free(cdata->data.contents);
  72 + cdata->data.contents = NULL;
  73 + }
  74 + lib3270_free(cdata);
  75 + }
  76 + *ptr = NULL;
  77 +}
  78 +
  79 +static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp)
  80 +{
  81 + CURLDATA * data = (CURLDATA *) userp;
  82 +
  83 + debug("%s",__FUNCTION__);
  84 +
  85 + size_t realsize = size * nmemb;
  86 +
  87 + debug("%s size=%d data->length=%d crldatalength=%d",__FUNCTION__,(int) size, (int) data->length, CRL_DATA_LENGTH);
  88 +
  89 + if((realsize + data->length) > data->data.length)
  90 + {
  91 + data->data.length += (CRL_DATA_LENGTH + realsize);
  92 + data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
  93 + memset(&(data->data.contents[data->length]),0,data->data.length-data->length);
  94 + }
  95 +
  96 + debug("%s",__FUNCTION__);
  97 +
  98 + if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
  99 + {
  100 + lib3270_trace_data(
  101 + data->hSession,
  102 + "Received",
  103 + (const unsigned char *) contents,
  104 + realsize
  105 + );
  106 + }
  107 +
  108 + debug("%s",__FUNCTION__);
  109 +
  110 + memcpy(&(data->data.contents[data->length]),contents,realsize);
  111 + data->length += realsize;
  112 +
  113 + debug("%s",__FUNCTION__);
  114 +
  115 + return realsize;
  116 +}
  117 +
  118 +static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype type, char *data, size_t size, void *userp)
  119 +{
  120 + const char * text = NULL;
  121 +
  122 + switch (type) {
  123 + case CURLINFO_TEXT:
  124 + lib3270_write_log(((CURLDATA *) userp)->hSession,"curl","%s",data);
  125 + return 0;
  126 +
  127 + case CURLINFO_HEADER_OUT:
  128 + text = "=> Send header";
  129 + break;
  130 +
  131 + case CURLINFO_DATA_OUT:
  132 + text = "=> Send data";
  133 + break;
  134 +
  135 + case CURLINFO_SSL_DATA_OUT:
  136 + text = "=> Send SSL data";
  137 + break;
  138 +
  139 + case CURLINFO_HEADER_IN:
  140 + text = "<= Recv header";
  141 + break;
  142 +
  143 + case CURLINFO_DATA_IN:
  144 + text = "<= Recv data";
  145 + break;
  146 +
  147 + case CURLINFO_SSL_DATA_IN:
  148 + text = "<= Recv SSL data";
  149 + break;
  150 +
  151 + default:
  152 + return 0;
  153 +
  154 + }
  155 +
  156 + lib3270_trace_data(
  157 + ((CURLDATA *) userp)->hSession,
  158 + text,
  159 + (const unsigned char *) data,
  160 + size
  161 + );
  162 +
  163 + return 0;
  164 +}
  165 +
  166 +char * lib3270_get_from_url(H3270 *hSession, const char *url, size_t *length, const char **error_message)
  167 +{
  168 + lib3270_write_event_trace(hSession,"Getting data from %s",url);
  169 +
  170 + // Use CURL to download the CRL
  171 + lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
  172 + lib3270_autoptr(CURL) hCurl = curl_easy_init();
  173 +
  174 + memset(crl_data,0,sizeof(CURLDATA));
  175 + crl_data->hSession = hSession;
  176 + crl_data->data.length = CRL_DATA_LENGTH;
  177 + crl_data->data.contents = lib3270_malloc(crl_data->data.length);
  178 +
  179 + if(!hCurl)
  180 + {
  181 + *error_message= _( "Can't initialize curl operation" );
  182 + errno = EINVAL;
  183 + return NULL;
  184 + }
  185 +
  186 + CURLcode res;
  187 +
  188 + curl_easy_setopt(hCurl, CURLOPT_URL, url);
  189 + curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
  190 +
  191 + curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
  192 +
  193 + curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
  194 + curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
  195 +
  196 + curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
  197 +
  198 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  199 + {
  200 + curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
  201 + curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
  202 + curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
  203 + }
  204 +
  205 + res = curl_easy_perform(hCurl);
  206 +
  207 + if(res != CURLE_OK)
  208 + {
  209 + if(crl_data->errbuf[0])
  210 + lib3270_write_log(hSession,"curl","%s: %s",url, crl_data->errbuf);
  211 +
  212 + *error_message = curl_easy_strerror(res);
  213 +
  214 + lib3270_write_log(hSession,"curl","%s: %s",url, *error_message);
  215 + errno = EINVAL;
  216 + return NULL;
  217 +
  218 + }
  219 +
  220 + if(length)
  221 + *length = (size_t) crl_data->length;
  222 +
  223 + char * httpText = lib3270_malloc(crl_data->length+1);
  224 + memset(httpText,0,crl_data->length+1);
  225 + memcpy(httpText,crl_data->data.contents,crl_data->length);
  226 +
  227 + return httpText;
  228 +
  229 +}
  230 +
  231 +#endif // HAVE_LIBCURL
... ...
src/core/macos/event_dispatcher.c 0 → 100644
... ... @@ -0,0 +1,231 @@
  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 - 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 + *
  28 + */
  29 +
  30 + /**
  31 + * @brief Implements the default event dispatcher for linux.
  32 + *
  33 + */
  34 +
  35 +#include <internals.h>
  36 +#include <sys/time.h>
  37 +#include <sys/types.h>
  38 +#include <lib3270/log.h>
  39 +#include <lib3270/trace.h>
  40 +
  41 +#define MILLION 1000000L
  42 +#define TN (timeout_t *)NULL
  43 +
  44 +/*---[ Implement ]------------------------------------------------------------------------------------------*/
  45 +
  46 +/**
  47 + * @brief lib3270's default event dispatcher.
  48 + *
  49 + * @param hSession TN3270 session to process.
  50 + * @param block If non zero, the method blocks waiting for event.
  51 + *
  52 + */
  53 +int lib3270_default_event_dispatcher(H3270 *hSession, int block)
  54 +{
  55 + int ns;
  56 + struct timeval now, twait, *tp;
  57 + int events;
  58 +
  59 + fd_set rfds, wfds, xfds;
  60 +
  61 + input_t *ip;
  62 + int processed_any = 0;
  63 +
  64 +retry:
  65 +
  66 + hSession->input.changed = 0;
  67 +
  68 + // If we've processed any input, then don't block again.
  69 + if(processed_any)
  70 + block = 0;
  71 +
  72 + events = 0;
  73 +
  74 + FD_ZERO(&rfds);
  75 + FD_ZERO(&wfds);
  76 + FD_ZERO(&xfds);
  77 +
  78 + for (ip = (input_t *) hSession->input.list.first; ip != (input_t *)NULL; ip = (input_t *) ip->next)
  79 + {
  80 + if(!ip->enabled)
  81 + {
  82 + debug("Socket %d is disabled",ip->fd);
  83 + continue;
  84 + }
  85 +
  86 + if(ip->flag & LIB3270_IO_FLAG_READ)
  87 + {
  88 + FD_SET(ip->fd, &rfds);
  89 + events++;
  90 + }
  91 +
  92 + if(ip->flag & LIB3270_IO_FLAG_WRITE)
  93 + {
  94 + FD_SET(ip->fd, &wfds);
  95 + events++;
  96 + }
  97 +
  98 + if(ip->flag & LIB3270_IO_FLAG_EXCEPTION)
  99 + {
  100 + FD_SET(ip->fd, &xfds);
  101 + events++;
  102 + }
  103 + }
  104 +
  105 + if (block)
  106 + {
  107 + if (hSession->timeouts.first)
  108 + {
  109 + (void) gettimeofday(&now, (void *)NULL);
  110 + twait.tv_sec = ((timeout_t *) hSession->timeouts.first)->tv.tv_sec - now.tv_sec;
  111 + twait.tv_usec = ((timeout_t *) hSession->timeouts.first)->tv.tv_usec - now.tv_usec;
  112 + if (twait.tv_usec < 0L) {
  113 + twait.tv_sec--;
  114 + twait.tv_usec += MILLION;
  115 + }
  116 + if (twait.tv_sec < 0L)
  117 + twait.tv_sec = twait.tv_usec = 0L;
  118 + tp = &twait;
  119 + }
  120 + else
  121 + {
  122 + twait.tv_sec = 1;
  123 + twait.tv_usec = 0L;
  124 + tp = &twait;
  125 + }
  126 + }
  127 + else
  128 + {
  129 + twait.tv_sec = 0;
  130 + twait.tv_usec = 10L;
  131 + tp = &twait;
  132 +
  133 + if(!events)
  134 + return processed_any;
  135 + }
  136 +
  137 + ns = select(FD_SETSIZE, &rfds, &wfds, &xfds, tp);
  138 +
  139 + if (ns < 0 && errno != EINTR)
  140 + {
  141 + lib3270_popup_dialog( hSession,
  142 + LIB3270_NOTIFY_ERROR,
  143 + _( "Network error" ),
  144 + _( "Select() failed when processing for events." ),
  145 + "%s",
  146 + strerror(errno));
  147 + }
  148 + else
  149 + {
  150 + for (ip = (input_t *) hSession->input.list.first; ip != (input_t *) NULL; ip = (input_t *) ip->next)
  151 + {
  152 + if((ip->flag & LIB3270_IO_FLAG_READ) && FD_ISSET(ip->fd, &rfds))
  153 + {
  154 + (*ip->call)(hSession,ip->fd,LIB3270_IO_FLAG_READ,ip->userdata);
  155 + processed_any = True;
  156 + if (hSession->input.changed)
  157 + goto retry;
  158 + }
  159 +
  160 + if((ip->flag & LIB3270_IO_FLAG_WRITE) && FD_ISSET(ip->fd, &wfds))
  161 + {
  162 + (*ip->call)(hSession,ip->fd,LIB3270_IO_FLAG_WRITE,ip->userdata);
  163 + processed_any = True;
  164 + if (hSession->input.changed)
  165 + goto retry;
  166 + }
  167 +
  168 + if((ip->flag & LIB3270_IO_FLAG_EXCEPTION) && FD_ISSET(ip->fd, &xfds))
  169 + {
  170 + (*ip->call)(hSession,ip->fd,LIB3270_IO_FLAG_EXCEPTION,ip->userdata);
  171 + processed_any = True;
  172 + if (hSession->input.changed)
  173 + goto retry;
  174 + }
  175 + }
  176 + }
  177 +
  178 + // See what's expired.
  179 + if (hSession->timeouts.first)
  180 + {
  181 + struct timeout *t;
  182 + (void) gettimeofday(&now, (void *)NULL);
  183 +
  184 + while(hSession->timeouts.first)
  185 + {
  186 + t = (struct timeout *) hSession->timeouts.first;
  187 +
  188 + if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec))
  189 + {
  190 + t->in_play = True;
  191 + (*t->proc)(hSession);
  192 + processed_any = True;
  193 +
  194 + lib3270_linked_list_delete_node(&hSession->timeouts,t);
  195 +
  196 + }
  197 + else
  198 + {
  199 + break;
  200 + }
  201 +
  202 + }
  203 +
  204 + /*
  205 +
  206 + while ((t = ((timeout_t *) hSession->timeouts.first)) != TN)
  207 + {
  208 + if (t->tv.tv_sec < now.tv_sec ||(t->tv.tv_sec == now.tv_sec && t->tv.tv_usec < now.tv_usec))
  209 + {
  210 + t->in_play = True;
  211 + (*t->proc)(t->session);
  212 + processed_any = True;
  213 +
  214 + lib3270_linked_list_delete_node(&hSession->timeouts,t);
  215 +
  216 + }
  217 + else
  218 + {
  219 + break;
  220 + }
  221 + }
  222 +
  223 + */
  224 + }
  225 +
  226 + if (hSession->input.changed)
  227 + goto retry;
  228 +
  229 + return processed_any;
  230 +
  231 +}
... ...
src/core/macos/log.c 0 → 100644
... ... @@ -0,0 +1,92 @@
  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. 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 - 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 + *
  28 + */
  29 +
  30 +#include <internals.h>
  31 +#include <stdio.h>
  32 +#include <stdarg.h>
  33 +#include <config.h>
  34 +#include <lib3270.h>
  35 +#include <lib3270/log.h>
  36 +
  37 +#ifdef HAVE_SYSLOG
  38 + #include <syslog.h>
  39 +#endif // HAVE_SYSLOG
  40 +
  41 +/*---[ Implementacao ]--------------------------------------------------------------------------------------*/
  42 +
  43 + int use_syslog = 0;
  44 +
  45 + void default_log_writer(H3270 GNUC_UNUSED(*session), const char *module, int GNUC_UNUSED(rc), const char *fmt, va_list arg_ptr)
  46 + {
  47 +#ifdef HAVE_SYSLOG
  48 + if(use_syslog)
  49 + {
  50 + vsyslog(LOG_INFO, fmt, arg_ptr);
  51 + }
  52 + else
  53 + {
  54 + printf("%s:\t",module);
  55 + vprintf(fmt,arg_ptr);
  56 + printf("\n");
  57 + fflush(stdout);
  58 + }
  59 +#else
  60 + printf("%s:\t",module);
  61 + vprintf(fmt,arg_ptr);
  62 + printf("\n");
  63 + fflush(stdout);
  64 +#endif
  65 + }
  66 +
  67 + LIB3270_EXPORT int lib3270_set_syslog(int flag)
  68 + {
  69 +#ifdef HAVE_SYSLOG
  70 + if(flag)
  71 + {
  72 + if(!use_syslog)
  73 + {
  74 + openlog(LIB3270_STRINGIZE_VALUE_OF(LIB3270_NAME), LOG_CONS, LOG_USER);
  75 + use_syslog = 1;
  76 + }
  77 + }
  78 + else
  79 + {
  80 + if(use_syslog)
  81 + {
  82 + closelog();
  83 + use_syslog = 0;
  84 + }
  85 + }
  86 +
  87 + return 0;
  88 +
  89 +#else
  90 + return errno = ENOENT;
  91 +#endif // HAVE_SYSLOG
  92 + }
... ...
src/core/macos/util.c 0 → 100644
... ... @@ -0,0 +1,169 @@
  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. Registro no INPI sob
  5 + * o nome G3270.
  6 + *
  7 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  8 + *
  9 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  10 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  11 + * Free Software Foundation.
  12 + *
  13 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  14 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  15 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  16 + * obter mais detalhes.
  17 + *
  18 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  19 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  20 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * Este programa está nomeado como - e possui - linhas de código.
  23 + *
  24 + * Contatos:
  25 + *
  26 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  27 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  28 + *
  29 + */
  30 +
  31 +/**
  32 + * @brief Linux Utility functions.
  33 + */
  34 +
  35 +
  36 +#include <config.h>
  37 +#include <stdarg.h>
  38 +#include <internals.h>
  39 +#include <unistd.h>
  40 +#include <CoreFoundation/CFBundle.h>
  41 +#include <CoreFoundation/CFURL.h>
  42 +#include <sys/syslimits.h>
  43 +
  44 +static char * concat(char *path, const char *name, size_t *length)
  45 +{
  46 + size_t szCurrent = strlen(path);
  47 +
  48 + if(szCurrent > 1 && path[szCurrent-1] != '/')
  49 + strcat(path,"/");
  50 +
  51 + szCurrent += strlen(name);
  52 +
  53 + if(szCurrent >= *length)
  54 + {
  55 + *length += (szCurrent + 1024);
  56 + path = lib3270_realloc(path,*length);
  57 + }
  58 +
  59 + strcat(path,name);
  60 +
  61 + return path;
  62 +}
  63 +
  64 +static char * build_filename(const char *root, const char *str, va_list args)
  65 +{
  66 + size_t szFilename = 1024 + strlen(root);
  67 + char * filename = (char *) lib3270_malloc(szFilename);
  68 +
  69 + strcpy(filename,root);
  70 +
  71 + while(str) {
  72 + filename = concat(filename,str,&szFilename);
  73 + str = va_arg(args, const char *);
  74 + }
  75 +
  76 + return (char *) lib3270_realloc(filename,strlen(filename)+1);
  77 +}
  78 +
  79 +char * lib3270_build_data_filename(const char *str, ...)
  80 +{
  81 + va_list args;
  82 + va_start (args, str);
  83 +
  84 + char *filename;
  85 + CFBundleRef mainBundle = CFBundleGetMainBundle();
  86 + if (mainBundle) {
  87 + CFURLRef url = CFBundleCopyBundleURL(mainBundle);
  88 + if (url) {
  89 + size_t szPath = PATH_MAX;
  90 + char *path = (char *) lib3270_malloc(szPath);
  91 + CFURLGetFileSystemRepresentation(url, true, path, szPath);
  92 + CFRelease(url);
  93 + path = concat(path, "Contents/Resources", &szPath);
  94 + filename = build_filename(path, str, args);
  95 + lib3270_free(path);
  96 + } else {
  97 + filename = build_filename(LIB3270_STRINGIZE_VALUE_OF(DATADIR), str, args);
  98 + }
  99 + } else {
  100 + filename = build_filename(LIB3270_STRINGIZE_VALUE_OF(DATADIR), str, args);
  101 + }
  102 +
  103 + va_end (args);
  104 +
  105 + return filename;
  106 +}
  107 +
  108 +char * lib3270_build_config_filename(const char *str, ...)
  109 +{
  110 + va_list args;
  111 + va_start (args, str);
  112 +
  113 + char *filename = build_filename(LIB3270_STRINGIZE_VALUE_OF(CONFDIR), str, args);
  114 +
  115 + va_end (args);
  116 +
  117 + return filename;
  118 +}
  119 +
  120 +char * lib3270_build_filename(const char *str, ...)
  121 +{
  122 + size_t szFilename = 1024;
  123 + char * filename = (char *) lib3270_malloc(szFilename);
  124 + char * tempname;
  125 +
  126 + // First build the base filename
  127 + memset(filename,0,szFilename);
  128 +
  129 + va_list args;
  130 + va_start (args, str);
  131 + while(str) {
  132 + filename = concat(filename,str,&szFilename);
  133 + str = va_arg(args, const char *);
  134 + }
  135 + va_end (args);
  136 +
  137 + // Check paths
  138 + size_t ix;
  139 +
  140 + static const char * paths[] =
  141 + {
  142 + LIB3270_STRINGIZE_VALUE_OF(DATADIR),
  143 + LIB3270_STRINGIZE_VALUE_OF(CONFDIR),
  144 + "."
  145 + };
  146 +
  147 + for(ix = 0; ix < (sizeof(paths)/sizeof(paths[0])); ix++)
  148 + {
  149 + tempname = lib3270_strdup_printf("%s/%s",paths[ix],filename);
  150 +
  151 + if(access(tempname, F_OK) == 0)
  152 + {
  153 + lib3270_free(filename);
  154 + return tempname;
  155 + }
  156 +
  157 + lib3270_free(tempname);
  158 +
  159 + }
  160 +
  161 + // Not found! Force the standard data dir
  162 +
  163 + tempname = lib3270_strdup_printf("%s/%s",paths[0],filename);
  164 + lib3270_free(filename);
  165 +
  166 + return tempname;
  167 +
  168 +}
  169 +
... ...
src/include/localdefs.h
... ... @@ -36,7 +36,11 @@
36 36 //typedef void *XtPointer;
37 37 // typedef void *Widget;
38 38 // typedef void *XEvent;
39   -typedef char Boolean;
  39 +#ifdef __APPLE__
  40 + typedef unsigned char Boolean;
  41 +#else
  42 + typedef char Boolean;
  43 +#endif
40 44 typedef char *String;
41 45 // typedef unsigned int Cardinal;
42 46 typedef unsigned long KeySym;
... ...
src/ssl/macos/getcrl.c 0 → 100644
... ... @@ -0,0 +1,131 @@
  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 - 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 + *
  28 + *
  29 + * References:
  30 + *
  31 + * http://www.openssl.org/docs/ssl/
  32 + * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
  33 + *
  34 + */
  35 +
  36 +#include "private.h"
  37 +
  38 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
  39 +
  40 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  41 +
  42 +static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
  43 +{
  44 + if(*file)
  45 + fclose(*file);
  46 +}
  47 +
  48 +X509_CRL * lib3270_download_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
  49 +{
  50 + X509_CRL * x509_crl = NULL;
  51 +
  52 + if(!(consturl && *consturl))
  53 + {
  54 + message->error = hSession->ssl.error = 0;
  55 + message->title = _( "Security error" );
  56 + message->text = _( "Can't open CRL File" );
  57 + message->description = _("The URL for the CRL is undefined or empty");
  58 + errno = ENOENT;
  59 + return NULL;
  60 + }
  61 +
  62 + if(strncasecmp(consturl,"file://",7) == 0)
  63 + {
  64 + lib3270_autoptr(FILE) hCRL = fopen(consturl+7,"r");
  65 +
  66 + if(!hCRL)
  67 + {
  68 + // Can't open CRL File.
  69 + int err = errno;
  70 +
  71 + message->error = hSession->ssl.error = 0;
  72 + message->title = _( "Security error" );
  73 + message->text = _( "Can't open CRL File" );
  74 + message->description = strerror(err);
  75 + trace_ssl(hSession,"Can't open %s: %s\n",consturl,message->description);
  76 + return NULL;
  77 +
  78 + }
  79 +
  80 + trace_ssl(hSession,"Loading CRL from %s\n",consturl+7);
  81 + if(d2i_X509_CRL_fp(hCRL, &x509_crl))
  82 + {
  83 + message->error = hSession->ssl.error = ERR_get_error();
  84 + message->title = _( "Security error" );
  85 + message->text = _( "Can't decode CRL" );
  86 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  87 + return NULL;
  88 + }
  89 +
  90 +
  91 +
  92 + }
  93 +#ifdef HAVE_LDAP
  94 + else if(strncasecmp(consturl,"ldap://",7) == 0 && strlen(consturl) > 8)
  95 + {
  96 + return get_crl_using_ldap(hSession, message, consturl);
  97 +
  98 + }
  99 +#endif // HAVE_LDAP
  100 + else
  101 + {
  102 +#ifdef HAVE_LIBCURL
  103 +
  104 + return get_crl_using_url(hSession, message, consturl);
  105 +
  106 +#else
  107 + // Can't get CRL.
  108 +
  109 + message->error = hSession->ssl.error = 0;
  110 +
  111 + if(!(message->text && message->description))
  112 + message->title = _( "Security error" );
  113 +
  114 + if(!message->text)
  115 + message->text = _( "Unexpected or invalid CRL URL" );
  116 +
  117 + if(!message->description)
  118 + message->description = _("The URL scheme is unknown");
  119 +
  120 + trace_ssl(hSession,"%s: The URL scheme is unknown",consturl);
  121 +
  122 + errno = EINVAL;
  123 + return NULL;
  124 +#endif // HAVE_LIBCURL
  125 + }
  126 +
  127 + return x509_crl;
  128 +
  129 +}
  130 +
  131 +#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK
... ...
src/ssl/macos/init.c 0 → 100644
... ... @@ -0,0 +1,118 @@
  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 - 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 + *
  28 + *
  29 + * References:
  30 + *
  31 + * http://www.openssl.org/docs/ssl/
  32 + * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
  33 + *
  34 + */
  35 +
  36 +/**
  37 + * @brief OpenSSL initialization for linux.
  38 + *
  39 + */
  40 +
  41 +#include <config.h>
  42 +
  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 <internals.h>
  54 +#include <errno.h>
  55 +#include <lib3270.h>
  56 +#include <lib3270/internals.h>
  57 +#include <lib3270/trace.h>
  58 +#include <lib3270/log.h>
  59 +#include "trace_dsc.h"
  60 +
  61 +#ifdef SSL_ENABLE_CRL_CHECK
  62 + #include <openssl/x509.h>
  63 +#endif // SSL_ENABLE_CRL_CHECK
  64 +
  65 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  66 +
  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)
  74 +{
  75 + debug("%s ssl_ctx=%p",__FUNCTION__,ssl_ctx);
  76 +
  77 + if(ssl_ctx)
  78 + return 0;
  79 +
  80 + trace_ssl(hSession,"Initializing SSL context.\n");
  81 +
  82 + SSL_load_error_strings();
  83 + SSL_library_init();
  84 +
  85 + ssl_ctx = SSL_CTX_new(SSLv23_method());
  86 + if(ssl_ctx == NULL)
  87 + {
  88 + message->error = hSession->ssl.error = ERR_get_error();
  89 + message->title = _( "Security error" );
  90 + message->text = _( "Cant initialize the SSL context." );
  91 + return -1;
  92 + }
  93 +
  94 + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);
  95 + SSL_CTX_set_info_callback(ssl_ctx, ssl_info_callback);
  96 +
  97 + SSL_CTX_set_default_verify_paths(ssl_ctx);
  98 +
  99 + ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
  100 +
  101 +#ifdef SSL_ENABLE_CRL_CHECK
  102 +
  103 + // Enable CRL check
  104 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  105 + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
  106 + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
  107 + X509_STORE_set1_param(store, param);
  108 + X509_VERIFY_PARAM_free(param);
  109 +
  110 + trace_ssl(hSession,"CRL CHECK was enabled\n");
  111 +
  112 +#endif // SSL_ENABLE_CRL_CHECK
  113 +
  114 + return 0;
  115 +
  116 +}
  117 +
  118 +#endif // HAVE_LIBSSL
... ...
src/ssl/macos/ldap.c 0 → 100644
... ... @@ -0,0 +1,241 @@
  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 - 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 + *
  28 + *
  29 + * References:
  30 + *
  31 + * http://www.openssl.org/docs/ssl/
  32 + * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
  33 + *
  34 + */
  35 +
  36 +#include <config.h>
  37 +#include <internals.h>
  38 +#include <lib3270/log.h>
  39 +#include <lib3270/trace.h>
  40 +#include <lib3270/toggle.h>
  41 +
  42 +#include "utilc.h"
  43 +
  44 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
  45 +
  46 +#include <openssl/ssl.h>
  47 +#include <openssl/err.h>
  48 +#include <openssl/x509_vfy.h>
  49 +#include <openssl/x509.h>
  50 +
  51 +#define LDAP_DEPRECATED 1
  52 +#include <ldap.h>
  53 +
  54 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  55 +
  56 +static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
  57 +{
  58 + debug("%s(%p)",__FUNCTION__,*message);
  59 + if(message)
  60 + ldap_msgfree(*message);
  61 + *message = NULL;
  62 +}
  63 +
  64 +static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ld)
  65 +{
  66 + debug("%s(%p)",__FUNCTION__,*ld);
  67 + if(*ld)
  68 + ldap_unbind_ext(*ld, NULL, NULL);
  69 + *ld = NULL;
  70 +}
  71 +
  72 +static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
  73 +{
  74 + debug("%s(%p)",__FUNCTION__,*ber);
  75 + if(*ber)
  76 + ber_free(*ber, 0);
  77 + *ber = NULL;
  78 +}
  79 +
  80 +static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
  81 +{
  82 + debug("%s(%p)",__FUNCTION__,*ptr);
  83 + if(*ptr)
  84 + ldap_memfree(*ptr);
  85 + *ptr = NULL;
  86 +}
  87 +
  88 +LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
  89 +{
  90 + X509_CRL * x509_crl = NULL;
  91 +
  92 + int rc;
  93 + lib3270_autoptr(char) url = lib3270_unescape(consturl);
  94 + char * base = strchr(url+7,'/');
  95 + char * attrs[] = { NULL, NULL };
  96 +
  97 + if(!base)
  98 + {
  99 + message->error = hSession->ssl.error = 0;
  100 + message->title = _( "Security error" );
  101 + message->text = _( "No DN of the entry at which to start the search on the URL" );
  102 + message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  103 + errno = EINVAL;
  104 + return NULL;
  105 + }
  106 +
  107 + *(base++) = 0;
  108 + attrs[0] = strchr(base,'?');
  109 +
  110 + if(!base)
  111 + {
  112 + message->error = hSession->ssl.error = 0;
  113 + message->title = _( "Security error" );
  114 + message->text = _( "No LDAP attribute on the URL" );
  115 + message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  116 + errno = EINVAL;
  117 + return NULL;
  118 + }
  119 +
  120 + *(attrs[0]++) = 0;
  121 +
  122 + debug("host: \"%s\"",url);
  123 + debug("Base: \"%s\"",base);
  124 + debug("Attr: \"%s\"",attrs[0]);
  125 +
  126 + // Do LDAP Query
  127 + LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL;
  128 + BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL;
  129 +
  130 + rc = ldap_initialize(&ld, url);
  131 + if(rc != LDAP_SUCCESS)
  132 + {
  133 + message->error = hSession->ssl.error = 0;
  134 + message->title = _( "Security error" );
  135 + message->text = _( "Can't initialize LDAP" );
  136 + message->description = ldap_err2string(rc);
  137 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  138 + return NULL;
  139 + }
  140 +
  141 + unsigned long version = LDAP_VERSION3;
  142 + rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
  143 + if(rc != LDAP_SUCCESS) {
  144 + message->error = hSession->ssl.error = 0;
  145 + message->title = _( "Security error" );
  146 + message->text = _( "Can't set LDAP protocol version" );
  147 + message->description = ldap_err2string(rc);
  148 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  149 + return NULL;
  150 + }
  151 +
  152 + rc = ldap_simple_bind_s(ld, "", "");
  153 + if(rc != LDAP_SUCCESS)
  154 + {
  155 + message->error = hSession->ssl.error = 0;
  156 + message->title = _( "Security error" );
  157 + message->text = _( "Can't bind to LDAP server" );
  158 + message->description = ldap_err2string(rc);
  159 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  160 + return NULL;
  161 + }
  162 +
  163 + lib3270_autoptr(LDAPMessage) results = NULL;
  164 + rc = ldap_search_ext_s(
  165 + ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
  166 + base, // Specifies the DN of the entry at which to start the search.
  167 + LDAP_SCOPE_BASE, // Specifies the scope of the search.
  168 + NULL, // Specifies a string representation of the filter to apply in the search.
  169 + (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
  170 + 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
  171 + NULL,
  172 + NULL,
  173 + NULL,
  174 + 0,
  175 + &results
  176 + );
  177 +
  178 + if(rc != LDAP_SUCCESS)
  179 + {
  180 + message->error = hSession->ssl.error = 0;
  181 + message->title = _( "Security error" );
  182 + message->text = _( "Can't search LDAP server" );
  183 + message->description = ldap_err2string(rc);
  184 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  185 + return NULL;
  186 + }
  187 +
  188 + char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
  189 + if(!attr)
  190 + {
  191 + message->error = hSession->ssl.error = 0;
  192 + message->title = _( "Security error" );
  193 + message->text = _( "Can't get LDAP attribute" );
  194 + message->description = _("Search did not produce any attributes.");
  195 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  196 + errno = ENOENT;
  197 + return NULL;
  198 + }
  199 +
  200 + struct berval ** value = ldap_get_values_len(ld, results, attr);
  201 + if(!value)
  202 + {
  203 + message->error = hSession->ssl.error = 0;
  204 + message->title = _( "Security error" );
  205 + message->text = _( "Can't get LDAP attribute" );
  206 + message->description = _("Search did not produce any values.");
  207 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  208 + errno = ENOENT;
  209 + return NULL;
  210 + }
  211 +
  212 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  213 + {
  214 + lib3270_trace_data(
  215 + hSession,
  216 + "CRL Data received from LDAP server",
  217 + (const unsigned char *) value[0]->bv_val,
  218 + value[0]->bv_len
  219 + );
  220 + }
  221 +
  222 + // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
  223 + const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
  224 +
  225 + if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
  226 + {
  227 + message->error = hSession->ssl.error = ERR_get_error();
  228 + message->title = _( "Security error" );
  229 + message->text = _( "Can't decode certificate revocation list" );
  230 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
  231 + ldap_value_free_len(value);
  232 + return NULL;
  233 + }
  234 +
  235 + ldap_value_free_len(value);
  236 +
  237 + return x509_crl;
  238 +
  239 +}
  240 +
  241 +#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK && HAVE_LDAP
... ...
src/ssl/macos/private.h 0 → 100644
... ... @@ -0,0 +1,63 @@
  1 +/*
  2 + * "Software G3270, 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 private.h 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 +#ifndef LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
  31 +
  32 + #define LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
  33 +
  34 + #include <config.h>
  35 +
  36 + #include <openssl/ssl.h>
  37 + #include <openssl/err.h>
  38 + #include <openssl/x509_vfy.h>
  39 + #include <openssl/x509.h>
  40 +
  41 + #include <internals.h>
  42 + #include <trace_dsc.h>
  43 + #include <errno.h>
  44 + #include <lib3270.h>
  45 + #include <lib3270/trace.h>
  46 + #include <lib3270/log.h>
  47 +
  48 + #ifdef HAVE_LDAP
  49 +
  50 + /// @brief Use libldap to get CRL.
  51 + LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
  52 +
  53 + #endif // HAVE_LDAP
  54 +
  55 + #ifdef HAVE_LIBCURL
  56 +
  57 + /// @brief Use libcurl to get CRL.
  58 + LIB3270_INTERNAL X509_CRL * get_crl_using_url(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
  59 +
  60 + #endif // HAVE_LIBCURL
  61 +
  62 +
  63 +#endif // !LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
... ...
src/ssl/macos/url.c 0 → 100644
... ... @@ -0,0 +1,127 @@
  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 - 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 + *
  28 + *
  29 + * References:
  30 + *
  31 + * http://www.openssl.org/docs/ssl/
  32 + * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
  33 + *
  34 + */
  35 +
  36 +#include <config.h>
  37 +
  38 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBCURL)
  39 +
  40 +#include "private.h"
  41 +#include <curl/curl.h>
  42 +#include <lib3270/toggle.h>
  43 +
  44 +#define CRL_DATA_LENGTH 2048
  45 +
  46 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  47 +
  48 +static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr)
  49 +{
  50 + debug("%s(%p)",__FUNCTION__,*ptr);
  51 + if(*ptr)
  52 + BIO_free_all(*ptr);
  53 + *ptr = NULL;
  54 +}
  55 +
  56 +LIB3270_INTERNAL X509_CRL * get_crl_using_url(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
  57 +{
  58 + X509_CRL * x509_crl = NULL;
  59 +
  60 + size_t szText = 0;
  61 + lib3270_autoptr(char) httpText = lib3270_get_from_url(hSession, consturl, &szText, &message->description);
  62 +
  63 + if(!httpText)
  64 + {
  65 + message->title = _( "Security error" );
  66 + message->text = _( "Error getting certificate revocation list" );
  67 + return NULL;
  68 + }
  69 +
  70 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  71 + lib3270_trace_data(hSession,"CRL Data",(const unsigned char *) httpText, (unsigned int) szText);
  72 +
  73 + if(strncasecmp(consturl,"ldap://",7) == 0)
  74 + {
  75 + // It's an LDAP query, assumes a base64 data.
  76 + char * data = strstr((char *) httpText,":: ");
  77 + if(!data)
  78 + {
  79 + message->error = hSession->ssl.error = ERR_get_error();
  80 + message->title = _( "Security error" );
  81 + message->text = _( "Got a bad formatted certificate revocation list from LDAP server" );
  82 + lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n", consturl, httpText);
  83 + errno = EINVAL;
  84 + return NULL;
  85 + }
  86 + data += 3;
  87 +
  88 + lib3270_autoptr(BIO) bio = BIO_new_mem_buf(httpText,-1);
  89 +
  90 + BIO * b64 = BIO_new(BIO_f_base64());
  91 + bio = BIO_push(b64, bio);
  92 +
  93 + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
  94 +
  95 + if(!d2i_X509_CRL_bio(bio, &x509_crl))
  96 + {
  97 + message->error = hSession->ssl.error = ERR_get_error();
  98 + message->title = _( "Security error" );
  99 + message->text = _( "Can't decode certificate revocation list got from LDAP server" );
  100 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  101 + errno = EINVAL;
  102 + return NULL;
  103 + }
  104 +
  105 + }
  106 + else
  107 + {
  108 + // CRL File, convert it
  109 + // Copy the pointer because d2i_X509_CRL changes the value!!!
  110 + const unsigned char *crl_data = (const unsigned char *) httpText;
  111 +
  112 + if(!d2i_X509_CRL(&x509_crl, &crl_data, szText))
  113 + {
  114 + message->error = hSession->ssl.error = ERR_get_error();
  115 + message->title = _( "Security error" );
  116 + message->text = _( "Can't decode certificate revocation list" );
  117 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  118 + return NULL;
  119 + }
  120 +
  121 + }
  122 +
  123 + return x509_crl;
  124 +
  125 +}
  126 +
  127 +#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK && HAVE_LIBCURL
... ...