Commit ff4333306a320544a765e3910584dd8ea4fde0dd

Authored by Perry Werneck
1 parent b455df4f

Implementing WinLDAP support.

configure.ac
... ... @@ -79,7 +79,7 @@ case "$host" in
79 79 *-mingw32|*-pc-msys)
80 80 app_cv_osname="windows"
81 81 CFLAGS="$CFLAGS -pthread -D_WIN32_WINNT=0x0600"
82   - LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32 -lwldap32"
  82 + LIBS="$LIBS -lws2_32 -lwtsapi32 -lcomdlg32"
83 83 LDFLAGS="$LDFLAGS -pthread"
84 84 DLL_LDFLAGS="-shared -Wl,--output-def,\$(@D)/\$(LIBNAME).def"
85 85 DLLEXT=".dll"
... ... @@ -521,24 +521,36 @@ AC_ARG_ENABLE([ldap],
521 521  
522 522  
523 523 if test "x${have_ldap}" != xno ; then
524   - AC_CHECK_HEADERS(
525   - [ldap.h],
526   - [have_ldap=yes],
527   - [if test "x$have_ldap" = xyes ; then
528   - AC_MSG_ERROR([LDAP headers not found.])
529   - fi])
530 524  
531   - if test "x$have_ldap" = xyes ; then
  525 + case "$host" in
  526 + *-mingw32|*-pc-msys)
  527 + LDAP_LIBS="-lwldap32"
  528 + AC_DEFINE(HAVE_LDAP,1,[LDAP is available])
  529 + ;;
  530 +
  531 + *)
  532 +
  533 + AC_CHECK_HEADERS(
  534 + [ldap.h],
  535 + [have_ldap=yes],
  536 + [if test "x$have_ldap" = xyes ; then
  537 + AC_MSG_ERROR([LDAP headers not found.])
  538 + fi])
  539 +
  540 + if test "x$have_ldap" = xyes ; then
532 541  
533   - LDAP_LIBS="-lldap -llber"
534   - AC_DEFINE(HAVE_LDAP,1,[LDAP is available])
535   - M4_DEFINES="$M4_DEFINES -DHAVE_LDAP"
  542 + LDAP_LIBS="-lldap -llber"
  543 + AC_DEFINE(HAVE_LDAP,1,[LDAP is available])
  544 + M4_DEFINES="$M4_DEFINES -DHAVE_LDAP"
536 545  
537   - else
  546 + else
538 547  
539   - have_ldap=no
  548 + have_ldap=no
540 549  
541   - fi
  550 + fi
  551 +
  552 +
  553 + esac
542 554  
543 555 else
544 556 LDAP_LIBS=
... ...
src/ssl/windows/getcrl.c
... ... @@ -98,13 +98,13 @@ LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE *
98 98  
99 99  
100 100 }
101   -#ifdef DEBUG
  101 +#ifdef HAVE_LDAP
102 102 else if(strncasecmp(consturl,"ldap://",7) == 0 && strlen(consturl) > 8)
103 103 {
104   - return get_crl_using_winldap(hSession, message, consturl);
  104 + return get_crl_using_ldap(hSession, message, consturl);
105 105  
106 106 }
107   -#endif // DEBUG
  107 +#endif // HAVE_LDAP
108 108 else
109 109 {
110 110 #ifdef HAVE_LIBCURL
... ...
src/ssl/windows/ldap.c
... ... @@ -27,6 +27,7 @@
27 27 *
28 28 * References:
29 29 *
  30 + * https://docs.microsoft.com/en-us/windows/win32/api/winldap/
30 31 * https://github.com/curl/curl/blob/curl-7_62_0/lib/ldap.c
31 32 * http://forums.codeguru.com/showthread.php?313123-Elementary-problems-using-winldap
32 33 * https://stackoverflow.com/questions/21501002/how-to-use-ldap-sasl-bind-in-winldap
... ... @@ -35,7 +36,7 @@
35 36  
36 37 #include <config.h>
37 38  
38   -#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
  39 +#if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
39 40  
40 41 #include "private.h"
41 42 #include <winldap.h>
... ... @@ -59,7 +60,32 @@ static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ptr)
59 60  
60 61 }
61 62  
62   -X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
  63 +static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message)
  64 +{
  65 + debug("%s(%p)",__FUNCTION__,*message);
  66 + if(message)
  67 + ldap_msgfree(*message);
  68 + *message = NULL;
  69 +}
  70 +
  71 +static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr)
  72 +{
  73 + debug("%s(%p)",__FUNCTION__,*ptr);
  74 + if(*ptr)
  75 + ldap_memfree(*ptr);
  76 + *ptr = NULL;
  77 +}
  78 +
  79 +static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber)
  80 +{
  81 + debug("%s(%p)",__FUNCTION__,*ber);
  82 + if(*ber)
  83 + ber_free(*ber, 0);
  84 + *ber = NULL;
  85 +}
  86 +
  87 +
  88 +X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
