Commit 151e49166f78e60b564f076e61d54fd74a827715

Authored by Perry Werneck
1 parent 7f7077f5

Fixing problem with CRL download from LDAP with libcurl for windows.

lib3270.cbp
... ... @@ -104,22 +104,10 @@
104 104 <Unit filename="src/include/winversc.h" />
105 105 <Unit filename="src/include/xioc.h" />
106 106 <Unit filename="src/include/xl.h" />
107   - <Unit filename="src/lib3270++/abstract.cc" />
108   - <Unit filename="src/lib3270++/events.cc" />
109   - <Unit filename="src/lib3270++/host.cc" />
110   - <Unit filename="src/lib3270++/ipc/session.cc" />
111   - <Unit filename="src/lib3270++/linux/request.cc" />
112   - <Unit filename="src/lib3270++/linux/session.cc" />
113   - <Unit filename="src/lib3270++/local/events.cc" />
114   - <Unit filename="src/lib3270++/local/session.cc" />
115 107 <Unit filename="src/lib3270++/private.h" />
116   - <Unit filename="src/lib3270++/session.cc" />
117   - <Unit filename="src/lib3270++/testprogram/testprogram.cc" />
118   - <Unit filename="src/lib3270++/windows/request.cc" />
119 108 <Unit filename="src/lib3270++/windows/resources.rc">
120 109 <Option compilerVar="WINDRES" />
121 110 </Unit>
122   - <Unit filename="src/lib3270++/windows/session.cc" />
123 111 <Unit filename="src/lib3270/actions.c">
124 112 <Option compilerVar="CC" />
125 113 </Unit>
... ...
src/lib3270/connect.c
... ... @@ -98,16 +98,38 @@ static int background_ssl_crl_check(H3270 *hSession, void *ssl_error)
98 98  
99 99 set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING);
100 100 int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error);
  101 +
  102 + debug("CRL check returns %d",rc);
  103 +
101 104 if(rc)
102 105 {
  106 + lib3270_write_log(
  107 + hSession,
  108 + "SSL-CRL-CHECK",
  109 + "CRL Check error: %s (rc=%d ssl_error=%d)",
  110 + ssl_error.title,
  111 + rc,
  112 + ssl_error.error
  113 + );
  114 +
103 115 if(ssl_error.description)
  116 + {
  117 + lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",ssl_error.description);
104 118 lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description);
  119 + }
105 120 else if(ssl_error.error)
106   - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ERR_reason_error_string(ssl_error.error));
  121 + {
  122 + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf("%s (SSL error %d)",ERR_reason_error_string(ssl_error.error),ssl_error.error);
  123 + lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",formatted_error);
  124 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", formatted_error);
  125 + }
107 126 else
  127 + {
108 128 lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s","");
  129 + }
  130 +
  131 + // return errno = rc;
109 132  
110   - return errno = rc;
111 133 }
112 134 #endif // SSL_ENABLE_CRL_CHECK
113 135  
... ...
src/lib3270/iocalls.c
... ... @@ -591,8 +591,6 @@ int non_blocking(H3270 *hSession, Boolean on)
591 591 lib3270_set_poll_state(hSession,hSession->xio.write, on);
592 592 lib3270_set_poll_state(hSession,hSession->xio.except, on);
593 593  
594   - trace("******** Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking");
595   -
596 594 return 0;
597 595 }
598 596  
... ...
src/lib3270/private.h
... ... @@ -772,7 +772,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
772 772 LIB3270_INTERNAL int ssl_3270_ex_index;
773 773  
774 774 #ifdef SSL_ENABLE_CRL_CHECK
775   - LIB3270_INTERNAL int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message);
  775 + LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url);
