/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  - Neither the name of Intel Corp. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

/**
 * @author Vadim Revyakin
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <curl/curl.h>
#include <curl/easy.h>

#ifdef ENABLE_EVENTING_SUPPORT
#include <openssl/opensslv.h>
#include <openssl/ssl.h>
#endif

#include "u/libu.h"
#include "wsman-types.h"
#include "wsman-client.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-debug.h"
#include "wsman-client-transport.h"

#define DEFAULT_TRANSFER_LEN 32000

#ifndef CURLOPT_CRLFILE
	#define CURLOPT_CRLFILE 10169
#endif
#ifndef CURLE_SSL_CRL_BADFILE
	#define CURLE_SSL_CRL_BADFILE 82
#endif


extern wsman_auth_request_func_t request_func;
void wsmc_handler( WsManClient *cl, WsXmlDocH rqstDoc, void* user_data);

static pthread_mutex_t curl_mutex = PTHREAD_MUTEX_INITIALIZER;


static long
reauthenticate(WsManClient *cl,
        long auth_set, long auth_avail, char **username, char **password)
{
	long choosen_auth = 0;
	wsman_auth_type_t ws_auth = WS_NO_AUTH;

	if (auth_avail &  CURLAUTH_GSSNEGOTIATE &&
			wsman_is_auth_method(cl, WS_GSSNEGOTIATE_AUTH)) {
		choosen_auth = CURLAUTH_GSSNEGOTIATE;
		ws_auth = WS_GSSNEGOTIATE_AUTH;
		goto REQUEST_PASSWORD;
	}
	if (auth_avail & CURLAUTH_DIGEST &&
			wsman_is_auth_method(cl, WS_DIGEST_AUTH)) {
		choosen_auth = CURLAUTH_DIGEST;
		ws_auth = WS_DIGEST_AUTH;
		goto REQUEST_PASSWORD;
	}
	if (auth_avail & CURLAUTH_NTLM &&
			wsman_is_auth_method(cl, WS_NTLM_AUTH)) {
		choosen_auth = CURLAUTH_NTLM;
		ws_auth = WS_NTLM_AUTH;
		goto REQUEST_PASSWORD;
	}
	if (auth_avail & CURLAUTH_BASIC &&
			wsman_is_auth_method(cl, WS_BASIC_AUTH)) {
		ws_auth = WS_BASIC_AUTH;
		choosen_auth = CURLAUTH_BASIC;
		goto REQUEST_PASSWORD;
	}

	debug("Client does not support authentication type 0x%04x"
			" acceptable by server\n", auth_avail);
	return 0;


REQUEST_PASSWORD:
	message("%s authentication is used",
			wsmc_transport_get_auth_name(ws_auth));
	if (auth_set == 0 && *username && *password) {
		// use existing username and password
		return choosen_auth;
	}

	if (cl->authentication.auth_request_func) {
		debug("Invoking Auth request callback");

		/* free the username and password as these are OUT params to the auth_request_func
		 * which the caller is expected to set
		 */
		if (*username) {
			u_free(*username);
			*username = NULL;
		}
		if (*password) {
			u_free(*password);
			*password = NULL;
		}
		cl->authentication.auth_request_func(cl, ws_auth, username, password);
	}
	else
		return 0;


	if (!(*username) || strlen(*username) == 0) {
		debug("No username. Authorization canceled");
		return 0;
	}
	return choosen_auth;
}


