diff --git a/.gitignore b/.gitignore
index 5386f78..ff9b350 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,7 @@ scripts
vgcore.*
doxygen/html
*.crl
+*.sh
src/include/lib3270/actions.h
doxygen/doxyfile
win32-configure*
diff --git a/lib3270.cbp b/lib3270.cbp
index 7d298f9..1dcead6 100644
--- a/lib3270.cbp
+++ b/lib3270.cbp
@@ -266,18 +266,29 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ssl/linux/curl.c b/src/ssl/linux/curl.c
new file mode 100644
index 0000000..93ac9e1
--- /dev/null
+++ b/src/ssl/linux/curl.c
@@ -0,0 +1,324 @@
+/*
+ * "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)
+ *
+ *
+ * References:
+ *
+ * http://www.openssl.org/docs/ssl/
+ * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
+ *
+ */
+
+#include
+
+#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBCURL)
+
+#include "private.h"
+#include
+
+#define CRL_DATA_LENGTH 2048
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ curl_easy_cleanup(*ptr);
+ *ptr = NULL;
+}
+
+typedef struct _curldata
+{
+ size_t length;
+ H3270 * hSession;
+ SSL_ERROR_MESSAGE * message;
+ char errbuf[CURL_ERROR_SIZE];
+ struct {
+ size_t length;
+ unsigned char * contents;
+ } data;
+} CURLDATA;
+
+static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ {
+ CURLDATA *cdata = *ptr;
+
+ if(cdata->data.contents) {
+ lib3270_free(cdata->data.contents);
+ cdata->data.contents = NULL;
+ }
+ lib3270_free(cdata);
+ }
+ *ptr = NULL;
+}
+
+static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ BIO_free_all(*ptr);
+ *ptr = NULL;
+}
+
+static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ CURLDATA * data = (CURLDATA *) userp;
+
+ debug("%s",__FUNCTION__);
+
+ size_t realsize = size * nmemb;
+
+ debug("%s size=%d data->length=%d crldatalength=%d",__FUNCTION__,(int) size, (int) data->length, CRL_DATA_LENGTH);
+
+ if((realsize + data->length) > data->data.length)
+ {
+ data->data.length += (CRL_DATA_LENGTH + realsize);
+ data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
+ memset(&(data->data.contents[data->length]),0,data->data.length-data->length);
+ }
+
+ debug("%s",__FUNCTION__);
+
+ if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
+ {
+ lib3270_trace_data(
+ data->hSession,
+ "Received",
+ (const char *) contents,
+ realsize
+ );
+ }
+
+ debug("%s",__FUNCTION__);
+
+ memcpy(&(data->data.contents[data->length]),contents,realsize);
+ data->length += realsize;
+
+ debug("%s",__FUNCTION__);
+
+ return realsize;
+}
+
+static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype type, char *data, size_t size, void *userp)
+{
+ const char * text = NULL;
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ lib3270_write_log(((CURLDATA *) userp)->hSession,"curl","%s",data);
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+
+ default:
+ return 0;
+
+ }
+
+ lib3270_trace_data(
+ ((CURLDATA *) userp)->hSession,
+ text,
+ data,
+ size
+ );
+
+ return 0;
+}
+
+LIB3270_INTERNAL X509_CRL * get_crl_using_curl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
+{
+ X509_CRL * x509_crl = NULL;
+
+ // Use CURL to download the CRL
+ lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
+ lib3270_autoptr(CURL) hCurl = curl_easy_init();
+
+ memset(crl_data,0,sizeof(CURLDATA));
+ crl_data->message = message;
+ crl_data->hSession = hSession;
+ crl_data->data.length = CRL_DATA_LENGTH;
+ crl_data->data.contents = lib3270_malloc(crl_data->data.length);
+
+ if(!hCurl)
+ {
+ message->title = _( "Security error" );
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = _( "Can't initialize curl operation" );
+ return NULL;
+ }
+
+ CURLcode res;
+
+ curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
+ curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
+
+ curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
+
+ curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
+ curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
+
+ curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
+
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
+ {
+ curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
+ curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
+ }
+
+ res = curl_easy_perform(hCurl);
+
+ if(res != CURLE_OK)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+
+ if(crl_data->errbuf[0])
+ {
+ message->text = curl_easy_strerror(res);
+ message->description = crl_data->errbuf;
+ }
+ else
+ {
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = curl_easy_strerror(res);
+ }
+
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
+ errno = EINVAL;
+ return NULL;
+
+ }
+
+ char *ct = NULL;
+ res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
+ if(res != CURLE_OK)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = curl_easy_strerror(res);
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
+ lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
+
+ if(ct)
+ {
+ const unsigned char * data = crl_data->data.contents;
+
+
+ if(strcasecmp(ct,"application/pkix-crl") == 0)
+ {
+ // CRL File, convert it
+ if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Can't decode certificate revocation list" );
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
+ return NULL;
+ }
+ }
+ else
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Got an invalid certificate revocation list from server" );
+ lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
+ errno = EINVAL;
+ return NULL;
+ }
+ }
+ else if(strncasecmp(consturl,"ldap://",7) == 0)
+ {
+ // It's an LDAP query, assumes a base64 data.
+ char * data = strstr((char *) crl_data->data.contents,":: ");
+ if(!data)
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Got a bad formatted certificate revocation list from LDAP server" );
+ lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n",consturl, crl_data->data.contents);
+ errno = EINVAL;
+ return NULL;
+ }
+ data += 3;
+
+ lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1);
+
+ BIO * b64 = BIO_new(BIO_f_base64());
+ bio = BIO_push(b64, bio);
+
+ BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
+
+ if(!d2i_X509_CRL_bio(bio, &x509_crl))
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Can't decode certificate revocation list got from LDAP server" );
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ }
+
+ return x509_crl;
+
+}
+
+#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK && HAVE_LIBCURL
diff --git a/src/ssl/linux/getcrl.c b/src/ssl/linux/getcrl.c
index c76c8ec..27df0f4 100644
--- a/src/ssl/linux/getcrl.c
+++ b/src/ssl/linux/getcrl.c
@@ -33,33 +33,10 @@
*
*/
-#define CRL_DATA_LENGTH 2048
-
-#include
+#include "private.h"
#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
-#include
-#include
-#include
-#include
-
-#ifdef HAVE_LDAP
- #define LDAP_DEPRECATED 1
- #include
-#endif // HAVE_LDAP
-
-#ifdef HAVE_LIBCURL
- #include
-#endif // HAVE_LIBCURL
-
-#include
-#include
-#include
-#include
-#include
-#include
-
/*--[ Implement ]------------------------------------------------------------------------------------*/
static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
@@ -68,176 +45,6 @@ static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
fclose(*file);
}
-#ifdef HAVE_LDAP
-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;
-}
-
-#endif // HAVE_LDAP
-
-#ifdef HAVE_LIBCURL
-static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- curl_easy_cleanup(*ptr);
- *ptr = NULL;
-}
-
-typedef struct _curldata
-{
- size_t length;
- H3270 * hSession;
- SSL_ERROR_MESSAGE * message;
- char errbuf[CURL_ERROR_SIZE];
- struct {
- size_t length;
- unsigned char * contents;
- } data;
-} CURLDATA;
-
-static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- {
- CURLDATA *cdata = *ptr;
-
- if(cdata->data.contents) {
- lib3270_free(cdata->data.contents);
- cdata->data.contents = NULL;
- }
- lib3270_free(cdata);
- }
- *ptr = NULL;
-}
-
-static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- BIO_free_all(*ptr);
- *ptr = NULL;
-}
-
-static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp)
-{
- CURLDATA * data = (CURLDATA *) userp;
-
- debug("%s",__FUNCTION__);
-
- size_t realsize = size * nmemb;
-
- debug("%s size=%d data->length=%d crldatalength=%d",__FUNCTION__,(int) size, (int) data->length, CRL_DATA_LENGTH);
-
- if((realsize + data->length) > data->data.length)
- {
- data->data.length += (CRL_DATA_LENGTH + realsize);
- data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
- memset(&(data->data.contents[data->length]),0,data->data.length-data->length);
- }
-
- debug("%s",__FUNCTION__);
-
- if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
- {
- lib3270_trace_data(
- data->hSession,
- "Received",
- (const char *) contents,
- realsize
- );
- }
-
- debug("%s",__FUNCTION__);
-
- memcpy(&(data->data.contents[data->length]),contents,realsize);
- data->length += realsize;
-
- debug("%s",__FUNCTION__);
-
- return realsize;
-}
-
-static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype type, char *data, size_t size, void *userp)
-{
- const char * text = NULL;
-
- switch (type) {
- case CURLINFO_TEXT:
- lib3270_write_log(((CURLDATA *) userp)->hSession,"curl","%s",data);
- return 0;
-
- case CURLINFO_HEADER_OUT:
- text = "=> Send header";
- break;
-
- case CURLINFO_DATA_OUT:
- text = "=> Send data";
- break;
-
- case CURLINFO_SSL_DATA_OUT:
- text = "=> Send SSL data";
- break;
-
- case CURLINFO_HEADER_IN:
- text = "<= Recv header";
- break;
-
- case CURLINFO_DATA_IN:
- text = "<= Recv data";
- break;
-
- case CURLINFO_SSL_DATA_IN:
- text = "<= Recv SSL data";
- break;
-
- default:
- return 0;
-
- }
-
- lib3270_trace_data(
- ((CURLDATA *) userp)->hSession,
- text,
- data,
- size
- );
-
- return 0;
-}
-
-#endif // HAVE_LIBCURL
-
-
LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
{
X509_CRL * x509_crl = NULL;
@@ -288,148 +95,7 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
#ifdef HAVE_LDAP
else if(strncasecmp(consturl,"ldap://",7) == 0 && strlen(consturl) > 8)
{
- int rc;
- lib3270_autoptr(char) url = strdup(consturl);
- char * base = strchr(url+7,'/');
- char * attrs[] = { NULL, NULL };
-
- if(!base)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "No DN of the entry at which to start the search on the URL" );
- message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
- return errno = EINVAL;
- }
-
- *(base++) = 0;
- attrs[0] = strchr(base,'?');
-
- if(!base)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "No LDAP attribute on the URL" );
- message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
- return errno = EINVAL;
- }
-
- *(attrs[0]++) = 0;
-
- debug("host: \"%s\"",url);
- debug("Base: \"%s\"",base);
- debug("Attr: \"%s\"",attrs[0]);
-
- // Do LDAP Query
- LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL;
- BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL;
-
- rc = ldap_initialize(&ld, url);
- if(rc != LDAP_SUCCESS)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't initialize LDAP" );
- message->description = ldap_err2string(rc);
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- return -1;
- }
-
- unsigned long version = LDAP_VERSION3;
- rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
- if(rc != LDAP_SUCCESS) {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't set LDAP version" );
- message->description = ldap_err2string(rc);
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- return NULL;
- }
-
- rc = ldap_simple_bind_s(ld, "", "");
- if(rc != LDAP_SUCCESS)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't bind to LDAP server" );
- message->description = ldap_err2string(rc);
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- return -1;
- }
-
- 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)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't search LDAP server" );
- message->description = ldap_err2string(rc);
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- return NULL;
- }
-
- char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
- if(!attr)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't get LDAP attribute" );
- message->description = _("Search did not produce any attributes.");
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- errno = ENOENT;
- return NULL;
- }
-
- struct berval ** value = ldap_get_values_len(ld, results, attr);
- if(!value)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't get LDAP attribute" );
- message->description = _("Search did not produce any values.");
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
- errno = ENOENT;
- return NULL;
- }
-
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
- {
- lib3270_trace_data(
- hSession,
- "CRL Data received from LDAP server",
- (const char *) value[0]->bv_val,
- value[0]->bv_len
- );
- }
-
- // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
- const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
-
- if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Can't decode CRL" );
- lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
- ldap_value_free_len(value);
- return NULL;
- }
-
- ldap_value_free_len(value);
+ return get_crl_using_ldap(hSession, message, consturl);
}
#endif // HAVE_LDAP
@@ -437,151 +103,7 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
{
#ifdef HAVE_LIBCURL
- // Use CURL to download the CRL
- lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
- lib3270_autoptr(CURL) hCurl = curl_easy_init();
-
- memset(crl_data,0,sizeof(CURLDATA));
- crl_data->message = message;
- crl_data->hSession = hSession;
- crl_data->data.length = CRL_DATA_LENGTH;
- crl_data->data.contents = lib3270_malloc(crl_data->data.length);
-
- if(hCurl)
- {
- CURLcode res;
-
- curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
- curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
-
- curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
-
- curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
- curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
-
- curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
-
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
- {
- curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
- curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
- curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
- }
-
- res = curl_easy_perform(hCurl);
-
- if(res != CURLE_OK)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
-
- if(crl_data->errbuf[0])
- {
- message->text = curl_easy_strerror(res);
- message->description = crl_data->errbuf;
- }
- else
- {
- message->text = _( "Error loading CRL" );
- message->description = curl_easy_strerror(res);
- }
-
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
- errno = EINVAL;
- return NULL;
-
- }
-
- char *ct = NULL;
- res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
- if(res != CURLE_OK)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Error loading CRL" );
- message->description = curl_easy_strerror(res);
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
- errno = EINVAL;
- return NULL;
- }
-
- if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
- lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
-
- if(ct)
- {
- const unsigned char * data = crl_data->data.contents;
-
-
- if(strcasecmp(ct,"application/pkix-crl") == 0)
- {
- // CRL File, convert it
- if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Can't decode CRL" );
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
- return NULL;
- }
- }
- else
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Got an invalid CRL from server" );
- lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
- errno = EINVAL;
- return NULL;
- }
- }
- else if(strncasecmp(consturl,"ldap://",7) == 0)
- {
- // It's an LDAP query, assumes a base64 data.
- char * data = strstr((char *) crl_data->data.contents,":: ");
- if(!data)
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Got a bad formatted CRL from LDAP server" );
- lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n",consturl, crl_data->data.contents);
- errno = EINVAL;
- return NULL;
- }
- data += 3;
-
-#ifdef DEBUG
- {
- FILE *out = fopen("linux_base64.crl","w");
- if(out)
- {
- fwrite(data,strlen(data),1,out);
- fclose(out);
- }
-
- }
-#endif
-
- lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1);
-
- BIO * b64 = BIO_new(BIO_f_base64());
- bio = BIO_push(b64, bio);
-
- BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
-
- if(!d2i_X509_CRL_bio(bio, &x509_crl))
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Can't decode CRL got from LDAP server" );
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
- errno = EINVAL;
- return NULL;
- }
-
- }
-
- }
+ return get_crl_using_curl(hSession, message, consturl);
#else
// Can't get CRL.
diff --git a/src/ssl/linux/ldap.c b/src/ssl/linux/ldap.c
new file mode 100644
index 0000000..3f0683b
--- /dev/null
+++ b/src/ssl/linux/ldap.c
@@ -0,0 +1,228 @@
+/*
+ * "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)
+ *
+ *
+ * References:
+ *
+ * http://www.openssl.org/docs/ssl/
+ * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
+ *
+ */
+
+#include
+
+#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
+
+#define LDAP_DEPRECATED 1
+#include
+
+/*--[ 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;
+}
+
+LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
+{
+ X509_CRL * x509_crl = NULL;
+
+ int rc;
+ lib3270_autoptr(char) url = strdup(consturl);
+ char * base = strchr(url+7,'/');
+ char * attrs[] = { NULL, NULL };
+
+ if(!base)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "No DN of the entry at which to start the search on the URL" );
+ message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
+ return errno = EINVAL;
+ }
+
+ *(base++) = 0;
+ attrs[0] = strchr(base,'?');
+
+ if(!base)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "No LDAP attribute on the URL" );
+ message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
+ return errno = EINVAL;
+ }
+
+ *(attrs[0]++) = 0;
+
+ debug("host: \"%s\"",url);
+ debug("Base: \"%s\"",base);
+ debug("Attr: \"%s\"",attrs[0]);
+
+ // Do LDAP Query
+ LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL;
+ BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL;
+
+ rc = ldap_initialize(&ld, url);
+ if(rc != LDAP_SUCCESS)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't initialize LDAP" );
+ message->description = ldap_err2string(rc);
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ return -1;
+ }
+
+ unsigned long version = LDAP_VERSION3;
+ rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version);
+ if(rc != LDAP_SUCCESS) {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't set LDAP version" );
+ message->description = ldap_err2string(rc);
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ return NULL;
+ }
+
+ rc = ldap_simple_bind_s(ld, "", "");
+ if(rc != LDAP_SUCCESS)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't bind to LDAP server" );
+ message->description = ldap_err2string(rc);
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ return -1;
+ }
+
+ 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)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't search LDAP server" );
+ message->description = ldap_err2string(rc);
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ return NULL;
+ }
+
+ char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
+ if(!attr)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't get LDAP attribute" );
+ message->description = _("Search did not produce any attributes.");
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ errno = ENOENT;
+ return NULL;
+ }
+
+ struct berval ** value = ldap_get_values_len(ld, results, attr);
+ if(!value)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't get LDAP attribute" );
+ message->description = _("Search did not produce any values.");
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
+ errno = ENOENT;
+ return NULL;
+ }
+
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
+ {
+ lib3270_trace_data(
+ hSession,
+ "CRL Data received from LDAP server",
+ (const char *) value[0]->bv_val,
+ value[0]->bv_len
+ );
+ }
+
+ // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
+ const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
+
+ if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Can't decode certificate revocation list" );
+ lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
+ ldap_value_free_len(value);
+ return NULL;
+ }
+
+ ldap_value_free_len(value);
+
+ return x509_crl;
+
+}
+
+#endif // HAVE_LIBSSL && SSL_ENABLE_CRL_CHECK && HAVE_LDAP
diff --git a/src/ssl/linux/private.h b/src/ssl/linux/private.h
new file mode 100644
index 0000000..3f1726b
--- /dev/null
+++ b/src/ssl/linux/private.h
@@ -0,0 +1,63 @@
+/*
+ * "Software G3270, 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 ', 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 private.h e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
+ *
+ */
+
+#ifndef LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
+
+ #define LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
+
+ #include
+
+ #include
+ #include
+ #include
+ #include
+
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+
+ #ifdef HAVE_LDAP
+
+ /// @brief Use libldap to get CRL.
+ LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
+
+ #endif // HAVE_LDAP
+
+ #ifdef HAVE_LIBCURL
+
+ /// @brief Use libcurl to get CRL.
+ LIB3270_INTERNAL X509_CRL * get_crl_using_curl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
+
+ #endif // HAVE_LIBCURL
+
+
+#endif // !LIB3270_LINUX_SSL_PRIVATE_H_INCLUDED
diff --git a/src/ssl/windows/curl.c b/src/ssl/windows/curl.c
new file mode 100644
index 0000000..7ab0017
--- /dev/null
+++ b/src/ssl/windows/curl.c
@@ -0,0 +1,381 @@
+/*
+ * "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)
+ *
+ * References:
+ *
+ * http://www.openssl.org/docs/ssl/
+ * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
+ *
+ */
+
+#include
+
+#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBCURL)
+
+#include "private.h"
+#include
+
+#define CRL_DATA_LENGTH 2048
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ curl_easy_cleanup(*ptr);
+ *ptr = NULL;
+}
+
+typedef struct _curldata
+{
+ size_t length;
+ H3270 * hSession;
+ SSL_ERROR_MESSAGE * message;
+ char errbuf[CURL_ERROR_SIZE];
+ struct {
+ size_t length;
+ unsigned char * contents;
+ } data;
+} CURLDATA;
+
+static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ {
+ CURLDATA *cdata = *ptr;
+
+ if(cdata->data.contents) {
+ lib3270_free(cdata->data.contents);
+ cdata->data.contents = NULL;
+ }
+ lib3270_free(cdata);
+ }
+ *ptr = NULL;
+}
+
+static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr)
+{
+ debug("%s(%p)",__FUNCTION__,*ptr);
+ if(*ptr)
+ BIO_free_all(*ptr);
+ *ptr = NULL;
+}
+
+static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ CURLDATA * data = (CURLDATA *) userp;
+
+ size_t realsize = size * nmemb;
+ size_t ix;
+
+ debug("Received %u bytes (datablock is %p)", (unsigned int) realsize, data);
+
+ unsigned char *ptr = (unsigned char *) contents;
+
+ if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
+ lib3270_trace_data(data->hSession,"curl_write:",(const char *) contents, realsize);
+
+ if((realsize + data->length) > data->data.length)
+ {
+ data->data.length += (CRL_DATA_LENGTH + realsize);
+ data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
+
+ for(ix = data->length; ix < data->data.length; ix++)
+ {
+ data->data.contents[ix] = 0;
+ }
+
+ }
+
+ for(ix = 0; ix < realsize; ix++)
+ {
+ data->data.contents[data->length++] = *(ptr++);
+ }
+
+ return realsize;
+}
+
+static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype type, char *data, size_t size, void *userp)
+{
+ const char * text = NULL;
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ lib3270_write_log(((CURLDATA *) userp)->hSession,"curl","%s",data);
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+
+ default:
+ return 0;
+
+ }
+
+ lib3270_trace_data(
+ ((CURLDATA *) userp)->hSession,
+ text,
+ data,
+ size
+ );
+
+ return 0;
+}
+
+X509_CRL * get_crl_using_curl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
+{
+ X509_CRL * x509_crl = NULL;
+
+ lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
+ lib3270_autoptr(CURL) hCurl = curl_easy_init();
+
+ memset(crl_data,0,sizeof(CURLDATA));
+ crl_data->message = message;
+ crl_data->hSession = hSession;
+ crl_data->data.length = CRL_DATA_LENGTH;
+ crl_data->data.contents = lib3270_malloc(crl_data->data.length);
+
+ if(!hCurl)
+ {
+ message->title = _( "Security error" );
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = _( "Can't initialize curl operation" );
+ return NULL;
+ }
+
+ CURLcode res;
+
+ curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
+ curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
+
+ curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
+
+ curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
+ curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
+
+ curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
+
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
+ {
+ curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
+ curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
+ }
+
+ res = curl_easy_perform(hCurl);
+
+ if(res != CURLE_OK)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+
+ if(crl_data->errbuf[0])
+ {
+ message->text = curl_easy_strerror(res);
+ message->description = crl_data->errbuf;
+ }
+ else
+ {
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = curl_easy_strerror(res);
+ }
+
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
+ errno = EINVAL;
+ return NULL;
+
+ }
+
+ char *ct = NULL;
+ res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
+ if(res != CURLE_OK)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Error loading certificate revocation list" );
+ message->description = curl_easy_strerror(res);
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
+ lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
+
+ if(ct)
+ {
+ const unsigned char * data = crl_data->data.contents;
+
+ if(strcasecmp(ct,"application/pkix-crl") == 0)
+ {
+ // CRL File, convert it
+ if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Can't decode certificate revocation list" );
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
+ return NULL;
+ }
+ }
+ else
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Got an invalid certificate revocation list from server" );
+ lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
+ errno = EINVAL;
+ return NULL;
+ }
+ }
+ else if(strncasecmp(consturl,"ldap://",7) == 0)
+ {
+ //
+ // curl's LDAP query on windows returns diferently. Working with it.
+ //
+#ifdef DEBUG
+ {
+ FILE *out = fopen("downloaded.crl","w");
+ if(out)
+ {
+ fwrite(crl_data->data.contents,crl_data->length,1,out);
+ fclose(out);
+ }
+
+ }
+#endif
+
+ char * attr = strchr(consturl,'?');
+ if(!attr)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "No attribute in LDAP search URL" );
+ errno = ENOENT;
+ return NULL;
+ }
+
+ attr++;
+
+ lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr);
+ trace_ssl(crl_data->hSession, text);
+
+ lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr);
+
+
+// char *ptr = strcasestr((char *) crl_data->data.contents, key);
+
+ size_t ix;
+ unsigned char *from = NULL;
+ size_t keylength = strlen(key);
+ for(ix = 0; ix < (crl_data->length - keylength); ix++)
+ {
+ if(!strncasecmp( (char *) (crl_data->data.contents+ix),key,keylength))
+ {
+ from = crl_data->data.contents+ix;
+ break;
+ }
+ }
+
+ debug("strstr(%s): %p", key, from);
+
+ if(!from)
+ {
+ message->error = hSession->ssl.error = 0;
+ message->title = _( "Security error" );
+ message->text = _( "Can't find certificate revocation list in LDAP response" );
+ errno = ENOENT;
+ return NULL;
+ }
+
+ from += strlen(key);
+ size_t length = crl_data->length - (from - crl_data->data.contents);
+
+ static const char terminator[] = { 0x0a, 0x0a, 0x09 };
+ unsigned char *to = from+length;
+
+ for(ix = 0; ix < (length - sizeof(terminator)); ix++)
+ {
+ if(!memcmp(from+ix,terminator,sizeof(terminator)))
+ {
+ to = from+ix;
+ break;
+ }
+ }
+
+ length = to - from;
+
+ if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
+ {
+ lib3270_trace_data(
+ hSession,
+ "CRL Data received from LDAP server",
+ (const char *) from,
+ length
+ );
+ }
+
+ if(!d2i_X509_CRL(&x509_crl, (const unsigned char **) &from, length))
+ {
+ message->error = hSession->ssl.error = ERR_get_error();
+ message->title = _( "Security error" );
+ message->text = _( "Can't decode certificate revocation list got from LDAP Search" );
+ lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ }
+
+ return x509_crl;
+
+}
+
+#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBCURL)
diff --git a/src/ssl/windows/getcrl.c b/src/ssl/windows/getcrl.c
index 5aaf292..c98b3e7 100644
--- a/src/ssl/windows/getcrl.c
+++ b/src/ssl/windows/getcrl.c
@@ -33,31 +33,15 @@
*
*/
-#define CRL_DATA_LENGTH 2048
-
#include
-#include
-#include
-#include
-
#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
-#include
-#include
-#include
-#include
+#include "private.h"
-#ifdef HAVE_LIBCURL
- #include
-#endif // HAVE_LIBCURL
+#define CRL_DATA_LENGTH 2048
-#include
-#include
-#include
-#include
-#include
-#include
+// #include
/*--[ Implement ]------------------------------------------------------------------------------------*/
@@ -67,136 +51,6 @@ static inline void lib3270_autoptr_cleanup_FILE(FILE **file)
fclose(*file);
}
-#ifdef HAVE_LIBCURL
-static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- curl_easy_cleanup(*ptr);
- *ptr = NULL;
-}
-
-typedef struct _curldata
-{
- size_t length;
- H3270 * hSession;
- SSL_ERROR_MESSAGE * message;
- char errbuf[CURL_ERROR_SIZE];
- struct {
- size_t length;
- unsigned char * contents;
- } data;
-} CURLDATA;
-
-static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- {
- CURLDATA *cdata = *ptr;
-
- if(cdata->data.contents) {
- lib3270_free(cdata->data.contents);
- cdata->data.contents = NULL;
- }
- lib3270_free(cdata);
- }
- *ptr = NULL;
-}
-
-static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr)
-{
- debug("%s(%p)",__FUNCTION__,*ptr);
- if(*ptr)
- BIO_free_all(*ptr);
- *ptr = NULL;
-}
-
-static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp)
-{
- CURLDATA * data = (CURLDATA *) userp;
-
- size_t realsize = size * nmemb;
- size_t ix;
-
- debug("Received %u bytes (datablock is %p)", (unsigned int) realsize, data);
-
- unsigned char *ptr = (unsigned char *) contents;
-
- if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
- lib3270_trace_data(data->hSession,"curl_write:",(const char *) contents, realsize);
-
- if((realsize + data->length) > data->data.length)
- {
- data->data.length += (CRL_DATA_LENGTH + realsize);
- data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
-
- for(ix = data->length; ix < data->data.length; ix++)
- {
- data->data.contents[ix] = 0;
- }
-
- }
-
- for(ix = 0; ix < realsize; ix++)
- {
- data->data.contents[data->length++] = *(ptr++);
- }
-
- return realsize;
-}
-
-static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype type, char *data, size_t size, void *userp)
-{
- const char * text = NULL;
-
- switch (type) {
- case CURLINFO_TEXT:
- lib3270_write_log(((CURLDATA *) userp)->hSession,"curl","%s",data);
- return 0;
-
- case CURLINFO_HEADER_OUT:
- text = "=> Send header";
- break;
-
- case CURLINFO_DATA_OUT:
- text = "=> Send data";
- break;
-
- case CURLINFO_SSL_DATA_OUT:
- text = "=> Send SSL data";
- break;
-
- case CURLINFO_HEADER_IN:
- text = "<= Recv header";
- break;
-
- case CURLINFO_DATA_IN:
- text = "<= Recv data";
- break;
-
- case CURLINFO_SSL_DATA_IN:
- text = "<= Recv SSL data";
- break;
-
- default:
- return 0;
-
- }
-
- lib3270_trace_data(
- ((CURLDATA *) userp)->hSession,
- text,
- data,
- size
- );
-
- return 0;
-}
-
-#endif // HAVE_LIBCURL
-
-
LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
{
X509_CRL * x509_crl = NULL;
@@ -248,202 +102,7 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
{
#ifdef HAVE_LIBCURL
- // Use CURL to download the CRL
- lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
- lib3270_autoptr(CURL) hCurl = curl_easy_init();
-
- memset(crl_data,0,sizeof(CURLDATA));
- crl_data->message = message;
- crl_data->hSession = hSession;
- crl_data->data.length = CRL_DATA_LENGTH;
- crl_data->data.contents = lib3270_malloc(crl_data->data.length);
-
- if(hCurl)
- {
- CURLcode res;
-
- curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
- curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
-
- curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
-
- curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
- curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
-
- curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
-
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
- {
- curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
- curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
- curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
- }
-
- res = curl_easy_perform(hCurl);
-
- if(res != CURLE_OK)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
-
- if(crl_data->errbuf[0])
- {
- message->text = curl_easy_strerror(res);
- message->description = crl_data->errbuf;
- }
- else
- {
- message->text = _( "Error loading CRL" );
- message->description = curl_easy_strerror(res);
- }
-
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
- errno = EINVAL;
- return NULL;
-
- }
-
- char *ct = NULL;
- res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
- if(res != CURLE_OK)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Error loading CRL" );
- message->description = curl_easy_strerror(res);
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
- errno = EINVAL;
- return NULL;
- }
-
- if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
- lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
-
- if(ct)
- {
- const unsigned char * data = crl_data->data.contents;
-
- if(strcasecmp(ct,"application/pkix-crl") == 0)
- {
- // CRL File, convert it
- if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Can't decode CRL" );
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
- return NULL;
- }
- }
- else
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Got an invalid CRL from server" );
- lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
- errno = EINVAL;
- return NULL;
- }
- }
- else if(strncasecmp(consturl,"ldap://",7) == 0)
- {
- //
- // curl's LDAP query on windows returns diferently. Working with it.
- //
-#ifdef DEBUG
- {
- FILE *out = fopen("downloaded.crl","w");
- if(out)
- {
- fwrite(crl_data->data.contents,crl_data->length,1,out);
- fclose(out);
- }
-
- }
-#endif
-
- char * attr = strchr(consturl,'?');
- if(!attr)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "No attribute in LDAP search URL" );
- errno = ENOENT;
- return NULL;
- }
-
- attr++;
-
- lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr);
- trace_ssl(crl_data->hSession, text);
-
- lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr);
-
-
-// char *ptr = strcasestr((char *) crl_data->data.contents, key);
-
- size_t ix;
- unsigned char *from = NULL;
- size_t keylength = strlen(key);
- for(ix = 0; ix < (crl_data->length - keylength); ix++)
- {
- if(!strncasecmp( (char *) (crl_data->data.contents+ix),key,keylength))
- {
- from = crl_data->data.contents+ix;
- break;
- }
- }
-
- debug("strstr(%s): %p", key, from);
-
- if(!from)
- {
- message->error = hSession->ssl.error = 0;
- message->title = _( "Security error" );
- message->text = _( "Can't find attribute in LDAP response" );
- errno = ENOENT;
- return NULL;
- }
-
- from += strlen(key);
- size_t length = crl_data->length - (from - crl_data->data.contents);
-
- static const char terminator[] = { 0x0a, 0x0a, 0x09 };
- unsigned char *to = from+length;
-
- for(ix = 0; ix < (length - sizeof(terminator)); ix++)
- {
- if(!memcmp(from+ix,terminator,sizeof(terminator)))
- {
- to = from+ix;
- break;
- }
- }
-
- length = to - from;
-
- if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
- {
- lib3270_trace_data(
- hSession,
- "CRL Data received from LDAP server",
- (const char *) from,
- length
- );
- }
-
- if(!d2i_X509_CRL(&x509_crl, (const unsigned char **) &from, length))
- {
- message->error = hSession->ssl.error = ERR_get_error();
- message->title = _( "Security error" );
- message->text = _( "Can't decode CRL got from LDAP Search" );
- lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
- errno = EINVAL;
- return NULL;
- }
-
- }
- }
+ return get_crl_using_curl(hSession, message, consturl);
#else
// Can't get CRL.
diff --git a/src/ssl/windows/private.h b/src/ssl/windows/private.h
new file mode 100644
index 0000000..abc9d71
--- /dev/null
+++ b/src/ssl/windows/private.h
@@ -0,0 +1,63 @@
+/*
+ * "Software G3270, 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 ', 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 private.h e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
+ *
+ */
+
+#ifndef LIB3270_WIN32_SSL_PRIVATE_H_INCLUDED
+
+ #define LIB3270_WIN32_SSL_PRIVATE_H_INCLUDED
+
+ #include
+
+ #include
+ #include
+
+ #include
+ #include
+ #include
+ #include
+
+ #include
+ #include
+ #include
+ #include
+ #include
+ #include
+
+ #ifdef HAVE_LIBCURL
+
+ #include
+
+ /// @brief Use libcurl to get CRL.
+ LIB3270_INTERNAL X509_CRL * get_crl_using_curl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
+
+ #endif // HAVE_LIBCURL
+
+ // LIB3270_INTERNAL X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
+
+
+#endif // !LIB3270_WIN32_SSL_PRIVATE_H_INCLUDED
--
libgit2 0.21.2