776 776 LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message);
777 777 #endif // SSL_ENABLE_CRL_CHECK
778 778  
... ...
src/lib3270/ssl/ctx_init.c
... ... @@ -105,7 +105,10 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message)
105 105 {
106 106 // Returns if don't have an SSL context.
107 107 if(!ssl_ctx)
  108 + {
  109 + trace("No SSL context %s will return %d",__FUNCTION__,0);
108 110 return 0;
  111 + }
109 112  
110 113 // Do I have X509 CRL? Is it valid?
111 114 if(hSession->ssl.crl.cert)
... ... @@ -147,8 +150,11 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message)
147 150 //
148 151 // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session
149 152 //
150   - if(lib3270_get_X509_CRL(hSession,message))
151   - return -1;
  153 + hSession->ssl.crl.cert = lib3270_get_crl(hSession,message,lib3270_get_crl_url(hSession));
  154 + if(!hSession->ssl.crl.cert)
  155 + {
  156 + return -1;
  157 + }
152 158  
153 159 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
154 160 {
... ... @@ -159,20 +165,17 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message)
159 165  
160 166 }
161 167  
  168 + // Add CRL in the store.
162 169 X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
163   -
164   - if(hSession->ssl.crl.cert)
  170 + if(X509_STORE_add_crl(store, hSession->ssl.crl.cert))
165 171 {
166   - X509_STORE_add_crl(store, hSession->ssl.crl.cert);
167 172 trace_ssl(hSession,"CRL was added to cert store\n");
  173 + return 0;
168 174 }
169 175  
170   - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
171   - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
172   - X509_STORE_set1_param(store, param);
173   - X509_VERIFY_PARAM_free(param);
  176 + trace_ssl(hSession,"CRL was not added to cert store\n");
174 177  
175   - return 0;
  178 + return -1;
176 179 }
177 180 #endif // SSL_ENABLE_CRL_CHECK
178 181  
... ... @@ -239,6 +242,15 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message)
239 242 ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL);
240 243  
241 244 #ifdef SSL_ENABLE_CRL_CHECK
  245 +
  246 + // Enable CRL check
  247 + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
  248 + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
  249 + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
  250 + X509_STORE_set1_param(store, param);
  251 + X509_VERIFY_PARAM_free(param);
  252 + trace_ssl(hSession,"CRL CHECK was enabled\n");
  253 +
242 254 return lib3270_check_X509_crl(hSession,message);
243 255 #else
244 256 return 0;
... ...
src/lib3270/ssl/linux/getcrl.c
... ... @@ -162,6 +162,7 @@ static size_t internal_curl_write_callback(void *contents, size_t size, size_t n
162 162 {
163 163 data->data.length += (CRL_DATA_LENGTH + realsize);
164 164 data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
  165 + memset(&(data->data.contents[data->length]),0,data->data.length-data->length);
165 166 }
166 167  
167 168 debug("%s",__FUNCTION__);
... ... @@ -237,9 +238,9 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype
237 238 #endif // HAVE_LIBCURL
238 239  
239 240  
240   -int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
  241 +LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
241 242 {
242   - const char * consturl = lib3270_get_crl_url(hSession);
  243 + X509_CRL * x509_crl = NULL;
243 244  
244 245 if(!(consturl && *consturl))
245 246 {
... ... @@ -247,10 +248,11 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
247 248 message->title = _( "Security error" );
248 249 message->text = _( "Can't open CRL File" );
249 250 message->description = _("The URL for the CRL is undefined or empty");
250   - return errno = ENOENT;
  251 + errno = ENOENT;
  252 + return NULL;
251 253 }
252 254  
253   - trace_ssl(hSession, "crl=%s\n",consturl);
  255 + trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl);
254 256  
255 257 if(strncasecmp(consturl,"file://",7) == 0)
256 258 {
... ... @@ -266,12 +268,21 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
266 268 message->text = _( "Can't open CRL File" );
267 269 message->description = strerror(err);
268 270 trace_ssl(hSession,"Can't open %s: %s\n",consturl,message->description);
269   - return err;
  271 + return NULL;
270 272  
271 273 }
272 274  
273 275 trace_ssl(hSession,"Loading CRL from %s\n",consturl+7);
274   - d2i_X509_CRL_fp(hCRL, &hSession->ssl.crl.cert);
  276 + if(d2i_X509_CRL_fp(hCRL, &x509_crl))
  277 + {
  278 + message->error = hSession->ssl.error = ERR_get_error();
  279 + message->title = _( "Security error" );
  280 + message->text = _( "Can't decode CRL" );
  281 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  282 + return NULL;
  283 + }
  284 +
  285 +
275 286  
276 287 }
277 288 #ifdef HAVE_LDAP
... ... @@ -332,7 +343,7 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
332 343 message->text = _( "Can't set LDAP version" );
333 344 message->description = ldap_err2string(rc);
334 345 lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
335   - return -1;
  346 + return NULL;