static WS_LASTERR_Code
convert_to_last_error(CURLcode r)
{
	switch (r) {
	case CURLE_OK:
		return WS_LASTERR_OK;
	case CURLE_FAILED_INIT:
		return WS_LASTERR_FAILED_INIT;
	case CURLE_UNSUPPORTED_PROTOCOL:
		return WS_LASTERR_UNSUPPORTED_PROTOCOL;
	case CURLE_URL_MALFORMAT:
		return WS_LASTERR_URL_MALFORMAT;
	case CURLE_COULDNT_RESOLVE_PROXY:
		return WS_LASTERR_COULDNT_RESOLVE_PROXY;
	case CURLE_COULDNT_RESOLVE_HOST:
		return WS_LASTERR_COULDNT_RESOLVE_HOST;
	case CURLE_COULDNT_CONNECT:
		return WS_LASTERR_COULDNT_CONNECT;
	case CURLE_HTTP_RETURNED_ERROR:
		return WS_LASTERR_HTTP_RETURNED_ERROR;
	case CURLE_WRITE_ERROR:
		return WS_LASTERR_WRITE_ERROR;
	case CURLE_READ_ERROR:
		return WS_LASTERR_READ_ERROR;
	case CURLE_OUT_OF_MEMORY:
		return WS_LASTERR_OUT_OF_MEMORY;
	case CURLE_OPERATION_TIMEOUTED:
		return WS_LASTERR_OPERATION_TIMEOUTED;
	case CURLE_HTTP_POST_ERROR:
		return WS_LASTERR_HTTP_POST_ERROR;
	case CURLE_BAD_DOWNLOAD_RESUME:
		return WS_LASTERR_BAD_DOWNLOAD_RESUME;
	case CURLE_TOO_MANY_REDIRECTS:
		return WS_LASTERR_TOO_MANY_REDIRECTS;
	case CURLE_SSL_CONNECT_ERROR:
		return WS_LASTERR_SSL_CONNECT_ERROR;
        case CURLE_BAD_FUNCTION_ARGUMENT:
                return WS_LASTERR_CURL_BAD_FUNCTION_ARG;
	case CURLE_SSL_PEER_CERTIFICATE:
		return WS_LASTERR_SSL_PEER_CERTIFICATE;
	case CURLE_SSL_ENGINE_NOTFOUND:
		return WS_LASTERR_SSL_ENGINE_NOTFOUND;
	case CURLE_SSL_ENGINE_SETFAILED:
		return WS_LASTERR_SSL_ENGINE_SETFAILED;
	case CURLE_SSL_CERTPROBLEM:
		return WS_LASTERR_SSL_CERTPROBLEM;
	case CURLE_SSL_CACERT:
		return WS_LASTERR_SSL_CACERT;
#if LIBCURL_VERSION_NUM > 0x70C01
	case CURLE_SSL_ENGINE_INITFAILED:
		return WS_LASTERR_SSL_ENGINE_INITFAILED;
#endif
	case CURLE_SEND_ERROR:
		return WS_LASTERR_SEND_ERROR;
	case CURLE_RECV_ERROR:
		return WS_LASTERR_RECV_ERROR;
	case CURLE_BAD_CONTENT_ENCODING:
		return WS_LASTERR_BAD_CONTENT_ENCODING;
#if LIBCURL_VERSION_NUM >= 0x70D01
	case CURLE_LOGIN_DENIED:
		return WS_LASTERR_LOGIN_DENIED;
#else
	/* Map 67 (same as CURLE_LOGIN_DENIED) got from OS that has lower version of CURL in which
	 * CURLE_LOGIN_DENIED is not defined. This way we get the same error code in case of login failure
	 */
	case 67:
		return WS_LASTERR_LOGIN_DENIED;
#endif
	case CURLE_SSL_CRL_BADFILE:
		return WS_LASTERR_BAD_CRL_FILE;

	default:
		return WS_LASTERR_OTHER_ERROR;
	}
	return WS_LASTERR_OTHER_ERROR;
}

static size_t
write_handler( void *ptr, size_t size, size_t nmemb, void *data)
{
	u_buf_t *buf = data;
	size_t len;

	len = size * nmemb;
	u_buf_append(buf, ptr, len);
	debug("write_handler: recieved %d bytes, all = %d\n", len, u_buf_len(buf));
	return len;
}

#ifdef ENABLE_EVENTING_SUPPORT
static int ssl_certificate_thumbprint_verify_callback(X509_STORE_CTX *ctx, void *arg)
{
	unsigned char *thumbprint = (unsigned char *)arg;
	X509 *cert = ctx->cert;
	EVP_MD                                  *tempDigest;

	unsigned char   tempFingerprint[EVP_MAX_MD_SIZE];
	unsigned int      tempFingerprintLen;
	tempDigest = (EVP_MD*)EVP_sha1( );
	if ( X509_digest(cert, tempDigest, tempFingerprint, &tempFingerprintLen ) <= 0)
		return 0;
	if(!memcmp(tempFingerprint, thumbprint, tempFingerprintLen))
		return 1;
	return 0;
}

