Commit 88311f50312f97115cd85e31abc9adb68098a704

Authored by Perry Werneck
1 parent 1c05e713

Adding "quick and dirty" workaround for possible bug in libcurl for windows.

.gitignore
... ... @@ -24,7 +24,8 @@ versions
24 24 ChangeLog*
25 25 Makefile
26 26 aclocal.m4
27   -configure
  27 +configure*
  28 +*.trace
28 29 autom4te.cache
29 30 makegtkruntime.sh
30 31 copydeps.sh
... ...
src/lib3270/ssl/linux/getcrl.c
... ... @@ -252,71 +252,40 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
252 252  
253 253 }
254 254 #ifdef HAVE_LDAP
255   - else if(strncasecmp(consturl,"ldap",4) == 0)
  255 + else if(strncasecmp(consturl,"ldap://",7) == 0 && strlen(consturl) > 8)
256 256 {
257 257 int rc;
258 258 lib3270_autoptr(char) url = strdup(consturl);
259   -
  259 + char * base = strchr(url+7,'/');
260 260 char * attrs[] = { NULL, NULL };
261   - char * base = NULL;
262 261  
263   - const struct _args
  262 + if(!base)
264 263 {
265   - const char * name;
266   - char ** value;
  264 + message->error = hSession->ssl.error = 0;
  265 + message->title = N_( "Security error" );
  266 + message->text = N_( "No DN of the entry at which to start the search on the URL" );
  267 + message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  268 + return NULL;
267 269 }
268   - args[] =
269   - {
270   - { "attr", &attrs[0] },
271   - { "base", &base }
272   - };
273   -
274   - // Get arguments
275   - size_t arg;
276   - char * ptr = strchr(url,'?');
277   - while(ptr)
278   - {
279   - *(ptr++) = 0;
280   - char *value = strchr(ptr,'=');
281   - if(!value)
282   - {
283   - message->error = hSession->ssl.error = 0;
284   - message->title = N_( "Security error" );
285   - message->text = N_( "Invalid argument format" );
286   - message->description = "The URL argument should be in the format name=value";
287   - return NULL;
288   - }
289   -
290   - *(value++) = 0;
291   -
292   - debug("%s=%s",ptr,value);
293 270  
294   - for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++)
295   - {
296   - if(!strcasecmp(ptr,args[arg].name))
297   - {
298   - *args[arg].value = value;
299   - debug("%s=\"%s\"",args[arg].name,*args[arg].value);
300   - }
301   - }
302   -
303   - ptr = strchr(value,'&');
304   - }
  271 + *(base++) = 0;
  272 + attrs[0] = strchr(base,'?');
305 273  
306   - // Do we get all the required arguments?
307   - for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++)
  274 + if(!base)
308 275 {
309   - if(!*args[arg].value)
310   - {
311   - message->error = hSession->ssl.error = 0;
312   - message->title = N_( "Security error" );
313   - message->text = N_( "Can't set LDAP query" );
314   - message->description = N_("Insuficient arguments");
315   - lib3270_write_log(hSession,"ssl","%s: Required argument \"%s\" is missing",url, args[arg].name);
316   - return NULL;
317   - }
  276 + message->error = hSession->ssl.error = 0;
  277 + message->title = N_( "Security error" );
  278 + message->text = N_( "No LDAP attribute on the URL" );
  279 + message->description = _( "The URL argument should be in the format ldap://[HOST]/[DN]?attribute" );
  280 + return NULL;
318 281 }
319 282  
  283 + *(attrs[0]++) = 0;
  284 +
  285 + debug("host: \"%s\"",url);
  286 + debug("Base: \"%s\"",base);
  287 + debug("Attr: \"%s\"",attrs[0]);
  288 +
320 289 // Do LDAP Query
321 290 LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL;
322 291 BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL;
... ... @@ -401,6 +370,16 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
401 370 return NULL;
402 371 }
403 372  
  373 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  374 + {
  375 + lib3270_trace_data(
  376 + hSession,
  377 + "CRL Data received from LDAP server",
  378 + (const char *) value[0]->bv_val,
  379 + value[0]->bv_len
  380 + );
  381 + }
  382 +
