diff --git a/lib3270.cbp b/lib3270.cbp index 207e763..12f3dba 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -219,7 +219,7 @@ - + diff --git a/src/include/config.h.in b/src/include/config.h.in index 31d2374..f803796 100644 --- a/src/include/config.h.in +++ b/src/include/config.h.in @@ -61,11 +61,6 @@ #undef SSL_ENABLE_CRL_EXPIRATION_CHECK #undef SSL_DEFAULT_CRL_URL - /* Windows Options */ -#ifdef WIN32 - #undef HAVE_WIN_REGISTRY -#endif // WIN32 - /* Optional parts. */ #undef X3270_DBCS #undef X3270_SCRIPT diff --git a/src/lib3270/session.c b/src/lib3270/session.c index aff406f..45eefd3 100644 --- a/src/lib3270/session.c +++ b/src/lib3270/session.c @@ -254,6 +254,11 @@ static void set_peer_certificate)(const void *cert unused) } #endif // HAVE_LIBSSL +static void default_update_luname(H3270 *session unused, const char *name unused) +{ + +} + void lib3270_reset_callbacks(H3270 *hSession) { // Default calls @@ -283,7 +288,7 @@ void lib3270_reset_callbacks(H3270 *hSession) hSession->cbk.set_timer = set_timer; hSession->cbk.print = print; hSession->cbk.set_peer_certificate = set_peer_certificate; - hSession->cbk.update_luname = (void (*)(H3270 *, const char *)) nop_int; + hSession->cbk.update_luname = default_update_luname; } @@ -298,7 +303,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char lib3270_reset_callbacks(hSession); // Trace management. - hSession->trace.handler = def_trace; + hSession->trace.handler = def_trace; // Set the defaults. hSession->extended = 1; diff --git a/src/lib3270/ssl/linux/getcrl.c b/src/lib3270/ssl/linux/getcrl.c index 36bbabd..99ae285 100644 --- a/src/lib3270/ssl/linux/getcrl.c +++ b/src/lib3270/ssl/linux/getcrl.c @@ -150,23 +150,6 @@ static size_t internal_curl_write_callback(void *contents, size_t size, size_t n memcpy(&(data->contents[data->length]),contents,realsize); data->length += realsize; - /* - struct MemoryStruct *mem = (struct MemoryStruct *)userp; - - char *ptr = realloc(mem->memory, mem->size + realsize + 1); - if(ptr == NULL) { - printf("not enough memory (realloc returned NULL)\n"); - return 0; - } - - mem->memory = ptr; - memcpy(&(mem->memory[mem->size]), contents, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - - */ - - return realsize; } diff --git a/src/lib3270/ssl/windows/getcrl.c b/src/lib3270/ssl/windows/getcrl.c index e9d4e16..308f063 100644 --- a/src/lib3270/ssl/windows/getcrl.c +++ b/src/lib3270/ssl/windows/getcrl.c @@ -33,7 +33,10 @@ * */ +#define CRL_DATA_LENGTH 4096 + #include + #if defined(HAVE_LIBSSL) && defined(SSL_ENABLE_CRL_CHECK) #include @@ -41,10 +44,9 @@ #include #include -#ifdef HAVE_LDAP - #define LDAP_DEPRECATED 1 - #include -#endif // HAVE_LDAP +#ifdef HAVE_LIBCURL + #include +#endif // HAVE_LIBCURL #include "../../private.h" #include @@ -59,66 +61,80 @@ static inline void lib3270_autoptr_cleanup_FILE(FILE **file) fclose(*file); } -#ifdef HAVE_LDAP -static inline void lib3270_autoptr_cleanup_LDAPMessage(LDAPMessage **message) +#ifdef HAVE_LIBCURL +static inline void lib3270_autoptr_cleanup_CURL(CURL **ptr) { - debug("%s(%p)",__FUNCTION__,*message); - if(message) - ldap_msgfree(*message); - *message = NULL; + debug("%s(%p)",__FUNCTION__,*ptr); + if(*ptr) + curl_easy_cleanup(*ptr); + *ptr = NULL; } -static inline void lib3270_autoptr_cleanup_LDAP(LDAP **ld) +typedef struct _curldata { - debug("%s(%p)",__FUNCTION__,*ld); - if(*ld) - ldap_unbind_ext(*ld, NULL, NULL); - *ld = NULL; -} + size_t length; + SSL_ERROR_MESSAGE * message; + unsigned char contents[CRL_DATA_LENGTH]; +} CURLDATA; -static inline void lib3270_autoptr_cleanup_BerElement(BerElement **ber) +static inline void lib3270_autoptr_cleanup_CURLDATA(CURLDATA **ptr) { - debug("%s(%p)",__FUNCTION__,*ber); - if(*ber) - ber_free(*ber, 0); - *ber = NULL; + debug("%s(%p)",__FUNCTION__,*ptr); + if(*ptr) + lib3270_free(*ptr); + *ptr = NULL; } -static inline void lib3270_autoptr_cleanup_LDAPPTR(char **ptr) +static inline void lib3270_autoptr_cleanup_BIO(BIO **ptr) { debug("%s(%p)",__FUNCTION__,*ptr); if(*ptr) - ldap_memfree(*ptr); + BIO_free_all(*ptr); *ptr = NULL; } -#endif // HAVE_LDAP - -X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) +static size_t internal_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userp) { - X509_CRL * crl = NULL; + CURLDATA * data = (CURLDATA *) userp; + + size_t realsize = size * nmemb; - if(!hSession->ssl.crl) + if((size + data->length) > CRL_DATA_LENGTH) { -#ifdef LIB3270_DEFAULT_CRL - hSession->ssl.crl = strdup(LIB3270_DEFAULT_CRL); -#else - char *env = getenv("LIB3270_DEFAULT_CRL"); - if(env) - hSession->ssl.crl = strdup(env); -#endif // LIB3270_DEFAULT_CRL + debug("CRL Data block is bigger than allocated block (%u bytes)",(unsigned int) size); + return 0; } - if(!hSession->ssl.crl) + debug("Received %u bytes", (unsigned int) realsize); + + memcpy(&(data->contents[data->length]),contents,realsize); + data->length += realsize; + + return realsize; +} + +#endif // HAVE_LIBCURL + + +X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) +{ + X509_CRL * crl = NULL; + const char * consturl = lib3270_get_crl_url(hSession); + + if(!(consturl && *consturl)) { + message->error = hSession->ssl.error = 0; + message->title = N_( "Security error" ); + message->text = N_( "Can't open CRL File" ); + message->description = N_("The URL for the CRL is undefined or empty"); return NULL; } - trace_ssl(hSession, "crl=%s",hSession->ssl.crl); + trace_ssl(hSession, "crl=%s",consturl); - if(strncasecmp(hSession->ssl.crl,"file://",7) == 0) + if(strncasecmp(consturl,"file://",7) == 0) { - lib3270_autoptr(FILE) hCRL = fopen(hSession->ssl.crl+7,"r"); + lib3270_autoptr(FILE) hCRL = fopen(consturl+7,"r"); if(!hCRL) { @@ -127,188 +143,133 @@ X509_CRL * lib3270_get_X509_CRL(H3270 *hSession, SSL_ERROR_MESSAGE * message) message->title = N_( "Security error" ); message->text = N_( "Can't open CRL File" ); message->description = strerror(errno); - lib3270_write_log(hSession,"ssl","Can't open %s: %s",hSession->ssl.crl,message->description); + lib3270_write_log(hSession,"ssl","Can't open %s: %s",consturl,message->description); return NULL; } - lib3270_write_log(hSession,"ssl","Loading CRL from %s",hSession->ssl.crl+7); + lib3270_write_log(hSession,"ssl","Loading CRL from %s",consturl+7); d2i_X509_CRL_fp(hCRL, &crl); } -#ifdef HAVE_LDAP - else if(strncasecmp(hSession->ssl.crl,"ldap",4) == 0) + else { - int rc; - lib3270_autoptr(char) url = strdup(hSession->ssl.crl); +#ifdef HAVE_LIBCURL - char * attrs[] = { NULL, NULL }; - char * base = NULL; + // Use CURL to download the CRL + lib3270_autoptr(CURLDATA) crl_data = lib3270_malloc(sizeof(CURLDATA)); + lib3270_autoptr(CURL) hCurl = curl_easy_init(); - const struct _args - { - const char * name; - char ** value; - } - args[] = - { - { "attr", &attrs[0] }, - { "base", &base } - }; - - // Get arguments - size_t arg; - char * ptr = strchr(url,'?'); - while(ptr) + memset(crl_data,0,sizeof(CURLDATA)); + crl_data->message = message; + + if(hCurl) { - *(ptr++) = 0; - char *value = strchr(ptr,'='); - if(!value) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Invalid argument format" ); - message->description = "The URL argument should be in the format name=value"; - return NULL; - } + CURLcode res; + + curl_easy_setopt(hCurl, CURLOPT_URL, consturl); + curl_easy_setopt(hCurl, CURLOPT_FOLLOWLOCATION, 1L); - *(value++) = 0; + curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, internal_curl_write_callback); + curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void *) crl_data); - debug("%s=%s",ptr,value); + res = curl_easy_perform(hCurl); - for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++) + if(res != CURLE_OK) { - if(!strcasecmp(ptr,args[arg].name)) - { - *args[arg].value = value; - debug("%s=\"%s\"",args[arg].name,*args[arg].value); - } + message->error = hSession->ssl.error = 0; + message->title = N_( "Security error" ); + message->text = N_( "Error loading CRL" ); + message->description = curl_easy_strerror(res); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); + return NULL; } - ptr = strchr(value,'&'); - } - - // Do we get all the required arguments? - for(arg = 0; arg < (sizeof(args)/sizeof(args[0])); arg++) - { - if(!*args[arg].value) + char *ct = NULL; + res = curl_easy_getinfo(hCurl, CURLINFO_CONTENT_TYPE, &ct); + if(res != CURLE_OK) { message->error = hSession->ssl.error = 0; message->title = N_( "Security error" ); - message->text = N_( "Can't set LDAP query" ); - message->description = N_("Insuficient arguments"); - lib3270_write_log(hSession,"ssl","%s: Required argument \"%s\" is missing",url, args[arg].name); + message->text = N_( "Error loading CRL" ); + message->description = curl_easy_strerror(res); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); return NULL; } - } - // Do LDAP Query - LDAP __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAP))) *ld = NULL; - BerElement __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_BerElement))) * ber = NULL; + debug("content-type: %s",ct); - rc = ldap_initialize(&ld, url); - if(rc != LDAP_SUCCESS) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't initialize LDAP" ); - message->description = ldap_err2string(rc); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + if(ct) + { + const unsigned char * data = crl_data->contents; - unsigned long version = LDAP_VERSION3; - rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,(void *) &version); - if(rc != LDAP_SUCCESS) { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't set LDAP version" ); - message->description = ldap_err2string(rc); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + if(strcasecmp(ct,"application/pkix-crl") == 0) + { + // CRL File, convert it + if(!d2i_X509_CRL(&crl, &data, crl_data->length)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = N_( "Security error" ); + message->text = N_( "Got an invalid CRL from server" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + return NULL; + } + } + else + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = N_( "Security error" ); + message->text = N_( "Got an invalid CRL from server" ); + lib3270_write_log(hSession,"ssl","%s: content-type unexpected: \"%s\"",consturl, ct); + return NULL; + } + } + else if(strncasecmp(consturl,"ldap://",7) == 0) + { + // It's an LDAP query, assumes a base64 data. + char * data = strstr((char *) crl_data->contents,":: "); + if(!data) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = N_( "Security error" ); + message->text = N_( "Got an invalid CRL from LDAP server" ); + lib3270_write_log(hSession,"ssl","%s: invalid format:\n%s\n",consturl, crl_data->contents); + return NULL; + } + data += 3; - rc = ldap_simple_bind_s(ld, "", ""); - if(rc != LDAP_SUCCESS) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't bind to LDAP server" ); - message->description = ldap_err2string(rc); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + debug("\n%s\nlength=%u",data,(unsigned int) strlen(data)); - lib3270_autoptr(LDAPMessage) results = NULL; - rc = ldap_search_ext_s( - ld, // Specifies the LDAP pointer returned by a previous call to ldap_init(), ldap_ssl_init(), or ldap_open(). - base, // Specifies the DN of the entry at which to start the search. - LDAP_SCOPE_BASE, // Specifies the scope of the search. - NULL, // Specifies a string representation of the filter to apply in the search. - (char **) &attrs, // Specifies a null-terminated array of character string attribute types to return from entries that match filter. - 0, // Should be set to 1 to request attribute types only. Set to 0 to request both attributes types and attribute values. - NULL, - NULL, - NULL, - 0, - &results - ); - - if(rc != LDAP_SUCCESS) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't search LDAP server" ); - message->description = ldap_err2string(rc); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + lib3270_autoptr(BIO) bio = BIO_new_mem_buf(data,-1); - char __attribute__ ((__cleanup__(lib3270_autoptr_cleanup_LDAPPTR))) *attr = ldap_first_attribute(ld, results, &ber); - if(!attr) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't get LDAP attribute" ); - message->description = N_("Search did not produce any attributes."); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + BIO * b64 = BIO_new(BIO_f_base64()); + bio = BIO_push(b64, bio); - struct berval ** value = ldap_get_values_len(ld, results, attr); - if(!value) - { - message->error = hSession->ssl.error = 0; - message->title = N_( "Security error" ); - message->text = N_( "Can't get LDAP attribute" ); - message->description = N_("Search did not produce any values."); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->description); - return NULL; - } + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - // 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_bio(bio, &crl)) + { + message->error = hSession->ssl.error = ERR_get_error(); + message->title = N_( "Security error" ); + message->text = N_( "Got an invalid CRL from server" ); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->text); + return NULL; + } - if(!d2i_X509_CRL(&crl, &crl_data, value[0]->bv_len)) - { - message->error = hSession->ssl.error = ERR_get_error(); - message->title = N_( "Security error" ); - message->text = N_( "Can't get CRL from LDAP Search" ); - lib3270_write_log(hSession,"ssl","%s: %s",url, message->text); - } + } - ldap_value_free_len(value); + } +#else + // Can't get CRL. - } -#endif // HAVE_LDAP - else - { message->error = hSession->ssl.error = 0; message->title = N_( "Security error" ); message->text = N_( "Unexpected or invalid CRL URL" ); message->description = N_("The URL scheme is unknown"); - lib3270_write_log(hSession,"ssl","%s: %s",hSession->ssl.crl, message->description); + lib3270_write_log(hSession,"ssl","%s: %s",consturl, message->description); return NULL; +#endif // HAVE_LIBCURL + } return crl; -- libgit2 0.21.2