static CURLcode
sslctxfun(CURL *curl, void *sslctx, void *parm)
{
	CURLcode r = CURLE_OK;
	SSL_CTX * ctx = (SSL_CTX *) sslctx ;
	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |  SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0 );
	SSL_CTX_set_cert_verify_callback(ctx, ssl_certificate_thumbprint_verify_callback, parm);
	return r;
}
#endif

static void *
init_curl_transport(WsManClient *cl)
{
	CURL *curl;
	CURLcode r = CURLE_OK;
        char *sslhack;
        long sslversion;
        dictionary *ini = iniparser_new(wsmc_get_conffile(cl));

#define curl_err(str)  debug("Error = %d (%s); %s", \
		r, curl_easy_strerror(r), str);
	curl = curl_easy_init();
	if (curl == NULL) {
		r = CURLE_FAILED_INIT;
		debug("Could not init easy curl");
		goto DONE;
	}
        // client:curlopt_nosignal
        if (ini) {
          int nosignal = iniparser_getint(ini, "client:curlopt_nosignal", 0);
          r = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, nosignal);
          if (r != 0) {
            curl_err("curl_easy_setopt(CURLOPT_NOSIGNAL) failed");
            goto DONE;
          }
        }
	debug("cl->authentication.verify_peer: %d", cl->authentication.verify_peer );
	// verify peer
	r = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, wsman_transport_get_verify_peer(cl)?1:0);
	if (r != 0) {
		curl_err("curl_easy_setopt(CURLOPT_SSL_VERIFYPEER) failed");
		goto DONE;
	}

	// verify host
	r = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, wsman_transport_get_verify_host(cl)?2:0);
	if (r != 0) {
		curl_err("curl_easy_setopt(CURLOPT_SSL_VERIFYHOST) failed");
		goto DONE;
	}

	r = curl_easy_setopt(curl, CURLOPT_PROXY, cl->proxy_data.proxy);
	if (r != 0) {
		curl_err("Could notcurl_easy_setopt(curl, CURLOPT_PROXY, ...)");
		goto DONE;
	}
	r = curl_easy_setopt(curl, CURLOPT_TIMEOUT, cl->transport_timeout);
	if (r != 0) {
		curl_err("Could notcurl_easy_setopt(curl, CURLOPT_TIMEOUT, ...)");
		goto DONE;
	}

	r = curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, cl->proxy_data.proxy_auth);
	if (r != 0) {
		curl_err("Could notcurl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, ...)");
		goto DONE;
	}
	
	if (0 != cl->authentication.verify_peer && 0 != cl->authentication.crl_check)
	{		
		if (cl->authentication.crl_file == NULL)
		{
			if (ini != NULL)
			{
			        char *crlfile = iniparser_getstr(ini, "client:crlfile");
				wsman_transport_set_crlfile(cl, crlfile);
			}
		}
		if (cl->authentication.crl_file != NULL)
		{
			debug("wsman-curl-client-transport.c: init_curl_transport() : CRL file = %s\n",cl->authentication.crl_file);
			r = curl_easy_setopt(curl, CURLOPT_CRLFILE, cl->authentication.crl_file);		
		}
		
	}

	if (cl->authentication.capath) {
		r = curl_easy_setopt(curl, CURLOPT_CAPATH, cl->authentication.capath);
		if (r != 0) {
			curl_err("Could not curl_easy_setopt(curl, CURLOPT_CAPATH, ..)");
			goto DONE;
		}
	}
	// cainfo
	if (cl->authentication.cainfo) {
		r = curl_easy_setopt(curl, CURLOPT_CAINFO, cl->authentication.cainfo);
		if (r != 0) {
			curl_err("Could not curl_easy_setopt(curl, CURLOPT_CAINFO, ..)");
			goto DONE;
		}
	}
	// certificate thumbprint