404 383 // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
405 384 const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
406 385  
... ... @@ -485,7 +464,18 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
485 464 return NULL;
486 465 }
487 466  
488   - debug("content-type: %s",ct);
  467 + /*
  468 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  469 + {
  470 + lib3270_autoptr(char) msg = lib3270_strdup_printf("CRL Data received with content-type \"%s\"", (ct ? ct : "undefined"));
  471 + lib3270_trace_data(
  472 + hSession,
  473 + msg,
  474 + (const char *) crl_data->contents,
  475 + crl_data->length
  476 + );
  477 + }
  478 + */
489 479  
490 480 if(ct)
491 481 {
... ... @@ -526,8 +516,6 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
526 516 }
527 517 data += 3;
528 518  
529   - debug("\n%s\nlength=%u",data,(unsigned int) strlen(data));
530   -
531 519 lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1);
532 520  
533 521 BIO * b64 = BIO_new(BIO_f_base64());
... ...
src/lib3270/ssl/windows/getcrl.c
... ... @@ -292,6 +292,19 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
292 292 return NULL;
293 293 }
294 294  
  295 + /*
  296 + if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
  297 + {
  298 + lib3270_autoptr(msg) = lib3270_vsprintf("CRL Data received with content-type \"%s\"", (ct ? ct : "undefined"));
  299 + lib3270_trace_data(
  300 + data->hSession,
  301 + msg,
  302 + (const char *) crl_data->contents,
  303 + crl_data->length
  304 + );
  305 + }
  306 + */
  307 +
295 308 if(ct)
296 309 {
297 310 const unsigned char * data = crl_data->contents;
... ... @@ -321,35 +334,76 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
321 334 }
322 335 else if(strncasecmp(consturl,"ldap://",7) == 0)
323 336 {
324   - // It's an LDAP query, assumes a base64 data.
325   - trace_ssl(crl_data->hSession, "No mime-type, assuming LDAP/BASE64");
  337 + // LDAP Query on curl for windows returns an unprocessed response instead of a base64 data.
  338 + char * attr = strchr(consturl,'?');
  339 + if(!attr)
  340 + {
  341 + message->error = hSession->ssl.error = 0;
  342 + message->title = N_( "Security error" );
  343 + message->text = N_( "No attribute in LDAP search URL" );
  344 + return NULL;
  345 + }
  346 +
  347 + attr++;
  348 +
  349 + //
  350 + // There's something odd on libcurl for windows! For some reason it's not converting the LDAP response values to
  351 + // base64, because of this I've to extract the BER directly.
  352 + //
  353 + // This is an ugly solution, I know!
  354 + //
  355 +
  356 + lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr);
  357 + trace_ssl(crl_data->hSession, text);
  358 +
  359 + lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr);
  360 + char *ptr = strstr((char *) crl_data->contents, key);
  361 +
  362 + debug("key=\"%s\" ptr=%p",key,ptr)
326 363  
327   - char * data = strstr((char *) crl_data->contents,":: ");
328   - if(!data)
  364 + if(!ptr)
329 365 {
330   - message->error = hSession->ssl.error = ERR_get_error();
  366 + message->error = hSession->ssl.error = 0;
331 367 message->title = N_( "Security error" );
332   - message->text = N_( "Got an invalid CRL from LDAP server" );
  368 + message->text = N_( "Can't find attribute in LDAP response" );
333 369 return NULL;
334 370 }
335   - data += 3;
336 371  
337   - debug("\n%s\nlength=%u",data,(unsigned int) strlen(data));
  372 + ptr += strlen(key);
  373 + size_t length = crl_data->length - (ptr - ((char *) crl_data->contents));
  374 + size_t ix;
338 375  
339   - lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1);
  376 + for(ix = 0; ix < (length-1); ix++)
  377 + {
  378 + if(ptr[ix] == '\n' && ptr[ix+1] == '\n')
  379 + break;
  380 + }