336 347 }
337 348  
338 349 rc = ldap_simple_bind_s(ld, "", "");
... ... @@ -368,7 +379,7 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
368 379 message->text = _( "Can't search LDAP server" );
369 380 message->description = ldap_err2string(rc);
370 381 lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
371   - return -1;
  382 + return NULL;
372 383 }
373 384  
374 385 char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber);
... ... @@ -379,7 +390,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
379 390 message->text = _( "Can't get LDAP attribute" );
380 391 message->description = _("Search did not produce any attributes.");
381 392 lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
382   - return errno = ENOENT;
  393 + errno = ENOENT;
  394 + return NULL;
383 395 }
384 396  
385 397 struct berval ** value = ldap_get_values_len(ld, results, attr);
... ... @@ -390,7 +402,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
390 402 message->text = _( "Can't get LDAP attribute" );
391 403 message->description = _("Search did not produce any values.");
392 404 lib3270_write_log(hSession,"ssl","%s: %s",url, message->description);
393   - return errno = ENOENT;
  405 + errno = ENOENT;
  406 + return NULL;
394 407 }
395 408  
396 409 if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
... ... @@ -406,14 +419,14 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
406 419 // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro.
407 420 const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val;
408 421  
409   - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &crl_data, value[0]->bv_len))
  422 + if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len))
410 423 {
411 424 message->error = hSession->ssl.error = ERR_get_error();
412 425 message->title = _( "Security error" );
413   - message->text = _( "Can't decode CRL got from LDAP Search" );
  426 + message->text = _( "Can't decode CRL" );
414 427 lib3270_write_log(hSession,"ssl","%s: %s",url, message->text);
415 428 ldap_value_free_len(value);
416   - return -1;
  429 + return NULL;
417 430 }
418 431  
419 432 ldap_value_free_len(value);
... ... @@ -474,7 +487,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
474 487 }
475 488  
476 489 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
477   - return -1;
  490 + errno = EINVAL;
  491 + return NULL;
478 492  
479 493 }
480 494  
... ... @@ -487,10 +501,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
487 501 message->text = _( "Error loading CRL" );
488 502 message->description = curl_easy_strerror(res);
489 503 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
490   - return -1;
  504 + errno = EINVAL;
  505 + return NULL;
491 506 }
492 507  
493   - trace_ssl(hSession,"CRL Data has %u bytes",(unsigned int) crl_data->length);
  508 + if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
  509 + lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
494 510  
495 511 if(ct)
496 512 {
... ... @@ -500,13 +516,13 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
500 516 if(strcasecmp(ct,"application/pkix-crl") == 0)
501 517 {
502 518 // CRL File, convert it
503   - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &data, crl_data->length))
  519 + if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
504 520 {
505 521 message->error = hSession->ssl.error = ERR_get_error();
506 522 message->title = _( "Security error" );
507   - message->text = _( "Got an invalid CRL from server" );
  523 + message->text = _( "Can't decode CRL" );
508 524 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
509   - return -1;
  525 + return NULL;
510 526 }
511 527 }
512 528 else
... ... @@ -515,7 +531,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
515 531 message->title = _( "Security error" );
516 532 message->text = _( "Got an invalid CRL from server" );
517 533 lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
518   - return -1;
  534 + errno = EINVAL;
  535 + return NULL;
