Commit a81e00e1497f1052589281acf85f3fa2d262399a

Authored by Perry Werneck
1 parent 641a1b5b

Reactivating CRL download from LDAP server.

lib3270.cbp
... ... @@ -134,6 +134,9 @@
134 134 <Unit filename="src/core/linux/event_dispatcher.c">
135 135 <Option compilerVar="CC" />
136 136 </Unit>
  137 + <Unit filename="src/core/linux/ldap.c">
  138 + <Option compilerVar="CC" />
  139 + </Unit>
137 140 <Unit filename="src/core/linux/log.c">
138 141 <Option compilerVar="CC" />
139 142 </Unit>
... ...
src/core/linux/ldap.c 0 → 100644
... ... @@ -0,0 +1,180 @@
  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_LDAP) && defined HAVE_LIBSSL
  33 +
  34 +#include <internals.h>
  35 +#include <lib3270.h>
  36 +#include <lib3270/log.h>
  37 +#include <lib3270/trace.h>
  38 +#include <openssl/x509.h>
  39 +#include <networking.h>
  40 +
  41 +#define LDAP_DEPRECATED 1
  42 +#include <ldap.h>
  43 +
  44 +typedef char LDAPPTR;
  45 +
  46 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  47 +
  48 +static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
  49 +{
  50 + debug("%s(%p)",__FUNCTION__,*message);
  51 + if(message)
  52 + ldap_msgfree(*message);
  53 + *message = NULL;
  54 +}
  55 +
  56 +static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ld)
  57 +{
  58 + debug("%s(%p)",__FUNCTION__,*ld);
  59 + if(*ld)
  60 + ldap_unbind_ext(*ld, NULL, NULL);
  61 + *ld = NULL;
  62 +}
  63 +
  64 +static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
  65 +{
  66 + debug("%s(%p)",__FUNCTION__,*ber);
  67 + if(*ber)
  68 + ber_free(*ber, 0);
  69 + *ber = NULL;
  70 +}
  71 +
  72 +static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
  73 +{
  74 + debug("%s(%p)",__FUNCTION__,*ptr);
  75 + if(*ptr)
  76 + ldap_memfree(*ptr);
  77 + *ptr = NULL;
  78 +}
  79 +
  80 +X509_CRL * lib3270_crl_get_using_ldap(H3270 *hSession, const char *url, const char **error) {
  81 +
  82 + // Get attributes
  83 + char * attrs[] = { NULL, NULL };
  84 + char * base = strchr(url+7,'/');
  85 + if(!base) {
  86 + *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  87 + errno = EINVAL;
  88 + return NULL;
  89 + }
  90 +
  91 + *(base++) = 0;
  92 + attrs[0] = strchr(base,'?');
  93 +
  94 + if(!base) {
  95 + *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  96 + errno = EINVAL;
  97 + return NULL;
  98 + }
  99 +
  100 + *(attrs[0]++) = 0;
  101 +
  102 + debug("host: \"%s\"",url);
  103 + debug("Base: \"%s\"",base);
  104 + debug("Attr: \"%s\"",attrs[0]);
  105 +
  106 + // Do LDAP Query
  107 + lib3270_autoptr(LDAP) ld = NULL;
  108 + lib3270_autoptr(BerElement) ber = NULL;
  109 +
  110 + int rc = ldap_initialize(&ld, url);
  111 + if(rc != LDAP_SUCCESS) {
  112 + *error = ldap_err2string(rc);
  113 + return NULL;
  114 + }
  115 +
  116 + unsigned long version = LDAP_VERSION3;
  117 + rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
  118 + if(rc != LDAP_SUCCESS) {
  119 + *error = ldap_err2string(rc);
  120 + return NULL;
  121 + }
  122 +
  123 + rc = ldap_simple_bind_s(ld, "", "");
  124 + if(rc != LDAP_SUCCESS) {
  125 + *error = ldap_err2string(rc);
  126 + return NULL;
  127 + }
  128 +
  129 + lib3270_autoptr(LDAPMessage) results = NULL;
  130 + rc = ldap_search_ext_s(
  131 + ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
  132 + base, // Specifies the DN of the entry at which to start the search.
  133 + LDAP_SCOPE_BASE, // Specifies the scope of the search.
  134 + NULL, // Specifies a string representation of the filter to apply in the search.
  135 + (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
  136 + 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
  137 + NULL,
  138 + NULL,
  139 + NULL,
  140 + 0,
  141 + &results
  142 + );
  143 +
  144 + if(rc != LDAP_SUCCESS) {
  145 + *error = ldap_err2string(rc);
  146 + return NULL;
  147 + }
  148 +
  149 + lib3270_autoptr(LDAPPTR) attr = ldap_first_attribute(ld, results, &ber);
  150 + if(!attr) {
  151 + *error = _("LDAP search did not produce any attributes.");
  152 + errno = ENOENT;
  153 + return NULL;
  154 + }
  155 +
  156 + //
  157 + // Load CRL
  158 + //
  159 + struct berval ** value = ldap_get_values_len(ld, results, attr);
  160 + if(!value) {
  161 + *error =_("LDAP search did not produce any values.");
  162 + errno = ENOENT;
  163 + return NULL;
  164 + }
  165 +
  166 + X509_CRL * crl = NULL;
  167 +
  168 + const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
  169 +
  170 + if(!d2i_X509_CRL(&crl, &crl_data, value[0]->bv_len)) {
  171 + *error = _( "Can't decode certificate revocation list" );
  172 + }
  173 +
  174 + ldap_value_free_len(value);
  175 +
  176 + return crl;
  177 +
  178 +}
  179 +
  180 +#endif // HAVE_LDAP
... ...
src/core/linux/private.h
... ... @@ -41,4 +41,8 @@
41 41 LIB3270_INTERNAL char * lib3270_url_get_using_curl(H3270 *hSession, const char *u, const char **error);
42 42 #endif // HAVE_LIBCURL
43 43  
  44 + #if defined(HAVE_LDAP)
  45 + LIB3270_INTERNAL char * lib3270_url_get_using_ldap(H3270 *hSession, const char *u, const char **error);
  46 + #endif // HAVE_LDAP
  47 +
44 48 #endif // !PRIVATE_H_INCLUDED
... ...
src/core/popup.c
... ... @@ -45,7 +45,7 @@ LIB3270_EXPORT int lib3270_popup(H3270 *hSession, const LIB3270_POPUP *popup, un
45 45 return hSession->cbk.popup(hSession,popup,wait);
46 46 }
47 47  
48   -LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
  48 +int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
49 49  
50 50 LIB3270_POPUP translated = *popup;
51 51  
... ...
src/include/internals.h
... ... @@ -888,5 +888,16 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
888 888 * @retval ECANCELED Operation was canceled.
889 889 * @retval ENOTSUP No popup handler available.
890 890 */
891   - LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait);
  891 + LIB3270_INTERNAL int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait);