340 381  
341   - BIO * b64 = BIO_new(BIO_f_base64());
342   - bio = BIO_push(b64, bio);
  382 + debug("length=%u ix=%u", (unsigned int) length, (unsigned int) ix);
343 383  
344   - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
  384 + if(ix >= length)
  385 + {
  386 + message->error = hSession->ssl.error = 0;
  387 + message->title = N_( "Security error" );
  388 + message->text = N_( "Can't find attribute end in LDAP response" );
  389 + return NULL;
  390 + }
  391 +
  392 + length = ix;
  393 +
  394 + lib3270_trace_data(
  395 + hSession,
  396 + "CRL Data received from LDAP server",
  397 + (const char *) ptr,
  398 + length
  399 + );
345 400  
346   - if(!d2i_X509_CRL_bio(bio, &crl))
  401 + if(!d2i_X509_CRL(&crl, (const unsigned char **) &ptr, length))
347 402 {
348 403 message->error = hSession->ssl.error = ERR_get_error();
349 404 message->title = N_( "Security error" );
350   - message->text = N_( "Got an invalid CRL from server" );
  405 + message->text = N_( "Can't get CRL from LDAP Search" );
351 406 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
352   - return NULL;
353 407 }
354 408  
355 409 }
... ...
src/lib3270/testprogram/testprogram.c
... ... @@ -6,9 +6,22 @@
6 6  
7 7 #include <lib3270.h>
8 8 #include <lib3270/actions.h>
  9 +#include <lib3270/trace.h>
9 10  
10 11 #define MAX_ARGS 10
11 12  
  13 +const char *trace_file = "test.trace";
  14 +
  15 +static void write_trace(H3270 *session, void *userdata, const char *fmt, va_list args)
  16 +{
  17 + FILE *out = fopen(trace_file,"a");
  18 + if(out)
  19 + {
  20 + vfprintf(out,fmt,args);
  21 + fclose(out);
  22 + }
  23 +}
  24 +
12 25 int main(int argc, char *argv[])
13 26 {
14 27 // #pragma GCC diagnostic push
... ... @@ -16,6 +29,7 @@ int main(int argc, char *argv[])
16 29 static struct option options[] = {
17 30 { "crl", required_argument, 0, 'C' },
18 31 { "url", required_argument, 0, 'U' },
  32 + { "tracefile", required_argument, 0, 't' },
19 33  
20 34 { 0, 0, 0, 0}
21 35  
... ... @@ -32,7 +46,7 @@ int main(int argc, char *argv[])
32 46  
33 47 int long_index =0;
34 48 int opt;
35   - while((opt = getopt_long(argc, argv, "C:U:", options, &long_index )) != -1) {
  49 + while((opt = getopt_long(argc, argv, "C:U:t:", options, &long_index )) != -1) {
36 50 switch(opt) {
37 51 case 'U':
38 52 lib3270_set_url(h,optarg);
... ... @@ -41,6 +55,11 @@ int main(int argc, char *argv[])
41 55 case 'C':
42 56 lib3270_set_crl_url(h,optarg);
43 57 break;
  58 +
  59 + case 't':
  60 + trace_file = optarg;
  61 + lib3270_set_trace_handler(h,write_trace,NULL);
  62 + break;
44 63 }
45 64  
46 65 }
... ...
src/lib3270/trace_ds.c
... ... @@ -31,9 +31,8 @@
31 31 */
32 32  
33 33  
34   -/*
35   - * trace_ds.c
36   - * 3270 data stream tracing.
  34 +/**
  35 + * @brief 3270 data stream tracing.
37 36 *
38 37 */
39 38  
... ... @@ -193,7 +192,9 @@ void trace_ssl(H3270 *session, const char *fmt, ...)
193 192 }
194 193  
195 194  
196   -/* Write to the trace file. */
  195 +/**
  196 + * @brief Write to the trace file.
  197 + */
197 198 static void wtrace(H3270 *session, const char *fmt, ...)
198 199 {
199 200 va_list args;
... ...