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; | ... | ... |