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,71 +252,40 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 252 | 252 | ||
| 253 | } | 253 | } |
| 254 | #ifdef HAVE_LDAP | 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 | int rc; | 257 | int rc; |
| 258 | lib3270_autoptr(char) url = strdup(consturl); | 258 | lib3270_autoptr(char) url = strdup(consturl); |
| 259 | - | 259 | + char * base = strchr(url+7,'/'); |
| 260 | char * attrs[] = { NULL, NULL }; | 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 | // Do LDAP Query | 289 | // Do LDAP Query |
| 321 | LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL; | 290 | LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL; |
| 322 | BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL; | 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,6 +370,16 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 401 | return NULL; | 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 | // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro. | 383 | // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro. |
| 405 | const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val; | 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,7 +464,18 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 485 | return NULL; | 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 | if(ct) | 480 | if(ct) |
| 491 | { | 481 | { |
| @@ -526,8 +516,6 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | @@ -526,8 +516,6 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 526 | } | 516 | } |
| 527 | data += 3; | 517 | data += 3; |
| 528 | 518 | ||
| 529 | - debug("\n%s\nlength=%u",data,(unsigned int) strlen(data)); | ||
| 530 | - | ||
| 531 | lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1); | 519 | lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1); |
| 532 | 520 | ||
| 533 | BIO * b64 = BIO_new(BIO_f_base64()); | 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,6 +292,19 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 292 | return NULL; | 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 | if(ct) | 308 | if(ct) |
| 296 | { | 309 | { |
| 297 | const unsigned char * data = crl_data->contents; | 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,35 +334,76 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) | ||
| 321 | } | 334 | } |
| 322 | else if(strncasecmp(consturl,"ldap://",7) == 0) | 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 | message->title = N_( "Security error" ); | 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 | return NULL; | 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 | message->error = hSession->ssl.error = ERR_get_error(); | 403 | message->error = hSession->ssl.error = ERR_get_error(); |
| 349 | message->title = N_( "Security error" ); | 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 | lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); | 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,9 +6,22 @@ | ||
| 6 | 6 | ||
| 7 | #include <lib3270.h> | 7 | #include <lib3270.h> |
| 8 | #include <lib3270/actions.h> | 8 | #include <lib3270/actions.h> |
| 9 | +#include <lib3270/trace.h> | ||
| 9 | 10 | ||
| 10 | #define MAX_ARGS 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 | int main(int argc, char *argv[]) | 25 | int main(int argc, char *argv[]) |
| 13 | { | 26 | { |
| 14 | // #pragma GCC diagnostic push | 27 | // #pragma GCC diagnostic push |
| @@ -16,6 +29,7 @@ int main(int argc, char *argv[]) | @@ -16,6 +29,7 @@ int main(int argc, char *argv[]) | ||
| 16 | static struct option options[] = { | 29 | static struct option options[] = { |
| 17 | { "crl", required_argument, 0, 'C' }, | 30 | { "crl", required_argument, 0, 'C' }, |
| 18 | { "url", required_argument, 0, 'U' }, | 31 | { "url", required_argument, 0, 'U' }, |
| 32 | + { "tracefile", required_argument, 0, 't' }, | ||
| 19 | 33 | ||
| 20 | { 0, 0, 0, 0} | 34 | { 0, 0, 0, 0} |
| 21 | 35 | ||
| @@ -32,7 +46,7 @@ int main(int argc, char *argv[]) | @@ -32,7 +46,7 @@ int main(int argc, char *argv[]) | ||
| 32 | 46 | ||
| 33 | int long_index =0; | 47 | int long_index =0; |
| 34 | int opt; | 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 | switch(opt) { | 50 | switch(opt) { |
| 37 | case 'U': | 51 | case 'U': |
| 38 | lib3270_set_url(h,optarg); | 52 | lib3270_set_url(h,optarg); |
| @@ -41,6 +55,11 @@ int main(int argc, char *argv[]) | @@ -41,6 +55,11 @@ int main(int argc, char *argv[]) | ||
| 41 | case 'C': | 55 | case 'C': |
| 42 | lib3270_set_crl_url(h,optarg); | 56 | lib3270_set_crl_url(h,optarg); |
| 43 | break; | 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,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,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 | static void wtrace(H3270 *session, const char *fmt, ...) | 198 | static void wtrace(H3270 *session, const char *fmt, ...) |
| 198 | { | 199 | { |
| 199 | va_list args; | 200 | va_list args; |