diff --git a/lib3270.cbp b/lib3270.cbp
index bde1d60..5a3de9c 100644
--- a/lib3270.cbp
+++ b/lib3270.cbp
@@ -134,6 +134,9 @@
+
+
+
diff --git a/src/core/linux/ldap.c b/src/core/linux/ldap.c
new file mode 100644
index 0000000..306b221
--- /dev/null
+++ b/src/core/linux/ldap.c
@@ -0,0 +1,180 @@
+/*
+ * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
+ * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
+ * aplicativos mainframe. Registro no INPI sob o nome G3270.
+ *
+ * Copyright (C) <2008>
+ *
+ * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
+ * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
+ * Free Software Foundation.
+ *
+ * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
+ * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
+ * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
+ * obter mais detalhes.
+ *
+ * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
+ * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
+ * St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Este programa está nomeado como - e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+#include
+
+#if defined(HAVE_LDAP) && defined HAVE_LIBSSL
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define LDAP_DEPRECATED 1
+#include
+
+typedef char LDAPPTR;
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
+{
+ debug("%s(%p)",__FUNCTION__,*message);
+ if(message)
+ ldap_msgfree(*message);
+ *message = NULL;
+}
+
+static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ld)
+{
+ debug("%s(%p)",__FUNCTION__,*ld);
+ if(*ld)
+ ldap_unbind_ext(*ld, NULL, NULL);
+ *ld = NULL;
+}
+
+static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
+{
+ debug("%s(%p)",__FUNCTION__,*ber);
+ if(*ber)
+ ber_free(*ber, 0);
+ *ber = NULL;
+}
+
+static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ ldap_memfree(*ptr);
+ *ptr = NULL;
+}
+
+X509_CRL * lib3270_crl_get_using_ldap(H3270 *hSession, const char *url, const char **error) {
+
+ // Get attributes
+ char * attrs[] = { NULL, NULL };
+ char * base = strchr(url+7,'/');
+ if(!base) {
+ *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
+ errno = EINVAL;
+ return NULL;
+ }
+
+ *(base++) = 0;
+ attrs[0] = strchr(base,'?');
+
+ if(!base) {
+ *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
+ errno = EINVAL;
+ return NULL;
+ }
+
+ *(attrs[0]++) = 0;
+
+ debug("host: \"%s\"",url);
+ debug("Base: \"%s\"",base);
+ debug("Attr: \"%s\"",attrs[0]);
+
+ // Do LDAP Query
+ lib3270_autoptr(LDAP) ld = NULL;
+ lib3270_autoptr(BerElement) ber = NULL;
+
+ int rc = ldap_initialize(&ld, url);
+ if(rc != LDAP_SUCCESS) {
+ *error = ldap_err2string(rc);
+ return NULL;
+ }
+
+ unsigned long version = LDAP_VERSION3;
+ rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
+ if(rc != LDAP_SUCCESS) {
+ *error = ldap_err2string(rc);
+ return NULL;
+ }
+
+ rc = ldap_simple_bind_s(ld, "", "");
+ if(rc != LDAP_SUCCESS) {
+ *error = ldap_err2string(rc);
+ return NULL;
+ }
+
+ lib3270_autoptr(LDAPMessage) results = NULL;
+ rc = ldap_search_ext_s(
+ ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
+ base, // Specifies the DN of the entry at which to start the search.
+ LDAP_SCOPE_BASE, // Specifies the scope of the search.
+ NULL, // Specifies a string representation of the filter to apply in the search.
+ (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
+ 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ &results
+ );
+
+ if(rc != LDAP_SUCCESS) {
+ *error = ldap_err2string(rc);
+ return NULL;
+ }
+
+ lib3270_autoptr(LDAPPTR) attr = ldap_first_attribute(ld, results, &ber);
+ if(!attr) {
+ *error = _("LDAP search did not produce any attributes.");
+ errno = ENOENT;
+ return NULL;
+ }
+
+ //
+ // Load CRL
+ //
+ struct berval ** value = ldap_get_values_len(ld, results, attr);
+ if(!value) {
+ *error =_("LDAP search did not produce any values.");
+ errno = ENOENT;
+ return NULL;
+ }
+
+ X509_CRL * crl = NULL;
+
+ const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
+
+ if(!d2i_X509_CRL(&crl, &crl_data, value[0]->bv_len)) {
+ *error = _( "Can't decode certificate revocation list" );
+ }
+
+ ldap_value_free_len(value);
+
+ return crl;
+
+}
+
+#endif // HAVE_LDAP
diff --git a/src/core/linux/private.h b/src/core/linux/private.h
index 9820807..079a675 100644
--- a/src/core/linux/private.h
+++ b/src/core/linux/private.h
@@ -41,4 +41,8 @@
LIB3270_INTERNAL char * lib3270_url_get_using_curl(H3270 *hSession, const char *u, const char **error);
#endif // HAVE_LIBCURL
+ #if defined(HAVE_LDAP)
+ LIB3270_INTERNAL char * lib3270_url_get_using_ldap(H3270 *hSession, const char *u, const char **error);
+ #endif // HAVE_LDAP
+
#endif // !PRIVATE_H_INCLUDED
diff --git a/src/core/popup.c b/src/core/popup.c
index 5380080..db75fe4 100644
--- a/src/core/popup.c
+++ b/src/core/popup.c
@@ -45,7 +45,7 @@ LIB3270_EXPORT int lib3270_popup(H3270 *hSession, const LIB3270_POPUP *popup, un
return hSession->cbk.popup(hSession,popup,wait);
}
-LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
+int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait) {
LIB3270_POPUP translated = *popup;
diff --git a/src/include/internals.h b/src/include/internals.h
index ae51e79..a9b1118 100644
--- a/src/include/internals.h
+++ b/src/include/internals.h
@@ -888,5 +888,16 @@ LIB3270_INTERNAL void set_ssl_state(H3270 *session, LIB3270_SSL_STATE state);
* @retval ECANCELED Operation was canceled.
* @retval ENOTSUP No popup handler available.
*/
- LIB3270_EXPORT int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait);
+ LIB3270_INTERNAL int lib3270_popup_translated(H3270 *hSession, const LIB3270_POPUP *popup, unsigned char wait);
+#if defined(HAVE_LDAP) && defined (HAVE_LIBSSL)
+ /**
+ * @brief Download X509 CRL using LDAP backend.
+ *
+ * @param hSession tn3270 session handle.
+ * @param url URL for Ldap access.
+ * @param error pointer to error message.
+ *
+ */
+ LIB3270_INTERNAL X509_CRL * lib3270_crl_get_using_ldap(H3270 *hSession, const char *url, const char **error);
+#endif // HAVE_LDAP
diff --git a/src/include/networking.h b/src/include/networking.h
index a85b646..1407838 100644
--- a/src/include/networking.h
+++ b/src/include/networking.h
@@ -224,5 +224,6 @@
LIB3270_INTERNAL int lib3270_activate_ssl_network_module(H3270 *hSession, int sock);
+
#endif // LIB3270_NETWORKING_H_INCLUDED
diff --git a/src/network_modules/openssl/start.c b/src/network_modules/openssl/start.c
index 5e91535..62906c2 100644
--- a/src/network_modules/openssl/start.c
+++ b/src/network_modules/openssl/start.c
@@ -35,13 +35,30 @@
#include "private.h"
#include
- static int import_crl(H3270 *hSession, SSL_CTX * ssl_ctx, LIB3270_NET_CONTEXT * context, const char *crl) {
+ static int import_crl(H3270 *hSession, SSL_CTX * ssl_ctx, LIB3270_NET_CONTEXT * context, const char *url) {
X509_CRL * x509_crl = NULL;
- // Import CRL
- {
- lib3270_autoptr(BIO) bio = BIO_new_mem_buf(crl,-1);
+ const char *error_message = NULL;
+ if(strncasecmp(url,"ldap",4) == 0) {
+
+ // Download using LDAP
+#ifdef HAVE_LDAP
+
+ x509_crl = lib3270_crl_get_using_ldap(hSession, url, &error_message);
+
+#else
+
+ *error_message = _("No LDAP support");
+
+#endif // HAVE_LDAP
+
+ } else {
+
+ // Download with URL
+ lib3270_autoptr(char) crl_text = lib3270_url_get(hSession, url, &error_message);
+
+ lib3270_autoptr(BIO) bio = BIO_new_mem_buf(crl_text,-1);
BIO * b64 = BIO_new(BIO_f_base64());
bio = BIO_push(b64, bio);
@@ -49,15 +66,21 @@
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
if(!d2i_X509_CRL_bio(bio, &x509_crl)) {
- trace_ssl(hSession,"Can't decode CRL data:\n%s\n",crl);
- return -1;
+ trace_ssl(hSession,"Can't decode CRL data:\n%s\n",crl_text);
+ error_message = _("Can't decode CRL data");
}
- lib3270_openssl_crl_free(context);
- context->crl.cert = x509_crl;
-
}
+ if(error_message)
+ trace_ssl(hSession,"Error downloading CRL from %s: %s\n",url,error_message);
+
+ if(!x509_crl)
+ return -1;
+
+ lib3270_openssl_crl_free(context);
+ context->crl.cert = x509_crl;
+
if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) {
lib3270_autoptr(BIO) bio = BIO_new(BIO_s_mem());
@@ -88,7 +111,7 @@
}
- static void download_crl(H3270 *hSession, SSL_CTX * ctx_context, LIB3270_NET_CONTEXT * context, X509 *peer) {
+ static void download_crl_from_peer(H3270 *hSession, SSL_CTX * ctx_context, LIB3270_NET_CONTEXT * context, X509 *peer) {
debug("%s peer=%p",__FUNCTION__,(void *) peer);
@@ -102,8 +125,6 @@
}
size_t ix;
- const char * error_message = NULL;
- lib3270_autoptr(char) crl_text = NULL;
const char *prefer = lib3270_crl_get_preferred_protocol(hSession);
if(!prefer) {
@@ -111,12 +132,7 @@
// No preferred protocol, try all uris.
for(ix = 0; ix < uris->length; ix++) {
- debug("Trying %s",uris->str[ix]);
- crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
-
- if(error_message) {
- trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
- } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
+ if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
return;
}
@@ -137,11 +153,7 @@
continue;
debug("Trying %s",uris->str[ix]);
- crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
-
- if(error_message) {
- trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
- } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
+ if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
return;
}
@@ -154,12 +166,7 @@
if(!strncasecmp(prefer,uris->str[ix],length))
continue;
- debug("Trying %s",uris->str[ix]);
- crl_text = lib3270_url_get(hSession, uris->str[ix], &error_message);
-
- if(error_message) {
- trace_ssl(hSession,"Error downloading CRL from %s: %s\n",uris->str[ix],error_message);
- } else if(!import_crl(hSession, ctx_context, context, crl_text)) {
+ if(!import_crl(hSession,ctx_context,context,uris->str[ix])) {
trace_ssl(hSession,"Got CRL from %s\n",uris->str[ix]);
return;
}
@@ -265,8 +272,13 @@
if(lib3270_ssl_get_crl_download(hSession) && SSL_get_verify_result(context->con) == X509_V_ERR_UNABLE_TO_GET_CRL) {
// CRL download is enabled and verification has failed; look for CRL file.
+
trace_ssl(hSession,"CRL Validation has failed, requesting CRL download\n");
- download_crl(hSession, ctx_context, context, peer);
+ if(context->crl.url) {
+ import_crl(hSession, ctx_context,context,context->crl.url);
+ } else {
+ download_crl_from_peer(hSession, ctx_context, context, peer);
+ }
}
--
libgit2 0.21.2