diff --git a/lib3270.cbp b/lib3270.cbp index 9eea33d..c3257ae 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -104,22 +104,10 @@ - - - - - - - - - - - - diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c index 8e65f67..4dcd17d 100644 --- a/src/lib3270/connect.c +++ b/src/lib3270/connect.c @@ -98,16 +98,38 @@ static int background_ssl_crl_check(H3270 *hSession, void *ssl_error) set_ssl_state(hSession,LIB3270_SSL_NEGOTIATING); int rc = lib3270_run_task(hSession, background_ssl_crl_check, &ssl_error); + + debug("CRL check returns %d",rc); + if(rc) { + lib3270_write_log( + hSession, + "SSL-CRL-CHECK", + "CRL Check error: %s (rc=%d ssl_error=%d)", + ssl_error.title, + rc, + ssl_error.error + ); + if(ssl_error.description) + { + lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",ssl_error.description); lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ssl_error.description); + } else if(ssl_error.error) - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", ERR_reason_error_string(ssl_error.error)); + { + lib3270_autoptr(char) formatted_error = lib3270_strdup_printf("%s (SSL error %d)",ERR_reason_error_string(ssl_error.error),ssl_error.error); + lib3270_write_log(hSession,"SSL-CRL-CHECK","%s",formatted_error); + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s", formatted_error); + } else + { lib3270_popup_dialog(hSession, LIB3270_NOTIFY_ERROR, ssl_error.title, ssl_error.text, "%s",""); + } + + // return errno = rc; - return errno = rc; } #endif // SSL_ENABLE_CRL_CHECK diff --git a/src/lib3270/iocalls.c b/src/lib3270/iocalls.c index d49cb90..992983c 100644 --- a/src/lib3270/iocalls.c +++ b/src/lib3270/iocalls.c @@ -591,8 +591,6 @@ int non_blocking(H3270 *hSession, Boolean on) lib3270_set_poll_state(hSession,hSession->xio.write, on); lib3270_set_poll_state(hSession,hSession->xio.except, on); - trace("******** Socket %d is %s",hSession->sock, on ? "non-blocking" : "blocking"); - return 0; } diff --git a/src/lib3270/private.h b/src/lib3270/private.h index eeaefda..048f69b 100644 --- a/src/lib3270/private.h +++ b/src/lib3270/private.h @@ -772,7 +772,7 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); LIB3270_INTERNAL int ssl_3270_ex_index; #ifdef SSL_ENABLE_CRL_CHECK - LIB3270_INTERNAL int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message); + LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *url); LIB3270_INTERNAL int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message); #endif // SSL_ENABLE_CRL_CHECK diff --git a/src/lib3270/ssl/ctx_init.c b/src/lib3270/ssl/ctx_init.c index 5356255..f574309 100644 --- a/src/lib3270/ssl/ctx_init.c +++ b/src/lib3270/ssl/ctx_init.c @@ -105,7 +105,10 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message) { // Returns if don't have an SSL context. if(!ssl_ctx) + { + trace("No SSL context %s will return %d",__FUNCTION__,0); return 0; + } // Do I have X509 CRL? Is it valid? if(hSession->ssl.crl.cert) @@ -147,8 +150,11 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message) // // https://stackoverflow.com/questions/10510850/how-to-verify-the-certificate-for-the-ongoing-ssl-session // - if(lib3270_get_X509_CRL(hSession,message)) - return -1; + hSession->ssl.crl.cert = lib3270_get_crl(hSession,message,lib3270_get_crl_url(hSession)); + if(!hSession->ssl.crl.cert) + { + return -1; + } if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) { @@ -159,20 +165,17 @@ int lib3270_check_X509_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message) } + // Add CRL in the store. X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); - - if(hSession->ssl.crl.cert) + if(X509_STORE_add_crl(store, hSession->ssl.crl.cert)) { - X509_STORE_add_crl(store, hSession->ssl.crl.cert); trace_ssl(hSession,"CRL was added to cert store\n"); + return 0; } - X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); - X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); - X509_STORE_set1_param(store, param); - X509_VERIFY_PARAM_free(param); + trace_ssl(hSession,"CRL was not added to cert store\n"); - return 0; + return -1; } #endif // SSL_ENABLE_CRL_CHECK @@ -239,6 +242,15 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) ssl_3270_ex_index = SSL_get_ex_new_index(0,NULL,NULL,NULL,NULL); #ifdef SSL_ENABLE_CRL_CHECK + + // Enable CRL check + X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx); + X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); + X509_STORE_set1_param(store, param); + X509_VERIFY_PARAM_free(param); + trace_ssl(hSession,"CRL CHECK was enabled\n"); + return lib3270_check_X509_crl(hSession,message); #else return 0; diff --git a/src/lib3270/ssl/linux/getcrl.c b/src/lib3270/ssl/linux/getcrl.c index 7de0fc9..db246e5 100644 --- a/src/lib3270/ssl/linux/getcrl.c +++ b/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 { data->data.length += (CRL_DATA_LENGTH + realsize); data->data.contents = lib3270_realloc(data->data.contents,data->data.length); + memset(&(data->data.contents[data->length]),0,data->data.length-data->length); } debug("%s",__FUNCTION__); @@ -237,9 +238,9 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype #endif // HAVE_LIBCURL -int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) +LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl) { - const char * consturl = lib3270_get_crl_url(hSession); + X509_CRL * x509_crl = NULL; if(!(consturl && *consturl)) { @@ -247,10 +248,11 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->title = _( "Security error" ); message->text = _( "Can't open CRL File" ); message->description = _("The URL for the CRL is undefined or empty"); - return errno = ENOENT; + errno = ENOENT; + return NULL; } - trace_ssl(hSession, "crl=%s\n",consturl); + trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl); if(strncasecmp(consturl,"file://",7) == 0) { @@ -266,12 +268,21 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Can't open CRL File" ); message->description = strerror(err); trace_ssl(hSession,"Can't open %s: %s\n",consturl,message->description); - return err; + return NULL; } trace_ssl(hSession,"Loading CRL from %s\n",consturl+7); - d2i_X509_CRL_fp(hCRL, &hSession->ssl.crl.cert); + if(d2i_X509_CRL_fp(hCRL, &x509_crl)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = _( "Security error" ); + message->text = _( "Can't decode CRL" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + return NULL; + } + + } #ifdef HAVE_LDAP @@ -332,7 +343,7 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Can't set LDAP version" ); message->description = ldap_err2string(rc); lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return -1; + return NULL; } rc = ldap_simple_bind_s(ld, "", ""); @@ -368,7 +379,7 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Can't search LDAP server" ); message->description = ldap_err2string(rc); lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return -1; + return NULL; } 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) message->text = _( "Can't get LDAP attribute" ); message->description = _("Search did not produce any attributes."); lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return errno = ENOENT; + errno = ENOENT; + return NULL; } 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) message->text = _( "Can't get LDAP attribute" ); message->description = _("Search did not produce any values."); lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return errno = ENOENT; + errno = ENOENT; + return NULL; } if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) @@ -406,14 +419,14 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) // Precisa salvar uma cópia porque d2i_X509_CRL modifica o ponteiro. const unsigned char *crl_data = (const unsigned char *) value[0]->bv_val; - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &crl_data, value[0]->bv_len)) + if(!d2i_X509_CRL(&x509_crl, &crl_data, value[0]->bv_len)) { message->error = hSession->ssl.error = ERR_get_error(); message->title = _( "Security error" ); - message->text = _( "Can't decode CRL got from LDAP Search" ); + message->text = _( "Can't decode CRL" ); lib3270_write_log(hSession,"ssl","%s: %s",url, message->text); ldap_value_free_len(value); - return -1; + return NULL; } ldap_value_free_len(value); @@ -474,7 +487,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) } lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return -1; + errno = EINVAL; + return NULL; } @@ -487,10 +501,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Error loading CRL" ); message->description = curl_easy_strerror(res); lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return -1; + errno = EINVAL; + return NULL; } - trace_ssl(hSession,"CRL Data has %u bytes",(unsigned int) crl_data->length); + if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE)) + lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length); if(ct) { @@ -500,13 +516,13 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) if(strcasecmp(ct,"application/pkix-crl") == 0) { // CRL File, convert it - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &data, crl_data->length)) + if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length)) { message->error = hSession->ssl.error = ERR_get_error(); message->title = _( "Security error" ); - message->text = _( "Got an invalid CRL from server" ); + message->text = _( "Can't decode CRL" ); lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); - return -1; + return NULL; } } else @@ -515,7 +531,8 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->title = _( "Security error" ); message->text = _( "Got an invalid CRL from server" ); lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct); - return -1; + errno = EINVAL; + return NULL; } } else if(strncasecmp(consturl,"ldap://",7) == 0) @@ -526,12 +543,25 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) { message->error = hSession->ssl.error = ERR_get_error(); message->title = _( "Security error" ); - message->text = _( "Got an invalid CRL from LDAP server" ); + message->text = _( "Got a bad formatted CRL from LDAP server" ); lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n",consturl, crl_data->data.contents); - return -1; + errno = EINVAL; + return NULL; } data += 3; +#ifdef DEBUG + { + FILE *out = fopen("linux_base64.crl","w"); + if(out) + { + fwrite(data,strlen(data),1,out); + fclose(out); + } + + } +#endif + lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1); BIO * b64 = BIO_new(BIO_f_base64()); @@ -539,13 +569,14 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - if(!d2i_X509_CRL_bio(bio, &hSession->ssl.crl.cert)) + if(!d2i_X509_CRL_bio(bio, &x509_crl)) { message->error = hSession->ssl.error = ERR_get_error(); message->title = _( "Security error" ); - message->text = _( "Got an invalid CRL from server" ); + message->text = _( "Can't decode CRL got from LDAP server" ); lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); - return -1; + errno = EINVAL; + return NULL; } } @@ -560,11 +591,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Unexpected or invalid CRL URL" ); message->description = _("The URL scheme is unknown"); lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return errno = EINVAL; + errno = EINVAL; + return NULL; #endif // HAVE_LIBCURL } - return hSession->ssl.crl.cert == NULL ? -1 : 0; + return x509_crl; } diff --git a/src/lib3270/ssl/negotiate.c b/src/lib3270/ssl/negotiate.c index 158530e..eab38e8 100644 --- a/src/lib3270/ssl/negotiate.c +++ b/src/lib3270/ssl/negotiate.c @@ -87,6 +87,7 @@ static int background_ssl_init(H3270 *hSession, void *message) hSession->ssl.host = False; if(ssl_ctx_init(hSession, (SSL_ERROR_MESSAGE *) message)) { + debug("%s has failed","ssl_ctx_init"); set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); hSession->ssl.host = False; return -1; diff --git a/src/lib3270/ssl/windows/getcrl.c b/src/lib3270/ssl/windows/getcrl.c index dabd3ee..781c481 100644 --- a/src/lib3270/ssl/windows/getcrl.c +++ b/src/lib3270/ssl/windows/getcrl.c @@ -31,14 +31,16 @@ * http://www.openssl.org/docs/ssl/ * https://stackoverflow.com/questions/4389954/does-openssl-automatically-handle-crls-certificate-revocation-lists-now * - * https://www.codepool.biz/build-use-libcurl-vs2015-windows.html - * */ -#define CRL_DATA_LENGTH 4096 +#define CRL_DATA_LENGTH 2048 #include +#include +#include +#include + #if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) #include @@ -54,8 +56,8 @@ #include #include #include -#include #include +#include /*--[ Implement ]------------------------------------------------------------------------------------*/ @@ -70,11 +72,8 @@ static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr) { debug("%s(%p)",__FUNCTION__,*ptr); if(*ptr) - { curl_easy_cleanup(*ptr); - } *ptr = NULL; - } typedef struct _curldata @@ -127,14 +126,20 @@ static size_t internal_curl_write_callback(void *contents, size_t size, size_t n if(lib3270_get_toggle(data->hSession,LIB3270_TOGGLE_SSL_TRACE)) lib3270_trace_data(data->hSession,"curl_write:",(const char *) contents, realsize); - for(ix = 0; ix < realsize; ix++) + if((realsize + data->length) > data->data.length) { - if(data->length >= data->data.length) + data->data.length += (CRL_DATA_LENGTH + realsize); + data->data.contents = lib3270_realloc(data->data.contents,data->data.length); + + for(ix = data->length; ix < data->data.length; ix++) { - data->data.length += (CRL_DATA_LENGTH + realsize); - data->data.contents = lib3270_realloc(data->data.contents,data->data.length); + data->data.contents[ix] = 0; } + } + + for(ix = 0; ix < realsize; ix++) + { data->data.contents[data->length++] = *(ptr++); } @@ -188,12 +193,13 @@ static int internal_curl_trace_callback(CURL GNUC_UNUSED(*handle), curl_infotype return 0; } + #endif // HAVE_LIBCURL -int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) +LIB3270_INTERNAL X509_CRL * lib3270_get_crl(H3270 *hSession, SSL_ERROR_MESSAGE * message, const char *consturl) { - const char * consturl = lib3270_get_crl_url(hSession); + X509_CRL * x509_crl = NULL; if(!(consturl && *consturl)) { @@ -201,10 +207,11 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->title = _( "Security error" ); message->text = _( "Can't open CRL File" ); message->description = _("The URL for the CRL is undefined or empty"); - return errno = ENOENT; + errno = ENOENT; + return NULL; } - trace_ssl(hSession, "crl=%s\n",consturl); + trace_ssl(hSession, "Getting CRL from \"%s\"\n",consturl); if(strncasecmp(consturl,"file://",7) == 0) { @@ -220,12 +227,21 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Can't open CRL File" ); message->description = strerror(err); trace_ssl(hSession,"Can't open %s: %s\n",consturl,message->description); - return err; + return NULL; } trace_ssl(hSession,"Loading CRL from %s\n",consturl+7); - d2i_X509_CRL_fp(hCRL, &hSession->ssl.crl.cert); + if(d2i_X509_CRL_fp(hCRL, &x509_crl)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = _( "Security error" ); + message->text = _( "Can't decode CRL" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + return NULL; + } + + } else @@ -233,187 +249,202 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) #ifdef HAVE_LIBCURL // Use CURL to download the CRL - lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA)); + lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA)); + lib3270_autoptr(CURL) hCurl = curl_easy_init(); memset(crl_data,0,sizeof(CURLDATA)); - crl_data->message = message; - crl_data->hSession = hSession; - - // Initialize curl and curl_easy - lib3270_autoptr(CURL) hCurl = curl_easy_init(); + crl_data->message = message; + crl_data->hSession = hSession; + crl_data->data.length = CRL_DATA_LENGTH; + crl_data->data.contents = lib3270_malloc(crl_data->data.length); - if(!hCurl) + if(hCurl) { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); - message->text = _( "Can't initialize curl" ); - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); - return -1; - } + CURLcode res; - CURLcode res; + curl_easy_setopt(hCurl, CURLOPT_URL, consturl); + curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(hCurl, CURLOPT_URL, consturl); - curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf); - curl_easy_setopt(hCurl, CURLOPT_ERRORBUFFER, crl_data->errbuf); + curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback); + curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data); - curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback); - curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data); + curl_easy_setopt(hCurl, CURLOPT_USERNAME, ""); - curl_easy_setopt(hCurl, CURLOPT_USERNAME, ""); + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) + { + curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback); + curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data); + } - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) - { - curl_easy_setopt(hCurl, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(hCurl, CURLOPT_DEBUGFUNCTION, internal_curl_trace_callback); - curl_easy_setopt(hCurl, CURLOPT_DEBUGDATA, (void *) crl_data); - } + res = curl_easy_perform(hCurl); - res = curl_easy_perform(hCurl); + if(res != CURLE_OK) + { + message->error = hSession->ssl.error = 0; + message->title = _( "Security error" ); - if(res != CURLE_OK) - { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); + if(crl_data->errbuf[0]) + { + message->text = curl_easy_strerror(res); + message->description = crl_data->errbuf; + } + else + { + message->text = _( "Error loading CRL" ); + message->description = curl_easy_strerror(res); + } + + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); + errno = EINVAL; + return NULL; - if(crl_data->errbuf[0]) - { - message->text = curl_easy_strerror(res); - message->description = crl_data->errbuf; } - else + + char *ct = NULL; + res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct); + if(res != CURLE_OK) { + message->error = hSession->ssl.error = 0; + message->title = _( "Security error" ); message->text = _( "Error loading CRL" ); message->description = curl_easy_strerror(res); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); + errno = EINVAL; + return NULL; } - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return -1; - } - - debug("Tamanho da resposta: %u", (unsigned int) crl_data->length); - - char *ct = NULL; - res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct); - if(res != CURLE_OK) - { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); - message->text = _( "Error loading CRL" ); - message->description = curl_easy_strerror(res); - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return -1; - } - - trace_ssl(hSession,"CRL Data has %u bytes",(unsigned int) crl_data->length); - - if(ct) - { - const unsigned char * data = crl_data->data.contents; + if(lib3270_get_toggle(crl_data->hSession,LIB3270_TOGGLE_SSL_TRACE)) + lib3270_trace_data(crl_data->hSession,"CRL Data",(const char *) crl_data->data.contents, (unsigned int) crl_data->length); - trace_ssl(crl_data->hSession, "Content-type: %s", ct); - - if(strcasecmp(ct,"application/pkix-crl") == 0) + if(ct) { - // CRL File, convert it - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, &data, crl_data->length)) + const unsigned char * data = crl_data->data.contents; + + if(strcasecmp(ct,"application/pkix-crl") == 0) + { + // CRL File, convert it + if(!d2i_X509_CRL(&x509_crl, &data, crl_data->length)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = _( "Security error" ); + message->text = _( "Can't decode CRL" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + return NULL; + } + } + else { message->error = hSession->ssl.error = ERR_get_error(); message->title = _( "Security error" ); message->text = _( "Got an invalid CRL from server" ); - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); - return -1; + lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct); + errno = EINVAL; + return NULL; } } - else - { - message->error = hSession->ssl.error = ERR_get_error(); - message->title = _( "Security error" ); - message->text = _( "Got an invalid CRL from server" ); - lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct); - return -1; - } - } - else if(strncasecmp(consturl,"ldap://",7) == 0) - { - // LDAP Query on curl for windows returns an unprocessed response instead of a base64 data. - char * attr = strchr(consturl,'?'); - if(!attr) + else if(strncasecmp(consturl,"ldap://",7) == 0) { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); - message->text = _( "No attribute in LDAP search URL" ); - return errno = ENOENT; - } + // + // curl's LDAP query on windows returns diferently. Working with it. + // +#ifdef DEBUG + { + FILE *out = fopen("downloaded.crl","w"); + if(out) + { + fwrite(crl_data->data.contents,crl_data->length,1,out); + fclose(out); + } - attr++; + } +#endif - // - // There's something odd on libcurl for windows! For some reason it's not converting the LDAP response values to - // base64, because of this I've to extract the BER directly. - // - // This is an ugly solution, I know! - // + char * attr = strchr(consturl,'?'); + if(!attr) + { + message->error = hSession->ssl.error = 0; + message->title = _( "Security error" ); + message->text = _( "No attribute in LDAP search URL" ); + errno = ENOENT; + return NULL; + } - lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr); - trace_ssl(crl_data->hSession, text); + attr++; - lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr); - char *ptr = strstr((char *) crl_data->data.contents, key); + lib3270_autoptr(char) text = lib3270_strdup_printf("No mime-type, extracting \"%s\" directly from LDAP response\n",attr); + trace_ssl(crl_data->hSession, text); - debug("key=\"%s\" ptr=%p",key,ptr) + lib3270_autoptr(char) key = lib3270_strdup_printf("%s: ",attr); - if(!ptr) - { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); - message->text = _( "Can't find attribute in LDAP response" ); - return errno = ENOENT; - } - ptr += strlen(key); - size_t length = crl_data->length - (ptr - ((char *) crl_data->data.contents)); - size_t ix; +// char *ptr = strcasestr((char *) crl_data->data.contents, key); - for(ix = 0; ix < (length-1); ix++) - { - if(ptr[ix] == '\n' && ptr[ix+1] == '\n') - break; - } + size_t ix; + unsigned char *from = NULL; + size_t keylength = strlen(key); + for(ix = 0; ix < (crl_data->length - keylength); ix++) + { + if(!strncasecmp( (char *) (crl_data->data.contents+ix),key,keylength)) + { + from = crl_data->data.contents+ix; + break; + } + } - debug("length=%u ix=%u", (unsigned int) length, (unsigned int) ix); + debug("strstr(%s): %p", key, from); - if(ix >= length) - { - message->error = hSession->ssl.error = 0; - message->title = _( "Security error" ); - message->text = _( "Can't find attribute end in LDAP response" ); - return errno = ENOENT; - } + if(!from) + { + message->error = hSession->ssl.error = 0; + message->title = _( "Security error" ); + message->text = _( "Can't find attribute in LDAP response" ); + errno = ENOENT; + return NULL; + } - length = ix; + from += strlen(key); + size_t length = crl_data->length - (from - crl_data->data.contents); - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) - { - lib3270_trace_data( - hSession, - "CRL Data received from LDAP server", - (const char *) ptr, - length - ); - } + static const char terminator[] = { 0x0a, 0x0a, 0x09 }; + unsigned char *to = from+length; - if(!d2i_X509_CRL(&hSession->ssl.crl.cert, (const unsigned char **) &ptr, length)) - { - message->error = hSession->ssl.error = ERR_get_error(); - message->title = _( "Security error" ); - message->text = _( "Can't decode CRL got from LDAP Search" ); - lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); - return -1; - } + for(ix = 0; ix < (length - sizeof(terminator)); ix++) + { + if(!memcmp(from+ix,terminator,sizeof(terminator))) + { + to = from+ix; + break; + } + } + length = to - from; + + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_SSL_TRACE)) + { + lib3270_trace_data( + hSession, + "CRL Data received from LDAP server", + (const char *) from, + length + ); + } + + if(!d2i_X509_CRL(&x509_crl, (const unsigned char **) &from, length)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = _( "Security error" ); + message->text = _( "Can't decode CRL got from LDAP Search" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + errno = EINVAL; + return NULL; + } + + } } + #else // Can't get CRL. @@ -422,12 +453,12 @@ int lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->text = _( "Unexpected or invalid CRL URL" ); message->description = _("The URL scheme is unknown"); lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); - return errno= EINVAL; + errno = EINVAL; + return NULL; #endif // HAVE_LIBCURL - } - return hSession->ssl.crl.cert == NULL ? -1 : 0; + return x509_crl; } diff --git a/src/lib3270/testprogram/testprogram.c b/src/lib3270/testprogram/testprogram.c index c1f2934..0fa2c0f 100644 --- a/src/lib3270/testprogram/testprogram.c +++ b/src/lib3270/testprogram/testprogram.c @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) printf("\nConnecting to %s\n",lib3270_get_url(h)); rc = lib3270_reconnect(h,120); - printf("\nConnect exits with rc=%d\n",rc); + printf("\n\nConnect exits with rc=%d (%s)\n\n",rc,strerror(rc)); if(!rc) { diff --git a/src/lib3270/windows/log.c b/src/lib3270/windows/log.c index dedc075..cc3355d 100644 --- a/src/lib3270/windows/log.c +++ b/src/lib3270/windows/log.c @@ -60,6 +60,11 @@ msg }; +#ifdef DEBUG + fprintf(stderr,"LOG(%s): %s\n",module,msg); + fflush(stderr); +#endif // DEBUG + ReportEvent( hEventLog, (rc == 0 ? EVENTLOG_INFORMATION_TYPE : EVENTLOG_ERROR_TYPE), @@ -74,7 +79,7 @@ } - LIB3270_EXPORT int lib3270_set_syslog(int flag) + LIB3270_EXPORT int lib3270_set_syslog(int GNUC_UNUSED(flag)) { return errno = ENOENT; } -- libgit2 0.21.2