63 89 {
64 90 debug("********************************************************* %s",__FUNCTION__);
65 91  
... ... @@ -146,7 +172,7 @@ X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, c
146 172 return NULL;
147 173 }
148 174  
149   - rc = ldap_simple_bind(ld, "", "");
  175 + rc = ldap_simple_bind_s(ld, NULL, NULL);
150 176 if(rc != LDAP_SUCCESS)
151 177 {
152 178 message->error = hSession->ssl.error = 0;
... ... @@ -161,6 +187,81 @@ X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, c
161 187 return NULL;
162 188 }
163 189  
  190 + lib3270_autoptr(LDAPMessage) results = NULL;
  191 + rc = ldap_search_ext_s(
  192 + ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open().
  193 + base, // Specifies the DN of the entry at which to start the search.
  194 + LDAP_SCOPE_BASE, // Specifies the scope of the search.
  195 + NULL, // Specifies a string representation of the filter to apply in the search.
  196 + (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter.
  197 + 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values.
  198 + NULL,
  199 + NULL,
  200 + NULL,
  201 + 0,
  202 + &results
  203 + );
  204 +
  205 +
  206 + if(rc != LDAP_SUCCESS)
  207 + {
  208 + message->error = hSession->ssl.error = 0;
  209 + message->title = _( "Security error" );
  210 + message->text = _( "Can't search LDAP server" );
  211 + message->description = ldap_err2string(rc);
  212 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  213 + return NULL;
  214 + }
  215 +
  216 + lib3270_autoptr(BerElement) ber = NULL;
  217 + char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
  218 + if(!attr)
  219 + {
  220 + message->error = hSession->ssl.error = 0;
  221 + message->title = _( "Security error" );
  222 + message->text = _( "Can't get LDAP attribute" );
  223 + message->description = _("Search did not produce any attributes.");
  224 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  225 + errno = ENOENT;
  226 + return NULL;
  227 + }
  228 +
  229 + struct berval ** value = ldap_get_values_len(ld, results, attr);
  230 + if(!value)
  231 + {
  232 + message->error = hSession->ssl.error = 0;
  233 + message->title = _( "Security error" );
  234 + message->text = _( "Can't get LDAP attribute" );
  235 + message->description = _("Search did not produce any values.");
  236 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
  237 + errno = ENOENT;
  238 + return NULL;
  239 + }
  240 +
  241 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  242 + {
  243 + lib3270_trace_data(
  244 + hSession,
  245 + "CRL Data received from LDAP server",
  246 + (const char *) value[0]->bv_val,
  247 + value[0]->bv_len
  248 + );
  249 + }
  250 +
  251 + // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
  252 + const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
  253 +
  254 + if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
  255 + {
  256 + message->error = hSession->ssl.error = ERR_get_error();
  257 + message->title = _( "Security error" );
  258 + message->text = _( "Can't decode certificate revocation list" );
  259 + lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
  260 + ldap_value_free_len(value);
  261 + return NULL;
  262 + }
  263 +
  264 + ldap_value_free_len(value);
164 265  
165 266 debug("********************************************************* %s",__FUNCTION__);
166 267  
... ... @@ -168,4 +269,4 @@ X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, c
168 269  
169 270 }
170 271  
171   -#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
  272 +#endif // defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LDAP)
... ...
src/ssl/windows/private.h
... ... @@ -57,7 +57,11 @@
57 57  
58 58 #endif // HAVE_LIBCURL
59 59  
60   - LIB3270_INTERNAL X509_CRL * get_crl_using_winldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
  60 + #ifdef HAVE_LDAP
61 61  
  62 + /// @brief Use winldap to get CRL.
  63 + LIB3270_INTERNAL X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl);
  64 +
  65 + #endif // HAVE_LDAP
62 66  
63 67 #endif // !LIB3270_WIN32_SSL_PRIVATE_H_INCLUDED
... ...