519 536 }
520 537 }
521 538 else if(strncasecmp(consturl,"ldap://",7) == 0)
... ... @@ -526,12 +543,25 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
526 543 {
527 544 message->error = hSession->ssl.error = ERR_get_error();
528 545 message->title = _( "Security error" );
529   - message->text = _( "Got an invalid CRL from LDAP server" );
  546 + message->text = _( "Got a bad formatted CRL from LDAP server" );
530 547 lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n",consturl, crl_data->data.contents);
531   - return -1;
  548 + errno = EINVAL;
  549 + return NULL;
532 550 }
533 551 data += 3;
534 552  
  553 +#ifdef DEBUG
  554 + {
  555 + FILE *out = fopen("linux_base64.crl","w");
  556 + if(out)
  557 + {
  558 + fwrite(data,strlen(data),1,out);
  559 + fclose(out);
  560 + }
  561 +
  562 + }
  563 +#endif
  564 +
535 565 lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1);
536 566  
537 567 BIO * b64 = BIO_new(BIO_f_base64());
... ... @@ -539,13 +569,14 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
539 569  
540 570 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
541 571  
542   - if(!d2i_X509_CRL_bio(bio, &hSession->ssl.crl.cert))
  572 + if(!d2i_X509_CRL_bio(bio, &x509_crl))
543 573 {
544 574 message->error = hSession->ssl.error = ERR_get_error();
545 575 message->title = _( "Security error" );
546   - message->text = _( "Got an invalid CRL from server" );
  576 + message->text = _( "Can't decode CRL got from LDAP server" );
547 577 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
548   - return -1;
  578 + errno = EINVAL;
  579 + return NULL;
549 580 }
550 581  
551 582 }
... ... @@ -560,11 +591,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
560 591 message->text = _( "Unexpected or invalid CRL URL" );
561 592 message->description = _("The URL scheme is unknown");
562 593 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
563   - return errno = EINVAL;
  594 + errno = EINVAL;
  595 + return NULL;
564 596 #endif // HAVE_LIBCURL
565 597 }
566 598  
567   - return hSession->ssl.crl.cert == NULL ? -1 : 0;
  599 + return x509_crl;
568 600  
569 601 }
570 602  
... ...
src/lib3270/ssl/negotiate.c
... ... @@ -87,6 +87,7 @@ static int background_ssl_init(H3270 *hSession, void *message)
87 87 hSession->ssl.host = False;
88 88  
89 89 if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) message)) {
  90 + debug("%s has failed","ssl_ctx_init");
90 91 set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
91 92 hSession->ssl.host = False;
92 93 return -1;
... ...
src/lib3270/ssl/windows/getcrl.c
... ... @@ -31,14 +31,16 @@
31 31 * http://www.openssl.org/docs/ssl/
32 32 * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now
33 33 *
34   - * https://www.codepool.biz/build-use-libcurl-vs2015-windows.html
35   - *
36 34 */
37 35  
38   -#define CRL_DATA_LENGTH 4096
  36 +#define CRL_DATA_LENGTH 2048
39 37  
40 38 #include <config.h>
41 39  
  40 +#include <winsock2.h>
  41 +#include <windows.h>
  42 +#include <winldap.h>
  43 +
42 44 #if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK)
43 45  
44 46 #include <openssl/ssl.h>
... ... @@ -54,8 +56,8 @@
54 56 #include <trace_dsc.h>
55 57 #include <errno.h>
56 58 #include <lib3270.h>
57   -#include <lib3270/log.h>
58 59 #include <lib3270/trace.h>
  60 +#include <lib3270/log.h>
59 61  
60 62 /*--[ Implement ]------------------------------------------------------------------------------------*/
61 63  
... ... @@ -70,11 +72,8 @@ static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr)
70 72 {
71 73 debug("%s(%p)",__FUNCTION__,*ptr);
72 74 if(*ptr)
73   - {
74 75 curl_easy_cleanup(*ptr);
75   - }
76 76 *ptr = NULL;
77   -
78 77 }
79 78  
80 79 typedef struct _curldata
... ... @@ -127,14 +126,20 @@ static size_t internal_curl_write_callback(void *contents, size_t size, size_t n
127 126 if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE))
128 127 lib3270_trace_data(data->hSession,"curl_write:",(const char *) contents, realsize);
129 128  
130   - for(ix = 0; ix < realsize; ix++)
  129 + if((realsize + data->length) > data->data.length)
