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