#ifdef ENABLE_EVENTING_SUPPORT
/*  Bug in e.g. Fedora: [ curl-Bugs-1924441 ] SSL callback option with NSS-linked libcurl */
#ifndef NO_SSL_CALLBACK
	else if (strlen((char *)cl->authentication.certificatethumbprint) > 0 && 0 != cl->authentication.verify_peer) {
		r = curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun);
		if(r != 0) {
			curl_err("Could not curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION)");
			goto DONE;
		}
		r = curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, (void *)cl->authentication.certificatethumbprint);
		if(r != 0) {
			curl_err("Could not curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA)");
			goto DONE;
		}
	}
#endif
#endif
	// sslkey
	r = curl_easy_setopt(curl, CURLOPT_SSLKEY, cl->authentication.sslkey);
	if (r != 0) {
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_SSLKEY, ..)");
		goto DONE;
	}
	// sslcert
	r = curl_easy_setopt(curl, CURLOPT_SSLCERT, cl->authentication.sslcert );
	if (r != 0) {
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_SSLCERT, ..)");
		goto DONE;
	}

        /* enforce specific ssl version if requested */
        sslhack = getenv("OPENWSMAN_CURL_TRANSPORT_SSLVERSION");
        if (sslhack == NULL) {
          sslversion = CURL_SSLVERSION_DEFAULT;
        } else if (!strcmp(sslhack,"tlsv1")) {
          sslversion = CURL_SSLVERSION_TLSv1;
        } else if (!strcmp(sslhack,"sslv2")) {
          sslversion = CURL_SSLVERSION_SSLv2;
        } else if (!strcmp(sslhack,"sslv3")) {
          sslversion = CURL_SSLVERSION_SSLv3;
#if LIBCURL_VERSION_NUM >= 0x072200
        } else if (!strcmp(sslhack,"tlsv1.0")) {
          sslversion = CURL_SSLVERSION_TLSv1_0;
        } else if (!strcmp(sslhack,"tlsv1.1")) {
          sslversion = CURL_SSLVERSION_TLSv1_1;
        } else if (!strcmp(sslhack,"tlsv1.2")) {
          sslversion = CURL_SSLVERSION_TLSv1_2;
#endif
        }
        else {
          sslversion = CURL_SSLVERSION_DEFAULT;
        }
        r = curl_easy_setopt(curl, CURLOPT_SSLVERSION, sslversion );
        if (r != 0) {
          curl_err("Could not curl_easy_setopt(curl, CURLOPT_SSLVERSION, ..)");
          goto DONE;
        }

        iniparser_free(ini);
	return (void *)curl;
 DONE:
	cl->last_error = convert_to_last_error(r);
	curl_easy_cleanup(curl);
        iniparser_free(ini);
	return NULL;
#undef curl_err
}

void
wsmc_handler( WsManClient *cl,
		WsXmlDocH rqstDoc,
		void* user_data)
{
#define curl_err(str)  debug("Error = %d (%s); %s", \
		r, curl_easy_strerror(r), str);
	WsManConnection *con = cl->connection;
	CURL *curl = NULL;
	CURLcode r;
	char *upwd = NULL;
	char *usag = NULL;
	struct curl_slist *headers=NULL;
	char *buf = NULL;
	int len;
	char *soapact_header = NULL;
	long http_code;
	long auth_avail = 0;
	char *_user = NULL, *_pass = NULL;
	u_buf_t *response = NULL;
	//char *soapaction;
	char *tmp_str = NULL;

	if (!cl->initialized && wsmc_transport_init(cl, NULL)) {
		cl->last_error = WS_LASTERR_FAILED_INIT;
		return;
	}
	if (cl->transport == NULL) {
		cl->transport = init_curl_transport(cl);
                if (cl->transport == NULL) {
                        return;
                }
	}
	curl = (CURL *)cl->transport;

	r = curl_easy_setopt(curl, CURLOPT_URL, cl->data.endpoint);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_URL, ...)");
		goto DONE;
	}

	r = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_handler);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ..)");
		goto DONE;
	}
	u_buf_create(&response);
	r = curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_WRITEDATA, ..)");
		goto DONE;
	}
	char content_type[64];
	snprintf(content_type, 64, "Content-Type: application/soap+xml;charset=%s", cl->content_encoding);
	headers = curl_slist_append(headers, content_type);
	tmp_str = wsman_transport_get_agent(cl);
	usag = malloc(12 + strlen(tmp_str) + 1);
	if (usag == NULL) {
		r = CURLE_OUT_OF_MEMORY;
		cl->fault_string = u_strdup("Could not malloc memory");
		curl_err("Could not malloc memory");
		goto DONE;
	}

	sprintf(usag, "User-Agent: %s", tmp_str);
	free(tmp_str);
	headers = curl_slist_append(headers, usag);

