/******************************************************************************* * 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 Anas Nashif * @author Vadim Revyakin */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "u/libu.h" #include "wsman-client-transport.h" #include "wsman-soap.h" #include "wsman-client.h" static char *auth_methods[] = { _WS_NO_AUTH, _WS_BASIC_AUTH, _WS_DIGEST_AUTH, _WS_PASS_AUTH, _WS_NTLM_AUTH, _WS_GSSNEGOTIATE_AUTH, NULL, }; extern void wsmc_handler(WsManClient * cl, WsXmlDocH rqstDoc, void *user_data); #ifdef BENCHMARK static long long transfer_time = 0; #endif int wsman_send_request(WsManClient * cl, WsXmlDocH request) { int ret = 0; #ifdef BENCHMARK struct timeval tv0, tv1; long long t0, t1; #endif if (wsmc_lock(cl) != 0 ) { error("Client busy"); return 1; } wsmc_reinit_conn(cl); #ifdef BENCHMARK gettimeofday(&tv0, NULL); #endif wsmc_handler(cl, request, NULL); if (cl->last_error != WS_LASTERR_OK) { warning("Couldn't send request to client: %s\n", cl->fault_string); ret = 1; } #ifdef BENCHMARK gettimeofday(&tv1, NULL); t0 = tv0.tv_sec * 10000000 + tv0.tv_usec; t1 = tv1.tv_sec * 10000000 + tv1.tv_usec; transfer_time += t1 - t0; #endif wsmc_unlock(cl); return ret; } #ifdef BENCHMARK long long get_transfer_time() { long long l = transfer_time; transfer_time = 0; return l; } #endif const char *wsmc_transport_get_auth_name(wsman_auth_type_t auth) { switch (auth) { case WS_NO_AUTH: return _WS_NO_AUTH; case WS_BASIC_AUTH: return _WS_BASIC_AUTH; case WS_DIGEST_AUTH: return _WS_DIGEST_AUTH; case WS_PASS_AUTH: return _WS_PASS_AUTH; case WS_NTLM_AUTH: return _WS_NTLM_AUTH; case WS_GSSNEGOTIATE_AUTH: return _WS_GSSNEGOTIATE_AUTH; default:; } return "Unknown"; } void wsmc_transport_set_auth_request_func(WsManClient * cl, wsman_auth_request_func_t f) { cl->authentication.auth_request_func = f; } void wsman_transport_set_agent(WsManClient * cl, const char *arg) { u_free(cl->user_agent); cl->user_agent = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_agent(WsManClient * cl) { if (cl->user_agent) return u_strdup(cl->user_agent); else return u_strdup(DEFAULT_USER_AGENT); } void wsman_transport_set_proxy(WsManClient * cl, const char *arg) { u_free(cl->proxy_data.proxy); cl->proxy_data.proxy = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_proxy(WsManClient *cl) { return cl->proxy_data.proxy ? u_strdup( cl->proxy_data.proxy ) : NULL; } void wsman_transport_set_userName(WsManClient * cl, const char *arg) { u_free(cl->data.user); cl->data.user = arg ? u_strdup(arg) : NULL; } char *wsman_transport_get_userName(WsManClient * cl) { return cl->data.user ? u_strdup(cl->data.user) : NULL; } void wsman_transport_set_password(WsManClient * cl, const char *arg) { u_free(cl->data.pwd); cl->data.pwd = arg ? u_strdup(arg) : NULL; } char *wsman_transport_get_password(WsManClient * cl) { return cl->data.pwd ? u_strdup(cl->data.pwd) : NULL; } void wsman_transport_set_proxyauth(WsManClient * cl, const char *arg) { u_free(cl->proxy_data.proxy_auth); cl->proxy_data.proxy_auth = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_proxyauth(WsManClient *cl) { return cl->proxy_data.proxy_auth ? u_strdup( cl->proxy_data.proxy_auth ) : NULL; } unsigned long wsman_transport_get_timeout(WsManClient * cl) { return cl->transport_timeout; } void wsman_transport_set_timeout(WsManClient * cl, unsigned long arg) { cl->transport_timeout = arg; } char *wsman_transport_get_auth_method(WsManClient * cl) { return cl->authentication.method ? u_strdup(cl->authentication.method) : NULL; } void wsman_transport_set_auth_method(WsManClient * cl, const char *arg) { u_free(cl->authentication.method); cl->authentication.method = arg ? u_strdup( arg ) : NULL; } int wsman_is_auth_method(WsManClient * cl, int method) { if (cl->authentication.method == NULL) { return 1; } if (method >= WS_MAX_AUTH) { return 0; } return (!strncasecmp (cl->authentication.method, auth_methods[method], strlen(cl->authentication.method))); } wsman_auth_type_t wsmc_transport_get_auth_value(WsManClient * cl) { char *m = cl->authentication.method; wsman_auth_type_t i; if (m == NULL) { return WS_NO_AUTH; } for (i = 0; auth_methods[i] != NULL; i++) { if (!strcasecmp(m, auth_methods[i])) { return i; } } return WS_MAX_AUTH; } void wsman_transport_set_verify_peer(WsManClient * cl, unsigned int arg) { cl->authentication.verify_peer = arg; } unsigned int wsman_transport_get_verify_peer(WsManClient *cl) { return cl->authentication.verify_peer; } void wsman_transport_set_verify_host(WsManClient * cl, unsigned int arg) { cl->authentication.verify_host = arg; } unsigned int wsman_transport_get_verify_host(WsManClient *cl) { return cl->authentication.verify_host; } void wsman_transport_set_crlcheck(WsManClient * cl, unsigned int arg) { cl->authentication.crl_check = arg; } unsigned int wsman_transport_get_crlcheck(WsManClient * cl) { return cl->authentication.crl_check; } #ifndef _WIN32 void wsman_transport_set_crlfile(WsManClient * cl, const char *arg) { u_free(cl->authentication.crl_file); cl->authentication.crl_file = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_crlfile(WsManClient *cl) { return cl->authentication.crl_file ? u_strdup(cl->authentication.crl_file) : NULL; } #endif void wsman_transport_set_cainfo(WsManClient * cl, const char *arg) { u_free(cl->authentication.cainfo); cl->authentication.cainfo = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_cainfo(WsManClient *cl) { return cl->authentication.cainfo ? u_strdup( cl->authentication.cainfo ) : NULL; } static int hexadecimal2raw(const char *str, unsigned char *dest, int len) { int i = 0; unsigned char v1 =0 , v2 = 0; while(*str != 0 && *(str+1) != 0 && i < len) { if(*str <= '9' && *str >= '0') v1 = *str - '0'; else if(*str <= 'f' && *str >= 'a') v1 = *str - 'a' + 10; else if(*str <= 'F' && *str >= 'A') v1 = *str - 'A' + 10; v1 <<= 4; str++; if(*str <= '9' && *str >= '0') v2 = *str - '0'; else if(*str <= 'f' && *str >= 'a') v2 = *str - 'a' + 10; else if(*str <= 'F' && *str >= 'A') v2 = *str - 'A' + 10; str++; dest[i] = v1 + v2; i++; } return i; } static char * raw2hexadecimal(unsigned char *dest, int len) { int i = 0; char v; char * str = calloc(1, len*2+1); char * p = str; if(str == NULL) return str; while(i < len) { v = (dest[i] & 0xf0) >> 4; if(v <= 9) *str = '0' + v; else *str = 'a' + v - 10; str++; v = dest[i] & 0x0f; if(v <= 9) *str = '0' + v; else *str = 'a' + v - 10; str++; i++; } return p; } void wsman_transport_set_certhumbprint(WsManClient *cl, const char *arg) { if(arg == NULL) return; hexadecimal2raw(arg, cl->authentication.certificatethumbprint, 20); } char *wsman_transport_get_certhumbprint(WsManClient *cl) { return raw2hexadecimal(cl->authentication.certificatethumbprint, 20); } void wsman_transport_set_capath(WsManClient *cl, const char *arg) { u_free(cl->authentication.capath); cl->authentication.capath = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_capath(WsManClient *cl) { return cl->authentication.capath ? u_strdup( cl->authentication.capath ) : NULL; } void wsman_transport_set_caoid(WsManClient *cl, const char *arg) { u_free(cl->authentication.caoid); cl->authentication.caoid = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_caoid(WsManClient *cl) { return cl->authentication.caoid ? u_strdup( cl->authentication.caoid ) : NULL; } #ifdef _WIN32 void wsman_transport_set_calocal(WsManClient *cl, BOOL local) { cl->authentication.calocal = local; } BOOL wsman_transport_get_calocal(WsManClient *cl) { return cl->authentication.calocal; } #endif char *wsman_transport_get_proxy_username(WsManClient *cl) { return cl->proxy_data.proxy_username ? u_strdup(cl->proxy_data.proxy_username) : NULL; } void wsman_transport_set_proxy_username(WsManClient *cl, const char *proxy_username ) { u_free(cl->proxy_data.proxy_username); cl->proxy_data.proxy_username = proxy_username ? u_strdup(proxy_username) : NULL; } char *wsman_transport_get_proxy_password(WsManClient *cl) { return cl->proxy_data.proxy_password ? u_strdup(cl->proxy_data.proxy_password) : NULL; } void wsman_transport_set_proxy_password(WsManClient *cl, const char *proxy_password ) { u_free(cl->proxy_data.proxy_password); cl->proxy_data.proxy_password = proxy_password ? u_strdup(proxy_password) : NULL; } void wsman_transport_set_cert(WsManClient * cl, const char *arg) { u_free(cl->authentication.sslcert); cl->authentication.sslcert = arg ? u_strdup( arg ) : NULL; } char *wsman_transport_get_cert(WsManClient *cl) { return cl->authentication.sslcert ? u_strdup( cl->authentication.sslcert ) : NULL; } void wsman_transport_set_key(WsManClient *cl, const char *key) { u_free(cl->authentication.sslkey); cl->authentication.sslkey = key ? u_strdup( key ) : NULL; } char *wsman_transport_get_key(WsManClient *cl) { return cl->authentication.sslkey ? u_strdup( cl->authentication.sslkey ) : NULL; } char *wsman_transport_get_last_error_string(WS_LASTERR_Code err) { switch (err) { case WS_LASTERR_OK: return "Everything OK"; case WS_LASTERR_FAILED_INIT: return "Transport initialization failed"; case WS_LASTERR_UNSUPPORTED_PROTOCOL: return "Unsupported protocol"; case WS_LASTERR_URL_MALFORMAT: return "URL malformat"; case WS_LASTERR_COULDNT_RESOLVE_PROXY: return "Could not resolve proxy"; case WS_LASTERR_COULDNT_RESOLVE_HOST: return "Could not resolve host"; case WS_LASTERR_COULDNT_CONNECT: return "Could not connect"; case WS_LASTERR_HTTP_RETURNED_ERROR: return "HTTP returned error"; case WS_LASTERR_WRITE_ERROR: return "Write error"; case WS_LASTERR_READ_ERROR: return "Read error"; case WS_LASTERR_OUT_OF_MEMORY: return "Could not alloc memory"; case WS_LASTERR_OPERATION_TIMEOUTED: return "Operation timeout reached"; case WS_LASTERR_HTTP_POST_ERROR: return "HTTP POST error"; case WS_LASTERR_BAD_DOWNLOAD_RESUME: return "Could not resume download"; case WS_LASTERR_TOO_MANY_REDIRECTS: return "Catch endless re-direct loop"; case WS_LASTERR_SSL_CONNECT_ERROR: return "SSL connection error"; case WS_LASTERR_SSL_PEER_CERTIFICATE: return "Peer's certificate wasn't OK"; case WS_LASTERR_SSL_ENGINE_NOTFOUND: return "SSL crypto engine not found"; case WS_LASTERR_SSL_ENGINE_SETFAILED: return "Can't set SSL crypto engine default"; case WS_LASTERR_SSL_CERTPROBLEM: return "Problem with the local certificate"; case WS_LASTERR_SSL_CACERT: return "Problem with the CA certificate"; case WS_LASTERR_SSL_ENGINE_INITFAILED: return "Failed to initialise SSL engine"; case WS_LASTERR_SEND_ERROR: return "Failed sending network data"; case WS_LASTERR_RECV_ERROR: return "Failure in receiving network data"; case WS_LASTERR_BAD_CONTENT_ENCODING: return "Unrecognized transfer encoding"; case WS_LASTERR_LOGIN_DENIED: return "User, password or similar was not accepted"; case WS_LASTERR_CURL_BAD_FUNCTION_ARG: return "Internal error: Wrong function argument in call to CURL"; default: return "Unrecognized error"; } }