Commit 88311f50312f97115cd85e31abc9adb68098a704
1 parent
1c05e713
Exists in
master
and in
3 other branches
Adding "quick and dirty" workaround for possible bug in libcurl for windows.
Showing
5 changed files
with
140 additions
and
77 deletions
Show diff stats
.gitignore
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; | ... | ... |