Commit fa9d0adc83d999807a08becf9ac907578cd32510

Authored by Perry Werneck
1 parent 4fd901ec

Reactivating win-ldap.

lib3270.cbp
... ... @@ -237,6 +237,9 @@
237 237 <Unit filename="src/core/windows/http.c">
238 238 <Option compilerVar="CC" />
239 239 </Unit>
  240 + <Unit filename="src/core/windows/ldap.c">
  241 + <Option compilerVar="CC" />
  242 + </Unit>
240 243 <Unit filename="src/core/windows/log.c">
241 244 <Option compilerVar="CC" />
242 245 </Unit>
... ...
src/core/windows/ldap.c 0 → 100644
... ... @@ -0,0 +1,232 @@
  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 + * References:
  29 + *
  30 + * https://docs.microsoft.com/en-us/windows/win32/api/winldap/
  31 + * https://github.com/curl/curl/blob/curl-7_62_0/lib/ldap.c
  32 + * http://forums.codeguru.com/showthread.php?313123-Elementary-problems-using-winldap
  33 + * https://stackoverflow.com/questions/21501002/how-to-use-ldap-sasl-bind-in-winldap
  34 + *
  35 + */
  36 +
  37 +#include <config.h>
  38 +
  39 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
  40 +
  41 +#include "private.h"
  42 +#include <winldap.h>
  43 +#include <utilc.h>
  44 +#include <lib3270/toggle.h>
  45 +#include <lib3270/trace.h>
  46 +
  47 +# ifndef LDAP_VENDOR_NAME
  48 +# error Your Platform SDK is NOT sufficient for LDAP support! \
  49 + Update your Platform SDK, or disable LDAP support!
  50 +# else
  51 +# include <winber.h>
  52 +# endif
  53 +
  54 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  55 +
  56 +static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ptr)
  57 +{
  58 + debug("%s(%p)",__FUNCTION__,*ptr);
  59 + if(*ptr)
  60 + {
  61 + ldap_unbind(*ptr);
  62 + *ptr = NULL;
  63 + }
  64 +
  65 +}
  66 +
  67 +static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
  68 +{
  69 + debug("%s(%p)",__FUNCTION__,*message);
  70 + if(message)
  71 + ldap_msgfree(*message);
  72 + *message = NULL;
  73 +}
  74 +
  75 +static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
  76 +{
  77 + debug("%s(%p)",__FUNCTION__,*ptr);
  78 + if(*ptr)
  79 + ldap_memfree(*ptr);
  80 + *ptr = NULL;
  81 +}
  82 +
  83 +static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
  84 +{
  85 + debug("%s(%p)",__FUNCTION__,*ber);
  86 + if(*ber)
  87 + ber_free(*ber, 0);
  88 + *ber = NULL;
  89 +}
  90 +
  91 +
  92 +X509_CRL * lib3270_crl_get_using_ldap(H3270 *hSession, const char *consturl, const char **error)
  93 +{
  94 + X509_CRL * x509_crl = NULL;
  95 + int rc = 0;
  96 +
  97 + // Strip query.
  98 +
  99 + lib3270_autoptr(char) urldup = lib3270_unescape(consturl);
  100 +
  101 + char * url = urldup+7;
  102 + char * base = strchr(url,'/');
  103 + char * port;
  104 + char * attrs[] = { NULL, NULL };
  105 +
  106 + if(!base)
  107 + {
  108 + *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  109 + errno = EINVAL;
  110 + return NULL;
  111 + }
  112 +
  113 + *(base++) = 0;
  114 + attrs[0] = strchr(base,'?');
  115 +
  116 + if(!base)
  117 + {
  118 + *error = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  119 + errno = EINVAL;
  120 + return NULL;
  121 + }
  122 +
  123 + *(attrs[0]++) = 0;
  124 +
  125 + port = strchr(url,':');
  126 + if(port)
  127 + {
  128 + *(port++) = 0;
  129 + }
  130 +
  131 + debug("host: \"%s\"",url);
  132 + debug("port: %d", atoi(port));
  133 + debug("Base: \"%s\"",base);
  134 + debug("Attr: \"%s\"",attrs[0]);
  135 +
  136 + // ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
  137 +
  138 + // Do LDAP Query
  139 + lib3270_autoptr(LDAP) ld = ldap_init(url, (port && *port ? atoi(port) : LDAP_PORT));
  140 +
  141 + if(!ld)
  142 + {
  143 + *error = _( "Can't initialize LDAP" );
  144 + errno = -1;
  145 + return NULL;
  146 + }
  147 +
  148 + static const int version = LDAP_VERSION3;
  149 + rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
  150 + if(rc != LDAP_SUCCESS)
  151 + {
  152 + *error = _( "Can't set LDAP protocol version" );
  153 + SetLastError(LdapMapErrorToWin32(rc));
  154 + errno = EINVAL;
  155 + return NULL;
  156 + }
  157 +
  158 + rc = ldap_simple_bind_s(ld, NULL, NULL);
  159 + if(rc != LDAP_SUCCESS)
  160 + {
  161 + *error =_( "Can't bind to LDAP server" );
  162 + SetLastError(LdapMapErrorToWin32(rc));
  163 + errno = EINVAL;
  164 + return NULL;
  165 + }
  166 +
  167 + lib3270_autoptr(LDAPMessage) results = NULL;
  168 + rc = ldap_search_ext_s(
  169 + ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
  170 + base, // Specifies the DN of the entry at which to start the search.
  171 + LDAP_SCOPE_BASE, // Specifies the scope of the search.
  172 + NULL, // Specifies a string representation of the filter to apply in the search.
  173 + (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
  174 + 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
  175 + NULL,
  176 + NULL,
  177 + NULL,
  178 + 0,
  179 + &results
  180 + );
  181 +
  182 +
  183 + if(rc != LDAP_SUCCESS)
  184 + {
  185 + *error = ldap_err2string(rc);
  186 + return NULL;
  187 + }
  188 +
  189 + lib3270_autoptr(BerElement) ber = NULL;
  190 + char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
  191 + if(!attr)
  192 + {
  193 + *error = _("LDAP Search did not produce any attributes.");
  194 + errno = ENOENT;
  195 + return NULL;
  196 + }
  197 +
  198 + struct berval ** value = ldap_get_values_len(ld, results, attr);
  199 + if(!value)
  200 + {
  201 + *error = _("LDAPSearch did not produce any values.");
  202 + errno = ENOENT;
  203 + return NULL;
  204 + }
  205 +
  206 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  207 + {
  208 + lib3270_trace_data(
  209 + hSession,
  210 + "CRL Data received from LDAP server",
  211 + (const unsigned char *) value[0]->bv_val,
  212 + value[0]->bv_len
  213 + );
  214 + }
  215 +
  216 + // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
  217 + const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
  218 +
  219 + if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
  220 + {
  221 + *error =_( "Can't decode certificate revocation list" );
  222 + ldap_value_free_len(value);
  223 + return NULL;
  224 + }
  225 +
  226 + ldap_value_free_len(value);
  227 +
  228 + return x509_crl;
  229 +
  230 +}
  231 +
  232 +#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
... ...
src/ssl/windows/ldap.c
... ... @@ -1,294 +0,0 @@
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   - * References:
29   - *
30   - * https://docs.microsoft.com/en-us/windows/win32/api/winldap/
31   - * https://github.com/curl/curl/blob/curl-7_62_0/lib/ldap.c
32   - * http://forums.codeguru.com/showthread.php?313123-Elementary-problems-using-winldap
33   - * https://stackoverflow.com/questions/21501002/how-to-use-ldap-sasl-bind-in-winldap
34   - *
35   - */
36   -
37   -#include <config.h>
38   -
39   -#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
40   -
41   -#include "private.h"
42   -#include <winldap.h>
43   -#include <utilc.h>
44   -#include <lib3270/toggle.h>
45   -
46   -# ifndef LDAP_VENDOR_NAME
47   -# error Your Platform SDK is NOT sufficient for LDAP support! \
48   - Update your Platform SDK, or disable LDAP support!
49   -# else
50   -# include <winber.h>
51   -# endif
52   -
53   -/*--[ Implement ]------------------------------------------------------------------------------------*/
54   -
55   -static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ptr)
56   -{
57   - debug("%s(%p)",__FUNCTION__,*ptr);
58   - if(*ptr)
59   - {
60   - ldap_unbind(*ptr);
61   - *ptr = NULL;
62   - }
63   -
64   -}
65   -
66   -static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
67   -{
68   - debug("%s(%p)",__FUNCTION__,*message);
69   - if(message)
70   - ldap_msgfree(*message);
71   - *message = NULL;
72   -}
73   -
74   -static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
75   -{
76   - debug("%s(%p)",__FUNCTION__,*ptr);
77   - if(*ptr)
78   - ldap_memfree(*ptr);
79   - *ptr = NULL;
80   -}
81   -
82   -static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
83   -{
84   - debug("%s(%p)",__FUNCTION__,*ber);
85   - if(*ber)
86   - ber_free(*ber, 0);
87   - *ber = NULL;
88   -}
89   -
90   -
91   -X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
92   -{
93   - X509_CRL * x509_crl = NULL;
94   - int rc = 0;
95   -
96   - // Strip query.
97   -
98   - lib3270_autoptr(char) urldup = lib3270_unescape(consturl);
99   -
100   - char * url = urldup+7;
101   - char * base = strchr(url,'/');
102   - char * port;
103   - char * attrs[] = { NULL, NULL };
104   -
105   - if(!base)
106   - {
107   - static const LIB3270_POPUP popup = {
108   - .summary = N_( "No DN of the entry at which to start the search on the URL" ),
109   - .body = N_( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" )
110   - };
111   -
112   - message->code = hSession->ssl.error = 0;
113   - message->popup = &popup;
114   - debug("%s",message->popup->summary);
115   - errno = EINVAL;
116   - return NULL;
117   - }
118   -
119   - *(base++) = 0;
120   - attrs[0] = strchr(base,'?');
121   -
122   - if(!base)
123   - {
124   - static const LIB3270_POPUP popup = {
125   - .summary = N_( "No LDAP attribute on the URL" ),
126   - .body = N_( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" )
127   - };
128   -
129   - message->code = hSession->ssl.error = 0;
130   - message->popup = &popup;
131   - debug("%s",message->popup->summary);
132   - errno = EINVAL;
133   - return NULL;
134   - }
135   -
136   - *(attrs[0]++) = 0;
137   -
138   - port = strchr(url,':');
139   - if(port)
140   - {
141   - *(port++) = 0;
142   - }
143   -
144   - debug("host: \"%s\"",url);
145   - debug("port: %d", atoi(port));
146   - debug("Base: \"%s\"",base);
147   - debug("Attr: \"%s\"",attrs[0]);
148   -
149   - // ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
150   -
151   - // Do LDAP Query
152   - lib3270_autoptr(LDAP) ld = ldap_init(url, (port && *port ? atoi(port) : LDAP_PORT));
153   -
154   - if(!ld)
155   - {
156   - static const LIB3270_POPUP popup = {
157   - .summary = N_( "Can't initialize LDAP" )
158   - };
159   -
160   - message->code = hSession->ssl.error = 0;
161   - message->popup = &popup;
162   -
163   - debug("%s",message->popup->summary);
164   - message->lasterror = GetLastError();
165   - errno = EINVAL;
166   - return NULL;
167   - }
168   -
169   - static const int version = LDAP_VERSION3;
170   - rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
171   - if(rc != LDAP_SUCCESS)
172   - {
173   - static const LIB3270_POPUP popup = {
174   - .summary = N_( "Can't set LDAP protocol version" )
175   - };
176   -
177   - message->code = hSession->ssl.error = 0;
178   - message->popup = &popup;
179   - message->lasterror = LdapMapErrorToWin32(rc);
180   -
181   - debug("%s (rc=%u, lasterror=%d)",ldap_err2string(rc),rc,(unsigned int) message->lasterror);
182   -
183   - errno = EINVAL;
184   - return NULL;
185   - }
186   -
187   - rc = ldap_simple_bind_s(ld, NULL, NULL);
188   - if(rc != LDAP_SUCCESS)
189   - {
190   - static const LIB3270_POPUP popup = {
191   - .summary = N_( "Can't bind to LDAP server" )
192   - };
193   -
194   - message->code = hSession->ssl.error = 0;
195   - message->popup = &popup;
196   - message->lasterror = LdapMapErrorToWin32(rc);
197   -
198   - debug("%s (rc=%u, lasterror=%d)",ldap_err2string(rc),rc,(unsigned int) message->lasterror);
199   -
200   - errno = EINVAL;
201   - return NULL;
202   - }
203   -
204   - lib3270_autoptr(LDAPMessage) results = NULL;
205   - rc = ldap_search_ext_s(
206   - ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
207   - base, // Specifies the DN of the entry at which to start the search.
208   - LDAP_SCOPE_BASE, // Specifies the scope of the search.
209   - NULL, // Specifies a string representation of the filter to apply in the search.
210   - (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
211   - 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
212   - NULL,
213   - NULL,
214   - NULL,
215   - 0,
216   - &results
217   - );
218   -
219   -
220   - if(rc != LDAP_SUCCESS)
221   - {
222   - static const LIB3270_POPUP popup = {
223   - .summary = N_( "Can't search LDAP server" )
224   - };
225   - message->body = ldap_err2string(rc);
226   - message->popup = &popup;
227   - lib3270_write_log(hSession,"ssl","%s: %s",url, message->body);
228   - return NULL;
229   - }
230   -
231   - lib3270_autoptr(BerElement) ber = NULL;
232   - char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
233   - if(!attr)
234   - {
235   - static const LIB3270_POPUP popup = {
236   - .summary = N_( "Can't get LDAP attribute" ),
237   - .body = N_("Search did not produce any attributes.")
238   - };
239   -
240   - message->code = hSession->ssl.error = 0;
241   - message->popup = &popup;
242   - lib3270_write_log(hSession,"ssl","%s: %s",url, message->popup->body);
243   - errno = ENOENT;
244   - return NULL;
245   - }
246   -
247   - struct berval ** value = ldap_get_values_len(ld, results, attr);
248   - if(!value)
249   - {
250   - static const LIB3270_POPUP popup = {
251   - .summary = N_( "Can't get LDAP attribute" ),
252   - .body = N_("Search did not produce any values.")
253   - };
254   - message->code = hSession->ssl.error = 0;
255   - message->popup = &popup;
256   - lib3270_write_log(hSession,"ssl","%s: %s",url, message->popup->body);
257   - errno = ENOENT;
258   - return NULL;
259   - }
260   -
261   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
262   - {
263   - lib3270_trace_data(
264   - hSession,
265   - "CRL Data received from LDAP server",
266   - (const unsigned char *) value[0]->bv_val,
267   - value[0]->bv_len
268   - );
269   - }
270   -
271   - // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
272   - const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
273   -
274   - if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
275   - {
276   - static const LIB3270_POPUP popup = {
277   - .summary = N_( "Can't decode certificate revocation list" )
278   - };
279   -
280   - message->code = hSession->ssl.error = ERR_get_error();
281   - message->popup = &popup;
282   -
283   - lib3270_write_log(hSession,"ssl","%s: %s",url, message->popup->summary);
284   - ldap_value_free_len(value);
285   - return NULL;
286   - }
287   -
288   - ldap_value_free_len(value);
289   -
290   - return x509_crl;
291   -
292   -}
293   -
294   -#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)