#if 0
	soapaction = ws_xml_get_xpath_value(rqstDoc, "/s:Envelope/s:Header/wsa:Action");
	if (soapaction) {
		soapact_header = malloc(12 + strlen(soapaction) + 1);
		if (soapact_header) {
			sprintf(soapact_header, "SOAPAction: %s", soapaction);
			headers = curl_slist_append(headers, soapact_header);
		}
		u_free(soapaction);
	}
#endif

	r = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_HTTPHEADER, ..)");
		goto DONE;
	}

	ws_xml_dump_memory_enc(rqstDoc, &buf, &len, cl->content_encoding);
#if 0
	int count = 0;
	while(count < len) {
		printf("%c",buf[count++]);
	}
#endif
	debug("*****set post buf len = %d******",len);
	r = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ..)");
		goto DONE;
	}
	r = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
	if (r != CURLE_OK) {
		cl->fault_string = u_strdup(curl_easy_strerror(r));
		curl_err("Could not curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, ..)");
		goto DONE;
	}

	int iDone = 0;
	while (1) {
		u_free(_user);
		u_free(_pass);
		_user = wsmc_get_user(cl);
		_pass = wsmc_get_password(cl);
		if (_user && _pass && cl->data.auth_set) {
			r = curl_easy_setopt(curl, CURLOPT_HTTPAUTH, cl->data.auth_set);
			if (r != CURLE_OK) {
				cl->fault_string = u_strdup(curl_easy_strerror(r));
				curl_err("curl_easy_setopt(CURLOPT_HTTPAUTH) failed");
				goto DONE;
			}
			u_free(upwd);
			upwd = u_strdup_printf(  "%s:%s", _user ,  _pass);
			if (!upwd) {
				r = CURLE_OUT_OF_MEMORY;
				cl->fault_string = u_strdup("Could not malloc memory");
				curl_err("Could not malloc memory");
				goto DONE;
			}
			r = curl_easy_setopt(curl, CURLOPT_USERPWD, upwd);
			if (r != CURLE_OK) {
				cl->fault_string = u_strdup(curl_easy_strerror(r));
				curl_err("curl_easy_setopt(curl, CURLOPT_USERPWD, ..) failed");
				goto DONE;
			}
		}

		if (wsman_debug_level_debugged(DEBUG_LEVEL_MESSAGE)) {
			curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
		}

		r = curl_easy_perform(curl);
		if (r != CURLE_OK) {
			cl->fault_string = u_strdup(curl_easy_strerror(r));
			curl_err("curl_easy_perform failed");
			goto DONE;
		}

		r = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
		if (r != CURLE_OK) {
			cl->fault_string = u_strdup(curl_easy_strerror(r));
			curl_err("curl_easy_getinfo(CURLINFO_RESPONSE_CODE) failed");
			goto DONE;
		}

		switch (http_code) 
		{
			case 200:
			case 400:
			case 500:
				// The resource was successfully retrieved or WSMan server 
				// returned a HTTP status code. You can use WinHttpReadData to 
				// read the contents of the server's response.
				iDone = 1;
				break;
			case 401:
				// The server requires authentication.
				break;
			default:
				// The status code does not indicate success.
				r = WS_LASTERR_OTHER_ERROR;
				iDone = 1;
				break;
		}

		if(iDone == 1) {
			break;
		}

		/* we are here because of authentication required */
		r = curl_easy_getinfo(curl, CURLINFO_HTTPAUTH_AVAIL, &auth_avail);
		if (r != CURLE_OK) {
			cl->fault_string = u_strdup(curl_easy_strerror(r));
			curl_err("curl_easy_getinfo(CURLINFO_HTTPAUTH_AVAIL) failed");
			goto DONE;
		}

		cl->data.auth_set = reauthenticate(cl, cl->data.auth_set, auth_avail,
                        &cl->data.user, &cl->data.pwd);
                u_buf_clear(response);
                if (cl->data.auth_set == 0) {
                    /* FIXME: user wants to cancel authentication */
#if LIBCURL_VERSION_NUM >= 0x70D01
                    r = CURLE_LOGIN_DENIED;
#else
					/* Map the login failure error to CURLE_LOGIN_DENIED (67) so that we
					 * get the same error code in case of login failure
					 */
					r = 67;
#endif
                    cl->fault_string = u_strdup(curl_easy_strerror(r));
                    curl_err("user/password wrong or empty.");
		    break;
                }
        }