131 130 {
132   - if(data->length >= data->data.length)
  131 + data->data.length += (CRL_DATA_LENGTH + realsize);
  132 + data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
  133 +
  134 + for(ix = data->length; ix < data->data.length; ix++)
133 135 {
134   - data->data.length += (CRL_DATA_LENGTH + realsize);
135   - data->data.contents = lib3270_realloc(data->data.contents,data->data.length);
  136 + data->data.contents[ix] = 0;
136 137 }
137 138  
  139 + }
  140 +
  141 + for(ix = 0; ix < realsize; ix++)
  142 + {
138 143 data->data.contents[data->length++] = *(ptr++);
139 144 }
140 145  
... ... @@ -188,12 +193,13 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype
188 193  
189 194 return 0;
190 195 }
  196 +
191 197 #endif // HAVE_LIBCURL
192 198  
193 199  
194   -int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
  200 +LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl)
195 201 {
196   - const char * consturl = lib3270_get_crl_url(hSession);
  202 + X509_CRL * x509_crl = NULL;
197 203  
198 204 if(!(consturl && *consturl))
199 205 {
... ... @@ -201,10 +207,11 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
201 207 message->title = _( "Security error" );
202 208 message->text = _( "Can't open CRL File" );
203 209 message->description = _("The URL for the CRL is undefined or empty");
204   - return errno = ENOENT;
  210 + errno = ENOENT;
  211 + return NULL;
205 212 }
206 213  
207   - trace_ssl(hSession, "crl=%s\n",consturl);
  214 + trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl);
208 215  
209 216 if(strncasecmp(consturl,"file://",7) == 0)
210 217 {
... ... @@ -220,12 +227,21 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
220 227 message->text = _( "Can't open CRL File" );
221 228 message->description = strerror(err);
222 229 trace_ssl(hSession,"Can't open %s: %s\n",consturl,message->description);
223   - return err;
  230 + return NULL;
224 231  
225 232 }
226 233  
227 234 trace_ssl(hSession,"Loading CRL from %s\n",consturl+7);
228   - d2i_X509_CRL_fp(hCRL, &hSession->ssl.crl.cert);
  235 + if(d2i_X509_CRL_fp(hCRL, &x509_crl))
  236 + {
  237 + message->error = hSession->ssl.error = ERR_get_error();
  238 + message->title = _( "Security error" );
  239 + message->text = _( "Can't decode CRL" );
  240 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  241 + return NULL;
  242 + }
  243 +
  244 +
229 245  
230 246 }
231 247 else
... ... @@ -233,187 +249,202 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
233 249 #ifdef HAVE_LIBCURL
234 250  
235 251 // Use CURL to download the CRL
236   - lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
  252 + lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA));
  253 + lib3270_autoptr(CURL) hCurl = curl_easy_init();
237 254  
238 255 memset(crl_data,0,sizeof(CURLDATA));
239   - crl_data->message = message;
240   - crl_data->hSession = hSession;
241   -
242   - // Initialize curl and curl_easy
243   - lib3270_autoptr(CURL) hCurl = curl_easy_init();
  256 + crl_data->message = message;
  257 + crl_data->hSession = hSession;
  258 + crl_data->data.length = CRL_DATA_LENGTH;
  259 + crl_data->data.contents = lib3270_malloc(crl_data->data.length);
244 260  
245   - if(!hCurl)
  261 + if(hCurl)
246 262 {
247   - message->error = hSession->ssl.error = 0;
248   - message->title = _( "Security error" );
249   - message->text = _( "Can't initialize curl" );
250   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
251   - return -1;
252   - }
  263 + CURLcode res;
