Commit a81e00e1497f1052589281acf85f3fa2d262399a

Authored by Perry Werneck
1 parent 641a1b5b

Reactivating CRL download from LDAP server.

@@ -134,6 +134,9 @@ @@ -134,6 +134,9 @@
134 <Unit filename="src/core/linux/event_dispatcher.c"> 134 <Unit filename="src/core/linux/event_dispatcher.c">
135 <Option compilerVar="CC" /> 135 <Option compilerVar="CC" />
136 </Unit> 136 </Unit>
  137 + <Unit filename="src/core/linux/ldap.c">
  138 + <Option compilerVar="CC" />
  139 + </Unit>
137 <Unit filename="src/core/linux/log.c"> 140 <Unit filename="src/core/linux/log.c">
138 <Option compilerVar="CC" /> 141 <Option compilerVar="CC" />
139 </Unit> 142 </Unit>
src/core/linux/ldap.c 0 → 100644
@@ -0,0 +1,180 @@ @@ -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,4 +41,8 @@
41 LIB3270_INTERNAL char * lib3270_url_get_using_curl(H3270 *hSession, const char *u, const char **error); 41 LIB3270_INTERNAL char * lib3270_url_get_using_curl(H3270 *hSession, const char *u, const char **error);
42 #endif // HAVE_LIBCURL 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 #endif // !PRIVATE_H_INCLUDED 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,7 +45,7 @@ LIB3270_EXPORT int lib3270_popup(H3270 *hSession, const LIB3270_POPUP *popup, un
45 return hSession->cbk.popup(hSession,popup,wait); 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 LIB3270_POPUP translated = *popup; 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,5 +888,16 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
888 * @retval ECANCELED Operation was canceled. 888 * @retval ECANCELED Operation was canceled.
889 * @retval ENOTSUP No popup handler available. 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,5 +224,6 @@
224 224
225 LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock); 225 LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock);
226 226
  227 +
227 #endif // LIB3270_NETWORKING_H_INCLUDED 228 #endif // LIB3270_NETWORKING_H_INCLUDED
228 229
src/network_modules/openssl/start.c
@@ -35,13 +35,30 @@ @@ -35,13 +35,30 @@
35 #include "private.h" 35 #include "private.h"
36 #include <lib3270/properties.h> 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 X509_CRL * x509_crl = NULL; 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 BIO * b64 = BIO_new(BIO_f_base64()); 63 BIO * b64 = BIO_new(BIO_f_base64());
47 bio = BIO_push(b64, bio); 64 bio = BIO_push(b64, bio);
@@ -49,15 +66,21 @@ @@ -49,15 +66,21 @@
49 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); 66 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
50 67
51 if(!d2i_X509_CRL_bio(bio, &x509_crl)) { 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 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) { 84 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) {
62 85
63 lib3270_autoptr(BIO) bio = BIO_new(BIO_s_mem()); 86 lib3270_autoptr(BIO) bio = BIO_new(BIO_s_mem());
@@ -88,7 +111,7 @@ @@ -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 debug("%s peer=%p",__FUNCTION__,(void *) peer); 116 debug("%s peer=%p",__FUNCTION__,(void *) peer);
94 117
@@ -102,8 +125,6 @@ @@ -102,8 +125,6 @@
102 } 125 }
103 126
104 size_t ix; 127 size_t ix;
105 - const char * error_message = NULL;  
106 - lib3270_autoptr(char) crl_text = NULL;  
107 128
108 const char *prefer = lib3270_crl_get_preferred_protocol(hSession); 129 const char *prefer = lib3270_crl_get_preferred_protocol(hSession);
109 if(!prefer) { 130 if(!prefer) {
@@ -111,12 +132,7 @@ @@ -111,12 +132,7 @@
111 // No preferred protocol, try all uris. 132 // No preferred protocol, try all uris.
112 for(ix = 0; ix < uris->length; ix++) { 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 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]); 136 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
121 return; 137 return;
122 } 138 }
@@ -137,11 +153,7 @@ @@ -137,11 +153,7 @@
137 continue; 153 continue;
138 154
139 debug("Trying %s",uris->str[ix]); 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 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]); 157 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
146 return; 158 return;
147 } 159 }
@@ -154,12 +166,7 @@ @@ -154,12 +166,7 @@
154 if(!strncasecmp(prefer,uris->str[ix],length)) 166 if(!strncasecmp(prefer,uris->str[ix],length))
155 continue; 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 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]); 170 trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
164 return; 171 return;
165 } 172 }
@@ -265,8 +272,13 @@ @@ -265,8 +272,13 @@
265 if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) { 272 if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) {
266 273
267 // CRL download is enabled and verification has failed; look for CRL file. 274 // CRL download is enabled and verification has failed; look for CRL file.
  275 +
268 trace_ssl(hSession,"CRL Validation has failed, requesting CRL download\n"); 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