Commit 151e49166f78e60b564f076e61d54fd74a827715
1 parent
7f7077f5
Exists in
master
and in
3 other branches
Fixing problem with CRL download from LDAP with libcurl for windows.
Showing
10 changed files
with
303 additions
and
214 deletions
Show diff stats
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 | } | ... | ... |