Commit c9b6daf96b542b68ed9ebd1a08c961a9ce029358

Authored by Perry Werneck
1 parent 40ee5f3f

Testin windows build.

src/lib3270/ssl/windows/getcrl.c 0 → 100644
... ... @@ -0,0 +1,318 @@
  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 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
  38 +
  39 +#include <openssl/ssl.h>
  40 +#include <openssl/err.h>
  41 +#include <openssl/x509_vfy.h>
  42 +#include <openssl/x509.h>
  43 +
  44 +#ifdef HAVE_LDAP
  45 + #define LDAP_DEPRECATED 1
  46 + #include <ldap.h>
  47 +#endif // HAVE_LDAP
  48 +
  49 +#include "../../private.h"
  50 +#include <trace_dsc.h>
  51 +#include <errno.h>
  52 +#include <lib3270.h>
  53 +
  54 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  55 +
  56 +static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
  57 +{
  58 + if(*file)
  59 + fclose(*file);
  60 +}
  61 +
  62 +#ifdef HAVE_LDAP
  63 +static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
  64 +{
  65 + debug("%s(%p)",__FUNCTION__,*message);
  66 + if(message)
  67 + ldap_msgfree(*message);
  68 + *message = NULL;
  69 +}
  70 +
  71 +static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ld)
  72 +{
  73 + debug("%s(%p)",__FUNCTION__,*ld);
  74 + if(*ld)
  75 + ldap_unbind_ext(*ld, NULL, NULL);
  76 + *ld = NULL;
  77 +}
  78 +
  79 +static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
  80 +{
  81 + debug("%s(%p)",__FUNCTION__,*ber);
  82 + if(*ber)
  83 + ber_free(*ber, 0);
  84 + *ber = NULL;
  85 +}
  86 +
  87 +static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
  88 +{
  89 + debug("%s(%p)",__FUNCTION__,*ptr);
  90 + if(*ptr)
  91 + ldap_memfree(*ptr);
  92 + *ptr = NULL;
  93 +}
  94 +
  95 +#endif // HAVE_LDAP
  96 +
  97 +X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
  98 +{
  99 + X509_CRL * crl = NULL;
  100 +
  101 + if(!hSession->ssl.crl)
  102 + {
  103 +#ifdef LIB3270_DEFAULT_CRL
  104 + hSession->ssl.crl = strdup(LIB3270_DEFAULT_CRL);
  105 +#else
  106 + char *env = getenv("LIB3270_DEFAULT_CRL");
  107 + if(env)
  108 + hSession->ssl.crl = strdup(env);
  109 +#endif // LIB3270_DEFAULT_CRL
  110 + }
  111 +
  112 + if(!hSession->ssl.crl)
  113 + {
  114 + return NULL;
  115 + }
  116 +
  117 + trace_ssl(hSession, "crl=%s",hSession->ssl.crl);
  118 +
  119 + if(strncasecmp(hSession->ssl.crl,"file://",7) == 0)
  120 + {
  121 + lib3270_autoptr(FILE) hCRL = fopen(hSession->ssl.crl+7,"r");
  122 +
  123 + if(!hCRL)
  124 + {
  125 + // Can't open CRL File.
  126 + message->error = hSession->ssl.error = 0;
  127 + message->title = N_( "Security error" );
  128 + message->text = N_( "Can't open CRL File" );
  129 + message->description = strerror(errno);
  130 + lib3270_write_log(hSession,"ssl","Can't open %s: %s",hSession->ssl.crl,message->description);
  131 + return NULL;
  132 +
  133 + }
  134 +
  135 + lib3270_write_log(hSession,"ssl","Loading CRL from %s",hSession->ssl.crl+7);
  136 + d2i_X509_CRL_fp(hCRL, &crl);
  137 +
  138 + }
  139 +#ifdef HAVE_LDAP
  140 + else if(strncasecmp(hSession->ssl.crl,"ldap",4) == 0)
  141 + {
  142 + int rc;
  143 + lib3270_autoptr(char) url = strdup(hSession->ssl.crl);
  144 +
  145 + char * attrs[] = { NULL, NULL };
  146 + char * base = NULL;
  147 +
  148 + const struct _args
  149 + {
  150 + const char * name;
  151 + char ** value;
  152 + }
  153 + args[] =
  154 + {
  155 + { "attr", &attrs[0] },
  156 + { "base", &base }
  157 + };
  158 +
  159 + // Get arguments
  160 + size_t arg;
  161 + char * ptr = strchr(url,'?');
  162 + while(ptr)
  163 + {
  164 + *(ptr++) = 0;
  165 + char *value = strchr(ptr,'=');
  166 + if(!value)
  167 + {
  168 + message->error = hSession->ssl.error = 0;
  169 + message->title = N_( "Security error" );
  170 + message->text = N_( "Invalid argument format" );
  171 + message->description = "The URL argument should be in the format name=value";
  172 + return NULL;
  173 + }
  174 +
  175 + *(value++) = 0;
  176 +
  177 + debug("%s=%s",ptr,value);
  178 +
  179 + for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++)
  180 + {
  181 + if(!strcasecmp(ptr,args[arg].name))
  182 + {
  183 + *args[arg].value = value;
  184 + debug("%s=\"%s\"",args[arg].name,*args[arg].value);
  185 + }
  186 + }
  187 +
  188 + ptr = strchr(value,'&');
  189 + }
  190 +
  191 + // Do we get all the required arguments?
  192 + for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++)
  193 + {
  194 + if(!*args[arg].value)
  195 + {
  196 + message->error = hSession->ssl.error = 0;
  197 + message->title = N_( "Security error" );
  198 + message->text = N_( "Can't set LDAP query" );
  199 + message->description = N_("Insuficient arguments");
  200 + lib3270_write_log(hSession,"ssl","%s: Required argument \"%s\" is missing",url, args[arg].name);
  201 + return NULL;
  202 + }
  203 + }
  204 +
  205 + // Do LDAP Query
  206 + LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL;
  207 + BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL;
  208 +
  209 + rc = ldap_initialize(&ld, url);
  210 + if(rc != LDAP_SUCCESS)
  211 + {
  212 + message->error = hSession->ssl.error = 0;
  213 + message->title = N_( "Security error" );
  214 + message->text = N_( "Can't initialize LDAP" );
  215 + message->description = ldap_err2string(rc);
  216 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  217 + return NULL;
  218 + }
  219 +
  220 + unsigned long version = LDAP_VERSION3;
  221 + rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
  222 + if(rc != LDAP_SUCCESS) {
  223 + message->error = hSession->ssl.error = 0;
  224 + message->title = N_( "Security error" );
  225 + message->text = N_( "Can't set LDAP version" );
  226 + message->description = ldap_err2string(rc);
  227 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  228 + return NULL;
  229 + }
  230 +
  231 + rc = ldap_simple_bind_s(ld, "", "");
  232 + if(rc != LDAP_SUCCESS)
  233 + {
  234 + message->error = hSession->ssl.error = 0;
  235 + message->title = N_( "Security error" );
  236 + message->text = N_( "Can't bind to LDAP server" );
  237 + message->description = ldap_err2string(rc);
  238 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  239 + return NULL;
  240 + }
  241 +
  242 + lib3270_autoptr(LDAPMessage) results = NULL;
  243 + rc = ldap_search_ext_s(
  244 + ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
  245 + base, // Specifies the DN of the entry at which to start the search.
  246 + LDAP_SCOPE_BASE, // Specifies the scope of the search.
  247 + NULL, // Specifies a string representation of the filter to apply in the search.
  248 + (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
  249 + 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
  250 + NULL,
  251 + NULL,
  252 + NULL,
  253 + 0,
  254 + &results
  255 + );
  256 +
  257 + if(rc != LDAP_SUCCESS)
  258 + {
  259 + message->error = hSession->ssl.error = 0;
  260 + message->title = N_( "Security error" );
  261 + message->text = N_( "Can't search LDAP server" );
  262 + message->description = ldap_err2string(rc);
  263 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  264 + return NULL;
  265 + }
  266 +
  267 + char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
  268 + if(!attr)
  269 + {
  270 + message->error = hSession->ssl.error = 0;
  271 + message->title = N_( "Security error" );
  272 + message->text = N_( "Can't get LDAP attribute" );
  273 + message->description = N_("Search did not produce any attributes.");
  274 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  275 + return NULL;
  276 + }
  277 +
  278 + struct berval ** value = ldap_get_values_len(ld, results, attr);
  279 + if(!value)
  280 + {
  281 + message->error = hSession->ssl.error = 0;
  282 + message->title = N_( "Security error" );
  283 + message->text = N_( "Can't get LDAP attribute" );
  284 + message->description = N_("Search did not produce any values.");
  285 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  286 + return NULL;
  287 + }
  288 +
  289 + // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
  290 + const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
  291 +
  292 + if(!d2i_X509_CRL(&crl, &crl_data, value[0]->bv_len))
  293 + {
  294 + message->error = hSession->ssl.error = ERR_get_error();
  295 + message->title = N_( "Security error" );
  296 + message->text = N_( "Can't get CRL from LDAP Search" );
  297 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
  298 + }
  299 +
  300 + ldap_value_free_len(value);
  301 +
  302 + }
  303 +#endif // HAVE_LDAP
  304 + else
  305 + {
  306 + message->error = hSession->ssl.error = 0;
  307 + message->title = N_( "Security error" );
  308 + message->text = N_( "Unexpected or invalid CRL URL" );
  309 + message->description = N_("The URL scheme is unknown");
  310 + lib3270_write_log(hSession,"ssl","%s: %s",hSession->ssl.crl, message->description);
  311 + return NULL;
  312 + }
  313 +
  314 + return crl;
  315 +
  316 +}
  317 +
  318 +#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK
