/*******************************************************************************
 * 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;
	EVP_MD                                  *tempDigest;

	unsigned char   tempFingerprint[EVP_MAX_MD_SIZE];
	unsigned int      tempFingerprintLen;
	tempDigest = (EVP_MD*)EVP_sha1( );

	X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
	if(!cert)
		return 0;

	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;
}