253 264  
254   - CURLcode res;
  265 + curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
  266 + curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
255 267  
256   - curl_easy_setopt(hCurl, CURLOPT_URL, consturl);
257   - curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L);
  268 + curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
258 269  
259   - curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf);
  270 + curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
  271 + curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
260 272  
261   - curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback);
262   - curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data);
  273 + curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
263 274  
264   - curl_easy_setopt(hCurl, CURLOPT_USERNAME, "");
  275 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  276 + {
  277 + curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
  278 + curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
  279 + curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
  280 + }
265 281  
266   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
267   - {
268   - curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L);
269   - curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback);
270   - curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data);
271   - }
  282 + res = curl_easy_perform(hCurl);
272 283  
273   - res = curl_easy_perform(hCurl);
  284 + if(res != CURLE_OK)
  285 + {
  286 + message->error = hSession->ssl.error = 0;
  287 + message->title = _( "Security error" );
274 288  
275   - if(res != CURLE_OK)
276   - {
277   - message->error = hSession->ssl.error = 0;
278   - message->title = _( "Security error" );
  289 + if(crl_data->errbuf[0])
  290 + {
  291 + message->text = curl_easy_strerror(res);
  292 + message->description = crl_data->errbuf;
  293 + }
  294 + else
  295 + {
  296 + message->text = _( "Error loading CRL" );
  297 + message->description = curl_easy_strerror(res);
  298 + }
  299 +
  300 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
  301 + errno = EINVAL;
  302 + return NULL;
279 303  
280   - if(crl_data->errbuf[0])
281   - {
282   - message->text = curl_easy_strerror(res);
283   - message->description = crl_data->errbuf;
284 304 }
285   - else
  305 +
  306 + char *ct = NULL;
  307 + res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
  308 + if(res != CURLE_OK)
286 309 {
  310 + message->error = hSession->ssl.error = 0;
  311 + message->title = _( "Security error" );
287 312 message->text = _( "Error loading CRL" );
288 313 message->description = curl_easy_strerror(res);
  314 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
  315 + errno = EINVAL;
  316 + return NULL;
289 317 }
290 318  
291   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
292   - return -1;
293   - }
294   -
295   - debug("Tamanho da resposta: %u", (unsigned int) crl_data->length);
296   -
297   - char *ct = NULL;
298   - res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct);
299   - if(res != CURLE_OK)
300   - {
301   - message->error = hSession->ssl.error = 0;
302   - message->title = _( "Security error" );
303   - message->text = _( "Error loading CRL" );
304   - message->description = curl_easy_strerror(res);
305   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
306   - return -1;
307   - }
308   -
309   - trace_ssl(hSession,"CRL Data has %u bytes",(unsigned int) crl_data->length);
310   -
311   - if(ct)
312   - {
313   - const unsigned char * data = crl_data->data.contents;
  319 + if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE))
  320 + lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length);
314 321  
315   - trace_ssl(crl_data->hSession, "Content-type: %s", ct);
316   -
317   - if(strcasecmp(ct,"application/pkix-crl") == 0)
  322 + if(ct)
318 323 {
319   - // CRL File, convert it
320   - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &data, crl_data->length))
  324 + const unsigned char * data = crl_data->data.contents;
  325 +
  326 + if(strcasecmp(ct,"application/pkix-crl") == 0)
  327 + {
  328 + // CRL File, convert it
  329 + if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length))
  330 + {
  331 + message->error = hSession->ssl.error = ERR_get_error();
  332 + message->title = _( "Security error" );
  333 + message->text = _( "Can't decode CRL" );
  334 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  335 + return NULL;
  336 + }
  337 + }
  338 + else