892 892  
  893 +#if defined(HAVE_LDAP) && defined (HAVE_LIBSSL)
  894 + /**
  895 + * @brief Download X509 CRL using LDAP backend.
  896 + *
  897 + * @param hSession tn3270 session handle.
  898 + * @param url URL for Ldap access.
  899 + * @param error pointer to error message.
  900 + *
  901 + */
  902 + LIB3270_INTERNAL X509_CRL * lib3270_crl_get_using_ldap(H3270 *hSession, const char *url, const char **error);
  903 +#endif // HAVE_LDAP
... ...
src/include/networking.h
... ... @@ -224,5 +224,6 @@
224 224  
225 225 LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock);
226 226  
  227 +
227 228 #endif // LIB3270_NETWORKING_H_INCLUDED
228 229  
... ...
src/network_modules/openssl/start.c
... ... @@ -35,13 +35,30 @@
35 35 #include "private.h"
36 36 #include <lib3270/properties.h>
37 37  
38   - static int import_crl(H3270 *hSession, SSL_CTX * ssl_ctx, LIB3270_NET_CONTEXT * context, const char *crl) {
  38 + static int import_crl(H3270 *hSession, SSL_CTX * ssl_ctx, LIB3270_NET_CONTEXT * context, const char *url) {
39 39  
40 40 X509_CRL * x509_crl = NULL;
41 41  
42   - // Import CRL
43   - {
44   - lib3270_autoptr(BIO) bio = BIO_new_mem_buf(crl,-1);
  42 + const char *error_message = NULL;
  43 + if(strncasecmp(url,"ldap",4) == 0) {
  44 +
  45 + // Download using LDAP
  46 +#ifdef HAVE_LDAP
  47 +
  48 + x509_crl = lib3270_crl_get_using_ldap(hSession, url, &error_message);
  49 +
  50 +#else
  51 +
  52 + *error_message = _("No LDAP support");
  53 +
  54 +#endif // HAVE_LDAP
  55 +
  56 + } else {
  57 +
  58 + // Download with URL
  59 + lib3270_autoptr(char) crl_text = lib3270_url_get(hSession, url, &error_message);
  60 +
  61 + lib3270_autoptr(BIO) bio = BIO_new_mem_buf(crl_text,-1);
45 62  
46 63 BIO * b64 = BIO_new(BIO_f_base64());
47 64 bio = BIO_push(b64, bio);
... ... @@ -49,15 +66,21 @@
49 66 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
50 67  
51 68 if(!d2i_X509_CRL_bio(bio, &x509_crl)) {
52   - trace_ssl(hSession,"Can't decode CRL data:\n%s\n",crl);
53   - return -1;
  69 + trace_ssl(hSession,"Can't decode CRL data:\n%s\n",crl_text);
  70 + error_message = _("Can't decode CRL data");
54 71 }
55 72  
56   - lib3270_openssl_crl_free(context);
57   - context->crl.cert = x509_crl;
58   -
59 73 }
60 74  
  75 + if(error_message)
  76 + trace_ssl(hSession,"Error downloading CRL from %s: %s\n",url,error_message);
  77 +
  78 + if(!x509_crl)
  79 + return -1;
  80 +
  81 + lib3270_openssl_crl_free(context);
  82 + context->crl.cert = x509_crl;
  83 +
61 84 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) {
62 85  
63 86 lib3270_autoptr(BIO) bio = BIO_new(BIO_s_mem());
... ... @@ -88,7 +111,7 @@
88 111  
89 112 }
90 113  
91   - static void download_crl(H3270 *hSession, SSL_CTX * ctx_context, LIB3270_NET_CONTEXT * context, X509 *peer) {
  114 + static void download_crl_from_peer(H3270 *hSession, SSL_CTX * ctx_context, LIB3270_NET_CONTEXT * context, X509 *peer) {
92 115  
93 116 debug("%s peer=%p",__FUNCTION__,(void *) peer);
94 117  
... ... @@ -102,8 +125,6 @@
102 125 }
103 126  
104 127 size_t ix;
105   - const char * error_message = NULL;
106   - lib3270_autoptr(char) crl_text = NULL;
107 128  
108 129 const char *prefer = lib3270_crl_get_preferred_protocol(hSession);
109 130 if(!prefer) {
... ... @@ -111,12 +132,7 @@
111 132 // No preferred protocol, try all uris.
112 133 for(ix = 0; ix < uris->length; ix++) {
113 134  
114   - debug("Trying %s",uris->str[ix]);
115   - crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
116   -
117   - if(error_message) {
118   - trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
119   - } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
  135 + if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
120 136 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
121 137 return;
122 138 }
... ... @@ -137,11 +153,7 @@
137 153 continue;
138 154  
139 155 debug("Trying %s",uris->str[ix]);
140   - crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
141   -
142   - if(error_message) {
143   - trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
144   - } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
  156 + if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
145 157 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
146 158 return;
147 159 }
... ... @@ -154,12 +166,7 @@
154 166 if(!strncasecmp(prefer,uris->str[ix],length))
155 167 continue;
156 168  
157   - debug("Trying %s",uris->str[ix]);
158   - crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
159   -
160   - if(error_message) {
161   - trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
162   - } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
  169 + if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
163 170 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
164 171 return;
165 172 }
... ... @@ -265,8 +272,13 @@
265 272 if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) {
266 273  
267 274 // CRL download is enabled and verification has failed; look for CRL file.
  275 +
268 276 trace_ssl(hSession,"CRL Validation has failed, requesting CRL download\n");
269   - download_crl(hSession, ctx_context, context, peer);
  277 + if(context->crl.url) {
  278 + import_crl(hSession, ctx_context,context,context->crl.url);
  279 + } else {
  280 + download_crl_from_peer(hSession, ctx_context, context, peer);
  281 + }
270 282  
271 283 }
272 284  
... ...