... ...
src/lib3270/windows/connect.c
... ... @@ -37,7 +37,7 @@
37 37 #include <windows.h>
38 38 #include <ws2tcpip.h>
39 39  
40   -#include "private.h"
  40 +#include "../private.h"
41 41 #include <errno.h>
42 42  
43 43 #include <ws2tcpip.h>
... ... @@ -262,14 +262,13 @@ LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, c
262 262  
263 263 int lib3270_connect(H3270 *hSession, int seconds)
264 264 {
265   - int s;
266   - int optval;
267   - struct addrinfo hints;
268   - struct addrinfo * result = NULL;
269   - struct addrinfo * rp = NULL;
  265 + int optval;
  266 + struct resolver host;
270 267  
271 268 CHECK_SESSION_HANDLE(hSession);
272 269  
  270 + memset(&host,0,sizeof(host));
  271 +
273 272 lib3270_main_iterate(hSession,0);
274 273  
275 274 if(hSession->auto_reconnect_inprogress)
... ... @@ -308,7 +307,7 @@ int lib3270_connect(H3270 *hSession, int seconds)
308 307 size_t out = 4096;
309 308  
310 309 iconv_t hConv = iconv_open(lib3270_win32_local_charset(),"UTF-8");
311   - if(iconv(hConv,&host.message,&in,&ptr,&out) == ((size_t) -1))
  310 + if(iconv(hConv,&host.message,&msg,&ptr,&out) == ((size_t) -1))
312 311 {
313 312 strncpy(msg,host.message,4095);
314 313 }
... ... @@ -351,7 +350,7 @@ int lib3270_connect(H3270 *hSession, int seconds)
351 350 /* connect */
352 351  
353 352 WSASetLastError(0);
354   - u_long iMode=1;
  353 + // u_long iMode=1;
355 354  
356 355 optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0;
357 356 if (setsockopt(hSession->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0)
... ...