321 339 {
322 340 message->error = hSession->ssl.error = ERR_get_error();
323 341 message->title = _( "Security error" );
324 342 message->text = _( "Got an invalid CRL from server" );
325   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
326   - return -1;
  343 + lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
  344 + errno = EINVAL;
  345 + return NULL;
327 346 }
328 347 }
329   - else
330   - {
331   - message->error = hSession->ssl.error = ERR_get_error();
332   - message->title = _( "Security error" );
333   - message->text = _( "Got an invalid CRL from server" );
334   - lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct);
335   - return -1;
336   - }
337   - }
338   - else if(strncasecmp(consturl,"ldap://",7) == 0)
339   - {
340   - // LDAP Query on curl for windows returns an unprocessed response instead of a base64 data.
341   - char * attr = strchr(consturl,'?');
342   - if(!attr)
  348 + else if(strncasecmp(consturl,"ldap://",7) == 0)
343 349 {
344   - message->error = hSession->ssl.error = 0;
345   - message->title = _( "Security error" );
346   - message->text = _( "No attribute in LDAP search URL" );
347   - return errno = ENOENT;
348   - }
  350 + //
  351 + // curl's LDAP query on windows returns diferently. Working with it.
  352 + //
  353 +#ifdef DEBUG
  354 + {
  355 + FILE *out = fopen("downloaded.crl","w");
  356 + if(out)
  357 + {
  358 + fwrite(crl_data->data.contents,crl_data->length,1,out);
  359 + fclose(out);
  360 + }
349 361  
350   - attr++;
  362 + }
  363 +#endif
351 364  
352   - //
353   - // There's something odd on libcurl for windows! For some reason it's not converting the LDAP response values to
354   - // base64, because of this I've to extract the BER directly.
355   - //
356   - // This is an ugly solution, I know!
357   - //
  365 + char * attr = strchr(consturl,'?');
  366 + if(!attr)
  367 + {
  368 + message->error = hSession->ssl.error = 0;
  369 + message->title = _( "Security error" );
  370 + message->text = _( "No attribute in LDAP search URL" );
  371 + errno = ENOENT;
  372 + return NULL;
  373 + }
358 374  
359   - lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr);
360   - trace_ssl(crl_data->hSession, text);
  375 + attr++;
361 376  
362   - lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr);
363   - char *ptr = strstr((char *) crl_data->data.contents, key);
  377 + lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr);
  378 + trace_ssl(crl_data->hSession, text);
364 379  
365   - debug("key=\"%s\" ptr=%p",key,ptr)
  380 + lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr);
366 381  
367   - if(!ptr)
368   - {
369   - message->error = hSession->ssl.error = 0;
370   - message->title = _( "Security error" );
371   - message->text = _( "Can't find attribute in LDAP response" );
372   - return errno = ENOENT;
373   - }
374 382  
375   - ptr += strlen(key);
376   - size_t length = crl_data->length - (ptr - ((char *) crl_data->data.contents));
377   - size_t ix;
  383 +// char *ptr = strcasestr((char *) crl_data->data.contents, key);
378 384  
379   - for(ix = 0; ix < (length-1); ix++)
380   - {
381   - if(ptr[ix] == '\n' && ptr[ix+1] == '\n')
382   - break;
383   - }
  385 + size_t ix;
  386 + unsigned char *from = NULL;
  387 + size_t keylength = strlen(key);
  388 + for(ix = 0; ix < (crl_data->length - keylength); ix++)
  389 + {
  390 + if(!strncasecmp( (char *) (crl_data->data.contents+ix),key,keylength))
  391 + {
  392 + from = crl_data->data.contents+ix;
  393 + break;
  394 + }
  395 + }
384 396  
385   - debug("length=%u ix=%u", (unsigned int) length, (unsigned int) ix);
  397 + debug("strstr(%s): %p", key, from);
386 398  
387   - if(ix >= length)
388   - {
389   - message->error = hSession->ssl.error = 0;
390   - message->title = _( "Security error" );
391   - message->text = _( "Can't find attribute end in LDAP response" );
392   - return errno = ENOENT;
393   - }
  399 + if(!from)
  400 + {
  401 + message->error = hSession->ssl.error = 0;
  402 + message->title = _( "Security error" );
  403 + message->text = _( "Can't find attribute in LDAP response" );
  404 + errno = ENOENT;
  405 + return NULL;
  406 + }