#if 0
	unsigned char *mbbuf = NULL;
	iconv_t cd;
	if(strcmp(cl->content_encoding, "UTF-8")) {
                cd = iconv_open("UTF-8", cl->content_encoding);
                if(cd == -1) {
			cl->last_error = WS_LASTERR_BAD_CONTENT_ENCODING;
			goto DONE2;
                }
                mbbuf = u_zalloc(u_buf_len(response));
                size_t outbuf_len = u_buf_len(response);
                size_t inbuf_len = outbuf_len;
                char *inbuf = u_buf_ptr(response);
                char *outbuf = mbbuf;
                size_t coverted = iconv(cd, &inbuf, &inbuf_len, &outbuf, &outbuf_len);
		  iconv_close(cd);
                if( coverted == -1) {
			cl->last_error = WS_LASTERR_BAD_CONTENT_ENCODING;
			goto DONE2;
                }
                u_buf_append(con->response, mbbuf, u_buf_len(response) - inbuf_len);
        }
	u_free(mbbuf);
#endif
	u_buf_append(con->response, u_buf_ptr(response), u_buf_len(response));
DONE:
	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
	cl->response_code = http_code;
	cl->last_error = convert_to_last_error(r);

	debug("curl error code: %d.", r);
	debug("cl->response_code: %d.", cl->response_code);
	debug("cl->last_error code: %d.", cl->last_error);

	curl_slist_free_all(headers);
	u_buf_free(response);
	u_free(soapact_header);
	u_free(usag);
	u_free(upwd);
	u_free(_pass);
	u_free(_user);
#ifdef _WIN32
	ws_xml_free_memory(buf);
#else
	u_free(buf);
#endif

	return;
#undef curl_err

}


int wsmc_transport_init(WsManClient *cl, void *arg)
{
	CURLcode r;

	pthread_mutex_lock(&curl_mutex);
	if (cl->initialized) {
		pthread_mutex_unlock(&curl_mutex);
		return 0;
	}
	r = curl_global_init(CURL_GLOBAL_SSL | CURL_GLOBAL_WIN32);
	if (r == CURLE_OK) {
		cl->initialized = 1;
	}
	pthread_mutex_unlock(&curl_mutex);
	if (r != CURLE_OK) {
		debug("Error = %d (%s); Could not initialize curl globals",
				r, curl_easy_strerror(r));
	}
	return (r == CURLE_OK ? 0 : 1);
}

void wsmc_transport_fini(WsManClient *cl)
{
	pthread_mutex_lock(&curl_mutex);
	if (cl->initialized == 0 ) {
		pthread_mutex_unlock(&curl_mutex);
		return;
	}
	curl_global_cleanup();
	cl->initialized = 0;
	pthread_mutex_unlock(&curl_mutex);
	return;
}

void
wsman_transport_close_transport(WsManClient *cl)
{
	if (cl->transport != NULL) {
		curl_easy_cleanup((CURL *)cl->transport);
	}
	cl->transport = NULL;
}