394 407  
395   - length = ix;
  408 + from += strlen(key);
  409 + size_t length = crl_data->length - (from - crl_data->data.contents);
396 410  
397   - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
398   - {
399   - lib3270_trace_data(
400   - hSession,
401   - "CRL Data received from LDAP server",
402   - (const char *) ptr,
403   - length
404   - );
405   - }
  411 + static const char terminator[] = { 0x0a, 0x0a, 0x09 };
  412 + unsigned char *to = from+length;
406 413  
407   - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, (const unsigned char **) &ptr, length))
408   - {
409   - message->error = hSession->ssl.error = ERR_get_error();
410   - message->title = _( "Security error" );
411   - message->text = _( "Can't decode CRL got from LDAP Search" );
412   - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
413   - return -1;
414   - }
  414 + for(ix = 0; ix < (length - sizeof(terminator)); ix++)
  415 + {
  416 + if(!memcmp(from+ix,terminator,sizeof(terminator)))
  417 + {
  418 + to = from+ix;
  419 + break;
  420 + }
  421 + }
415 422  
  423 + length = to - from;
  424 +
  425 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE))
  426 + {
  427 + lib3270_trace_data(
  428 + hSession,
  429 + "CRL Data received from LDAP server",
  430 + (const char *) from,
  431 + length
  432 + );
  433 + }
  434 +
  435 + if(!d2i_X509_CRL(&x509_crl, (const unsigned char **) &from, length))
  436 + {
  437 + message->error = hSession->ssl.error = ERR_get_error();
  438 + message->title = _( "Security error" );
  439 + message->text = _( "Can't decode CRL got from LDAP Search" );
  440 + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text);
  441 + errno = EINVAL;
  442 + return NULL;
  443 + }
  444 +
  445 + }
416 446 }
  447 +
417 448 #else
418 449 // Can't get CRL.
419 450  
... ... @@ -422,12 +453,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message)
422 453 message->text = _( "Unexpected or invalid CRL URL" );
423 454 message->description = _("The URL scheme is unknown");
424 455 lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description);
425   - return errno= EINVAL;
  456 + errno = EINVAL;
  457 + return NULL;
426 458 #endif // HAVE_LIBCURL
427   -
428 459 }
429 460  
430   - return hSession->ssl.crl.cert == NULL ? -1 : 0;
  461 + return x509_crl;
431 462  
432 463 }
433 464  
... ...
src/lib3270/testprogram/testprogram.c
... ... @@ -75,7 +75,7 @@ int main(int argc, char *argv[])
75 75 printf("\nConnecting to %s\n",lib3270_get_url(h));
76 76  
77 77 rc = lib3270_reconnect(h,120);
78   - printf("\nConnect exits with rc=%d\n",rc);
  78 + printf("\n\nConnect exits with rc=%d (%s)\n\n",rc,strerror(rc));
79 79  
80 80 if(!rc)
81 81 {
... ...
src/lib3270/windows/log.c
... ... @@ -60,6 +60,11 @@
60 60 msg
61 61 };
62 62  
  63 +#ifdef DEBUG
  64 + fprintf(stderr,"LOG(%s): %s\n",module,msg);
  65 + fflush(stderr);
  66 +#endif // DEBUG
  67 +
63 68 ReportEvent(
64 69 hEventLog,
65 70 (rc == 0 ? EVENTLOG_INFORMATION_TYPE : EVENTLOG_ERROR_TYPE),
... ... @@ -74,7 +79,7 @@
74 79  
75 80 }
76 81  
77   - LIB3270_EXPORT int lib3270_set_syslog(int flag)
  82 + LIB3270_EXPORT int lib3270_set_syslog(int GNUC_UNUSED(flag))
78 83 {
79 84 return errno = ENOENT;
80 85 }
... ...