| /******************************************************************************* |
| * 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 |
| * @author Liang Hou |
| */ |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #ifdef HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #include <errno.h> |
| #include <time.h> |
| |
| #include <wsman-client.h> |
| #include <wsman-client-transport.h> |
| #include <wsman-debug.h> |
| #include <u/libu.h> |
| |
| #if __linux__ |
| extern char *getpass (const char *__prompt); |
| #endif |
| |
| static long int server_port = 0; |
| static char *cainfo = NULL; |
| static char *cert = NULL; |
| static char *sslkey = NULL; |
| static char *endpoint = NULL; |
| static char *username = NULL; |
| static char *password = NULL; |
| static char *server = "localhost"; |
| static char *agent = NULL; |
| static char *url_path = NULL; |
| static char *authentication_method = NULL; |
| static char noverify_peer = 0; |
| static char noverify_host = 0; |
| |
| static long int transport_timeout = 0; |
| static char *proxy = NULL; |
| static char *proxy_upwd = NULL; |
| |
| |
| static long int non_interactive = 0; |
| static long int debug_level = -1; |
| static char *encoding = NULL; |
| static char *test_case = NULL; |
| static long int enum_max_elements = 0; |
| char enum_optimize = 0; |
| char enum_estimate = 0; |
| char dump_request = 0; |
| char step = 0; |
| char cim_extensions = 0; |
| static char *enum_mode = NULL; |
| static char *binding_enum_mode = NULL; |
| static char *enum_context = NULL; |
| static char *event_delivery_mode = NULL; |
| static char *event_delivery_sec_mode = NULL; |
| static char *event_delivery_uri = NULL; |
| static long int event_subscription_expire = 0; |
| static long int event_heartbeat = 0; |
| static int event_sendbookmark =0; |
| static char *event_subscription_id = NULL; |
| static char *event_reference_properties = NULL; |
| static char *event_username = NULL; |
| static char *event_password = NULL; |
| static char *event_thumbprint = NULL; |
| |
| static char *cim_namespace = NULL; |
| static char *fragment = NULL; |
| static char *wsm_filter = NULL; |
| static char *wsm_dialect = NULL; |
| static char *input = NULL; |
| |
| static unsigned long operation_timeout = 0; |
| static unsigned long max_envelope_size = 0; |
| |
| static char *_action = NULL; |
| static char *config_file = NULL; |
| static char *output_file = NULL; |
| static char *resource_uri_opt = NULL; |
| static char *invoke_method = NULL; |
| static char **properties = NULL; |
| |
| struct _WsActions { |
| char *action; |
| int value; |
| }; |
| typedef struct _WsActions WsActions; |
| |
| WsActions action_data[] = { |
| {"get", WSMAN_ACTION_TRANSFER_GET}, |
| {"put", WSMAN_ACTION_TRANSFER_PUT}, |
| {"create", WSMAN_ACTION_TRANSFER_CREATE}, |
| {"delete", WSMAN_ACTION_TRANSFER_DELETE}, |
| {"enumerate", WSMAN_ACTION_ENUMERATION}, |
| {"pull", WSMAN_ACTION_PULL}, |
| {"release", WSMAN_ACTION_RELEASE}, |
| {"invoke", WSMAN_ACTION_CUSTOM}, |
| {"identify", WSMAN_ACTION_IDENTIFY}, |
| {"anonid", WSMAN_ACTION_ANON_IDENTIFY}, |
| {"subscribe", WSMAN_ACTION_SUBSCRIBE}, |
| {"unsubscribe", WSMAN_ACTION_UNSUBSCRIBE}, |
| {"renew", WSMAN_ACTION_RENEW}, |
| {"associators", WSMAN_ACTION_ASSOCIATORS}, |
| {"references", WSMAN_ACTION_REFERENCES}, |
| {"test", WSMAN_ACTION_TEST}, |
| {NULL, 0}, |
| }; |
| |
| WsActions delivery_mode[] = { |
| {"push", WSMAN_DELIVERY_PUSH}, |
| {"pushwithack", WSMAN_DELIVERY_PUSHWITHACK}, |
| {"events", WSMAN_DELIVERY_EVENTS}, |
| {"pull", WSMAN_DELIVERY_PULL}, |
| {NULL, 0} |
| }; |
| |
| WsActions delivery_sec_mode[] = { |
| {"httpbasic", WSMAN_DELIVERY_SEC_HTTP_BASIC}, |
| {"httpdigest", WSMAN_DELIVERY_SEC_HTTP_DIGEST}, |
| {"httpsbasic", WSMAN_DELIVERY_SEC_HTTPS_BASIC}, |
| {"httpsdigest", WSMAN_DELIVERY_SEC_HTTPS_DIGEST}, |
| {"httpsmutual", WSMAN_DELIVERY_SEC_HTTPS_MUTUAL}, |
| {"httpsmutualbasic", WSMAN_DELIVERY_SEC_HTTPS_MUTUAL_BASIC}, |
| {"httpsmutualdigest", WSMAN_DELIVERY_SEC_HTTPS_MUTUAL_DIGEST}, |
| {NULL, 0} |
| }; |
| |
| static int wsman_options_get_action(void) |
| { |
| int op = 0; |
| int i; |
| for (i = 0; action_data[i].action != NULL; i++) { |
| if (strcmp(action_data[i].action, _action) == 0) { |
| op = action_data[i].value; |
| break; |
| } |
| } |
| return op; |
| } |
| |
| static char wsman_parse_options(int argc, char **argv) |
| { |
| char retval = 0; |
| u_error_t *error = NULL; |
| char my_version = 0; |
| |
| u_option_entry_t options[] = { |
| {"non-interactive", 0, U_OPTION_ARG_NONE, &non_interactive, |
| "Non interactive mode, don't ask for credentials", NULL}, |
| {"version", 'q', U_OPTION_ARG_NONE, &my_version, |
| "Display application version", NULL}, |
| {"debug", 'd', U_OPTION_ARG_INT, &debug_level, |
| "Set the verbosity of debugging output.", "1-6"}, |
| {"encoding", 'j', U_OPTION_ARG_STRING, &encoding, |
| "Set request message encoding"}, |
| {"cacert", 'c', U_OPTION_ARG_STRING, &cainfo, |
| "Certificate file to verify the peer", "<filename>"}, |
| {"cert", 'A', U_OPTION_ARG_STRING, &cert, |
| "Certificate file. The certificate must be in PEM format.", "<filename>"}, |
| {"sslkey", 'K', U_OPTION_ARG_STRING, &sslkey, |
| "SSL Key.", "<key>"}, |
| {"username", 'u', U_OPTION_ARG_STRING, &username, |
| "User name", "<username>"}, |
| {"path", 'g', U_OPTION_ARG_STRING, &url_path, |
| "Service Path (default: 'wsman')", "<path>"}, |
| {"input", 'J', U_OPTION_ARG_STRING, &input, |
| "File with resource for Create and Put operations in XML, can be a SOAP envelope", |
| "<filename>"}, |
| {"password", 'p', U_OPTION_ARG_STRING, &password, |
| "User Password", "<password>"}, |
| {"hostname", 'h', U_OPTION_ARG_STRING, &server, |
| "Host name", "<hostname>"}, |
| {"endpoint", 'b', U_OPTION_ARG_STRING, &endpoint, |
| "End point", "<url>"}, |
| {"port", 'P', U_OPTION_ARG_INT, &server_port, |
| "Server Port", "<port>"}, |
| {"proxy", 'X', U_OPTION_ARG_STRING, &proxy, |
| "Proxy name", "<proxy>"}, |
| {"proxyauth", 'Y', U_OPTION_ARG_STRING, &proxy_upwd, |
| "Proxy user:pwd", "<proxyauth>"}, |
| {"auth", 'y', U_OPTION_ARG_STRING, &authentication_method, |
| "Authentication Method", "<basic|digest|gss>"}, |
| {"method", 'a', U_OPTION_ARG_STRING, &invoke_method, |
| "Method (Works only with 'invoke')", "<custom method>"}, |
| {"prop", 'k', U_OPTION_ARG_STRING_ARRAY, &properties, |
| "Properties with key value pairs (For 'put', 'invoke' and 'create')", |
| "<key=val>"}, |
| {"config-file", 'C', U_OPTION_ARG_STRING, &config_file, |
| "Alternate configuration file", "<file>"}, |
| {"out-file", 'O', U_OPTION_ARG_STRING, &output_file, |
| "Write output to file", "<file>"}, |
| {"noverifypeer", 'V', U_OPTION_ARG_NONE, &noverify_peer, |
| "Not to verify peer certificate", NULL}, |
| {"noverifyhost", 'v', U_OPTION_ARG_NONE, &noverify_host, |
| "Not to verify hostname", NULL}, |
| {"transport-timeout", 'I', U_OPTION_ARG_INT, &transport_timeout, |
| "Transport timeout in seconds", "<time in sec>"}, |
| {NULL} |
| }; |
| |
| |
| |
| u_option_entry_t request_options[] = { |
| {"filter", 'x', U_OPTION_ARG_STRING, &wsm_filter, |
| "Filter", "<filter>"}, |
| {"dialect", 'D', U_OPTION_ARG_STRING, &wsm_dialect, |
| "Filter Dialect", "<dialect>"}, |
| {"operation-timeout", 't', U_OPTION_ARG_INT, &operation_timeout, |
| "Operation timeout in milliseconds", "<time in msec>"}, |
| {"max-envelope-size", 'e', U_OPTION_ARG_INT, |
| &max_envelope_size, |
| "maximal envelope size", "<size>"}, |
| {"fragment", 'F', U_OPTION_ARG_STRING, &fragment, |
| "Fragment (Supported Dialects: XPATH)", "<fragment>"}, |
| {NULL} |
| }; |
| |
| u_option_entry_t enum_options[] = { |
| |
| {"max-elements", 'm', U_OPTION_ARG_INT, &enum_max_elements, |
| "Max Elements Per Pull/Optimized Enumeration", |
| "<max number of elements>"}, |
| {"optimize", 'o', U_OPTION_ARG_NONE, &enum_optimize, |
| "Optimize enumeration results", NULL}, |
| {"estimate-count", 'E', U_OPTION_ARG_NONE, &enum_estimate, |
| "Return estimation of total items", NULL}, |
| {"enum-mode", 'M', U_OPTION_ARG_STRING, &enum_mode, |
| "Enumeration Mode", "epr|objepr"}, |
| {"enum-context", 'U', U_OPTION_ARG_STRING, &enum_context, |
| "Enumeration Context (For use with Pull and Release)", |
| "<enum context>"}, |
| {NULL} |
| }; |
| |
| u_option_entry_t event_options[] = { |
| {"delivery-mode", 'G', U_OPTION_ARG_STRING, &event_delivery_mode, |
| "Four delivery modes available: push/pushwithack/events/pull", |
| "<mode>"}, |
| {"delivery-sec-mode", 's', U_OPTION_ARG_STRING, &event_delivery_sec_mode, |
| "Four delivery modes available: httpbasic/httpdigest/httpsbasic/httpsdigest/httpsmutual/httpsmutualbasic/httpsmutualdigest", |
| "<mode>"}, |
| {"delivery-username", 'n', U_OPTION_ARG_STRING, &event_username, |
| "username for the eventing receiver", |
| "<username>"}, |
| {"delivery-password", 'z', U_OPTION_ARG_STRING, &event_password, |
| "password for the eventing receiver", |
| "<password>"}, |
| {"delivery-thumbprint", 'Y', U_OPTION_ARG_STRING, &event_thumbprint, |
| "ceritificate thumbprint of the eventing receiver", |
| "<thumbprint>"}, |
| {"notification-uri", 'Z', U_OPTION_ARG_STRING, &event_delivery_uri, |
| "Where notifications are sent", |
| "<uri>"}, |
| {"subscription-expiry-time", 'r', U_OPTION_ARG_INT, &event_subscription_expire, |
| "subscription expiry time in seconds", |
| "<seconds>"}, |
| {"heartbeat",'H', U_OPTION_ARG_INT, &event_heartbeat, |
| "Send hearbeat in an interval", |
| "<seconds>"}, |
| {"bookmark", 'l', U_OPTION_ARG_NONE, &event_sendbookmark, |
| "Send bookmark",NULL}, |
| {"subscription-identifier", 'i', U_OPTION_ARG_STRING, &event_subscription_id, |
| "Used to specify which subscription", |
| "<uuid:XXX>"}, |
| {"event-reference-properties", 'L', U_OPTION_ARG_STRING, &event_reference_properties, |
| "Event Reference Properties, correlation of Events with Subscription", |
| "<xml string>"}, |
| {NULL} |
| }; |
| |
| u_option_entry_t cim_options[] = { |
| |
| {"namespace", 'N', U_OPTION_ARG_STRING, &cim_namespace, |
| "CIM Namespace (default is root/cimv2)", "<namespace>"}, |
| {"binding-enum-mode", 'B', U_OPTION_ARG_STRING, |
| &binding_enum_mode, |
| "CIM binding Enumeration Mode", "none|include|exclude"}, |
| {"cim-extensions", 'T', U_OPTION_ARG_NONE, &cim_extensions, |
| "Show CIM Extensions", NULL}, |
| {NULL} |
| }; |
| |
| u_option_entry_t test_options[] = { |
| {"from-file", 'f', U_OPTION_ARG_STRING, &test_case, |
| "Send request from file", "<file name>"}, |
| {"print-request", 'R', U_OPTION_ARG_NONE, &dump_request, |
| "print request on stdout", NULL}, |
| {"step", 'S', U_OPTION_ARG_NONE, &step, |
| "Do not perform multiple operations (do not pull data when enumerating)", |
| NULL}, |
| //{ "print-response", 'N', 0, G_OPTION_ARG_NONE, &dump_response, "print all responses to stdout", NULL}, |
| {NULL} |
| }; |
| |
| u_option_group_t *enum_group; |
| u_option_group_t *event_group; |
| u_option_group_t *test_group; |
| u_option_group_t *cim_group; |
| u_option_group_t *req_flag_group; |
| |
| u_option_context_t *opt_ctx; |
| opt_ctx = u_option_context_new("<action> <Resource Uri>"); |
| enum_group = u_option_group_new("enumeration", "Enumeration", |
| "Enumeration Options"); |
| test_group = u_option_group_new("tests", "Tests", "Test Cases"); |
| cim_group = u_option_group_new("cim", "CIM", "CIM Options"); |
| event_group = u_option_group_new("event", "Event subscription", "Subscription Options"); |
| req_flag_group = |
| u_option_group_new("flags", "Flags", "Request Flags"); |
| |
| u_option_group_add_entries(enum_group, enum_options); |
| u_option_group_add_entries(test_group, test_options); |
| u_option_group_add_entries(cim_group, cim_options); |
| u_option_group_add_entries(req_flag_group, request_options); |
| u_option_group_add_entries(event_group, event_options); |
| |
| u_option_context_set_ignore_unknown_options(opt_ctx, FALSE); |
| u_option_context_add_main_entries(opt_ctx, options, "wsman"); |
| u_option_context_add_group(opt_ctx, enum_group); |
| u_option_context_add_group(opt_ctx, test_group); |
| u_option_context_add_group(opt_ctx, cim_group); |
| u_option_context_add_group(opt_ctx, req_flag_group); |
| u_option_context_add_group(opt_ctx, event_group); |
| |
| retval = u_option_context_parse(opt_ctx, &argc, &argv, &error); |
| u_option_context_free(opt_ctx); |
| |
| if (retval == 0) { |
| if (error) { |
| if (error->message) |
| fprintf(stderr, "%s\n", error->message); |
| u_error_free(error); |
| } |
| else { |
| fprintf(stderr, "Can't parse context information\n"); |
| } |
| return FALSE; |
| } |
| |
| if (my_version) { |
| fprintf(stdout, PACKAGE_STRING " (" PACKAGE_BUILDTS ")\n\n"); |
| exit(0); |
| } |
| |
| if (argc > 2) { |
| _action = argv[1]; |
| resource_uri_opt = argv[2]; |
| } else { |
| if (argv[1] && (strcmp(argv[1], "identify") == 0 || |
| strcmp(argv[1], "test") == 0 || |
| strcmp(argv[1], "anonid") == 0 || |
| strcmp(argv[1], "unsubscribe") == 0 || |
| strcmp(argv[1], "renew") == 0)) { |
| _action = argv[1]; |
| } else { |
| fprintf(stderr, |
| "Error: operation can not be completed." |
| " Action or/and Resource Uri missing.\n"); |
| return FALSE; |
| } |
| } |
| u_error_free(error); |
| |
| // set default options |
| if (server_port == 0) { |
| server_port = cainfo ? 5986 : 5985; |
| } |
| if (url_path == NULL) { |
| if (strcmp(argv[1], "anonid") == 0) |
| url_path = "/wsman-anon/identify"; |
| else |
| url_path = "/wsman"; |
| } |
| return TRUE; |
| } |
| |
| |
| static void wsman_output(WsManClient * cl, WsXmlDocH doc) |
| { |
| FILE *f = stdout; |
| const char *filename = output_file; |
| const char *badxml = NULL; |
| WS_LASTERR_Code err; |
| |
| err = wsmc_get_last_error(cl); |
| if (err != WS_LASTERR_OK) { |
| return; |
| } |
| if (!doc) { |
| error("doc with NULL content"); |
| badxml = (char*)u_buf_ptr(cl->connection->response); |
| if ((-1 == debug_level) || (NULL == badxml)) { |
| goto error1; |
| } |
| } |
| if (filename) { |
| f = fopen(filename, "w"); |
| if (f == NULL) { |
| error("Could not open file for writing"); |
| goto error1; |
| } |
| } |
| if (NULL != badxml) { |
| fprintf(f, "%s", badxml); // on debug mode, output the bad xml |
| } else { |
| ws_xml_dump_node_tree(f, ws_xml_get_doc_root(doc)); |
| } |
| if (f != stdout) { |
| fclose(f); |
| } |
| |
| error1: |
| return; |
| } |
| |
| /* |
| * output pull results to separate files (appending "-<index>" to the name) |
| * |
| */ |
| static void wsman_output_pull(WsManClient * cl, WsXmlDocH doc, int index) |
| { |
| char *strbuf, *origfile = output_file; |
| int count; |
| |
| if (output_file) { |
| count = strlen(output_file) + 16; |
| strbuf = (char*)calloc(count, 1); |
| snprintf(strbuf, count, "%s-%u.xml", output_file, index); |
| output_file = strbuf; |
| } |
| wsman_output(cl, doc); |
| if (origfile) { |
| output_file = origfile; |
| free(strbuf); |
| } |
| } |
| |
| static void initialize_logging(void) |
| { |
| debug_add_handler(wsman_debug_message_handler, DEBUG_LEVEL_ALWAYS, |
| NULL); |
| } |
| |
| |
| |
| static void |
| request_usr_pwd( WsManClient *client, wsman_auth_type_t auth, |
| char **username, |
| char **password) |
| { |
| char *pw; |
| char user[21]; |
| char *p; |
| |
| fprintf(stdout,"Authentication failed, please retry\n"); |
| /* |
| fprintf(stdout, "%s authentication is used\n", |
| wsmc_transport_get_auth_name( auth)); |
| */ |
| printf("User name: "); |
| fflush(stdout); |
| if ( (p = fgets(user, 20, stdin) ) != NULL ) |
| { |
| |
| if (strchr(user, '\n')) |
| (*(strchr(user, '\n'))) = '\0'; |
| *username = u_strdup_printf ("%s", user); |
| } else { |
| *username = NULL; |
| } |
| |
| pw = (char *)getpass("Password: "); |
| *password = u_strdup_printf ("%s", pw); |
| } |
| |
| |
| |
| static hash_t *wsman_options_get_properties(void) |
| { |
| int c = 0; |
| hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, 0); |
| |
| while (properties != NULL && properties[c] != NULL) { |
| char *cc[3] = { NULL, NULL, NULL }; |
| u_tokenize1(cc, 2, properties[c], '='); |
| if (!hash_lookup(h, cc[0])) { |
| if (!hash_alloc_insert(h, cc[0], cc[1])) { |
| debug("hash_alloc_insert failed"); |
| } |
| } else { |
| warn("duplicate not added to hash"); |
| } |
| |
| c++; |
| } |
| return h; |
| } |
| |
| |
| static int wsman_options_get_delivery_mode(void) |
| { |
| int mode = 0; |
| int i; |
| for (i = 0; delivery_mode[i].action != NULL; i++) { |
| if (strcmp(delivery_mode[i].action, event_delivery_mode) == 0) { |
| mode = delivery_mode[i].value; |
| break; |
| } |
| } |
| return mode; |
| } |
| |
| static int wsman_options_get_delivery_sec_mode(void) |
| { |
| int mode = 0; |
| int i; |
| for (i = 0; delivery_sec_mode[i].action != NULL; i++) { |
| if (strcmp(delivery_sec_mode[i].action, event_delivery_sec_mode) == 0) { |
| mode = delivery_sec_mode[i].value; |
| break; |
| } |
| } |
| return mode; |
| } |
| |
| |
| static int wsman_read_client_config(dictionary * ini) |
| { |
| if (iniparser_find_entry(ini, "client")) { |
| agent = iniparser_getstr(ini, "client:agent"); |
| server_port = server_port ? |
| server_port : iniparser_getint(ini, "client:port", 5985); |
| authentication_method = authentication_method ? |
| authentication_method : |
| iniparser_getstr(ini, "client:authentication_method"); |
| } else { |
| return 0; |
| } |
| return 1; |
| } |
| |
| static void free_include_result_property(char **resultProps) |
| { |
| if (NULL != resultProps) { |
| char **tmp = resultProps; |
| while (*tmp != NULL) { // iterate until list terminator |
| u_free(*tmp); |
| tmp++; |
| } |
| u_free(resultProps); |
| } |
| } |
| |
| static char ** get_include_result_property(int *propNum) |
| { |
| char **resultProps = NULL; |
| char *tok, *val, *copy; |
| int idx = 0; |
| |
| *propNum = 0; |
| if (NULL != enum_context) { |
| copy = u_strdup(enum_context); |
| for (tok = copy ; NULL != tok ; (*propNum)++, tok = strchr(tok, ',')) { // get count |
| tok++; |
| } |
| resultProps = (char **)u_calloc((*propNum + 1), sizeof(char *)); // 1 more for list terminator |
| val = copy; |
| while (val) { |
| tok = strchr(val, ','); |
| if (NULL != tok) { |
| *tok++ = '\0'; |
| } |
| resultProps[idx++] = u_strdup(val); |
| val = tok; |
| } |
| resultProps[idx] = NULL; // list terminator |
| u_free(copy); |
| } |
| return resultProps; |
| } |
| |
| int main(int argc, char **argv) |
| { |
| int retVal = 0; |
| int op; |
| char *filename; |
| dictionary *ini = NULL; |
| WsManClient *cl; |
| WsXmlDocH doc; |
| char *enumContext = NULL; |
| WsXmlDocH rqstDoc; |
| client_opt_t *options; |
| WsXmlDocH enum_response; |
| WsXmlDocH resource = NULL; |
| char *enumeration_mode, *binding_enumeration_mode, |
| *resource_uri_with_selectors; |
| char *resource_uri = NULL; |
| char subscontext[512]; |
| filter_t *filter = NULL; |
| |
| /* read credentials from environment */ |
| username = getenv("WSMAN_USER"); |
| password = getenv("WSMAN_PASS"); |
| event_username = getenv("WSMAN_EVENT_USER"); |
| event_password = getenv("WSMAN_EVENT_PASS"); |
| |
| /* parse command line options |
| might overwrite environment credentials */ |
| |
| if (!wsman_parse_options(argc, argv)) { |
| exit(EXIT_FAILURE); |
| } |
| |
| filename = (char *) config_file; |
| |
| if (filename) { |
| ini = iniparser_new(filename); |
| if (ini == NULL) { |
| fprintf(stderr, "cannot parse file [%s]", |
| filename); |
| exit(EXIT_FAILURE); |
| } else if (!wsman_read_client_config(ini)) { |
| fprintf(stderr, "Configuration file not found\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| initialize_logging(); |
| // wsmc_transport_init(NULL); |
| options = wsmc_options_init(); |
| |
| debug("Certificate: %s", cainfo); |
| |
| if (endpoint) { |
| cl = wsmc_create_from_uri(endpoint); |
| } else { |
| cl = wsmc_create(server, |
| server_port, |
| url_path, |
| cainfo ? "https" : "http", |
| username, |
| password); |
| } |
| |
| if (non_interactive == 0) { |
| wsmc_transport_set_auth_request_func(cl , &request_usr_pwd ); |
| } |
| |
| if (cl == NULL) { |
| error("Null Client"); |
| exit(EXIT_FAILURE); |
| } |
| // transport options |
| wsman_transport_set_auth_method(cl, authentication_method); |
| if (proxy) { |
| wsman_transport_set_proxy(cl, proxy); |
| if (proxy_upwd) { |
| wsman_transport_set_proxyauth(cl, proxy_upwd); |
| } |
| } |
| |
| if (cainfo) { |
| wsman_transport_set_cainfo(cl, cainfo); |
| } |
| if (cert) { |
| wsman_transport_set_cert(cl, cert); |
| if (!cainfo) |
| fprintf(stderr, "Warning: --cacert not set to enable SSL operation\n"); |
| } |
| if (sslkey) { |
| wsman_transport_set_key(cl, sslkey); |
| if (!cainfo) |
| fprintf(stderr, "Warning: --cacert not set to enable SSL operation\n"); |
| } |
| wsman_transport_set_verify_peer(cl, !noverify_peer); |
| wsman_transport_set_verify_host(cl, !noverify_host); |
| wsman_transport_set_timeout(cl, transport_timeout); |
| |
| // library options |
| wsman_debug_set_level(debug_level); |
| /* |
| * Setup Resource URI and Selectors |
| */ |
| resource_uri_with_selectors = resource_uri_opt; |
| if (resource_uri_with_selectors && |
| strcmp(resource_uri_with_selectors,CIM_ALL_AVAILABLE_CLASSES) != 0) { |
| wsmc_set_options_from_uri(resource_uri_with_selectors, |
| options); |
| wsmc_remove_query_string(resource_uri_with_selectors, |
| &resource_uri); |
| } else if (resource_uri_with_selectors) { |
| wsmc_remove_query_string(resource_uri_with_selectors, |
| &resource_uri); |
| } |
| op = wsman_options_get_action(); |
| if (encoding) { |
| wsmc_set_encoding(cl, encoding); |
| } |
| if (dump_request) { |
| wsmc_set_action_option(options, FLAG_DUMP_REQUEST); |
| } |
| if (max_envelope_size) { |
| options->max_envelope_size = max_envelope_size; |
| } |
| if (operation_timeout) { |
| options->timeout = operation_timeout; |
| } |
| if (fragment) { |
| options->fragment = fragment; |
| } |
| |
| options->properties = wsman_options_get_properties(); |
| options->cim_ns = cim_namespace; |
| if (cim_extensions) { |
| wsmc_set_action_option(options, FLAG_CIM_EXTENSIONS); |
| } |
| |
| switch (op) { |
| case WSMAN_ACTION_TEST: |
| rqstDoc = wsmc_read_file(input, wsmc_get_encoding(cl), 0); |
| wsman_send_request(cl, rqstDoc); |
| doc = wsmc_build_envelope_from_response(cl); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_ANON_IDENTIFY: |
| case WSMAN_ACTION_IDENTIFY: |
| doc = wsmc_action_identify(cl, options); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_CUSTOM: |
| if (input) { |
| resource = wsmc_read_file(input, wsmc_get_encoding(cl), 0); |
| } |
| doc = wsmc_action_invoke(cl, resource_uri, options, |
| invoke_method, |
| resource); |
| ws_xml_destroy_doc(resource); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_TRANSFER_DELETE: |
| doc = wsmc_action_delete(cl, resource_uri, options); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| |
| case WSMAN_ACTION_TRANSFER_CREATE: |
| if (input) { |
| resource = wsmc_read_file(input, "UTF-8", 0); |
| doc = |
| wsmc_action_create(cl, resource_uri, options, |
| resource); |
| ws_xml_destroy_doc(resource); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| } else { |
| fprintf(stderr, "Missing resource data\n"); |
| } |
| break; |
| case WSMAN_ACTION_TRANSFER_PUT: |
| if (input) { |
| printf("input file provided\n"); |
| resource = wsmc_read_file(input, wsmc_get_encoding(cl), 0); |
| doc = wsmc_action_put(cl, resource_uri, options, |
| resource); |
| ws_xml_destroy_doc(resource); |
| } else { |
| doc = |
| wsmc_action_get_and_put(cl, resource_uri, |
| options); |
| } |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_TRANSFER_GET: |
| doc = wsmc_action_get(cl, resource_uri, options); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_PULL: |
| doc = wsmc_action_pull(cl, resource_uri, options, filter, enum_context); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_RELEASE: |
| doc = |
| wsmc_action_release(cl, resource_uri, options, |
| enum_context); |
| wsman_output(cl, doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| break; |
| case WSMAN_ACTION_ASSOCIATORS: |
| case WSMAN_ACTION_REFERENCES: |
| case WSMAN_ACTION_ENUMERATION: |
| if ( op == WSMAN_ACTION_REFERENCES || op == WSMAN_ACTION_ASSOCIATORS ) { |
| if (wsm_filter) { |
| epr_t *epr = epr_from_string(wsm_filter); |
| if(options->cim_ns) { |
| epr_add_selector_text(epr, CIM_NAMESPACE_SELECTOR, options->cim_ns); |
| } |
| if (epr) { |
| char **resultProperties = NULL; |
| const char *assocClass, *resultClass, *role, *resultRole; |
| int propNum; |
| |
| if (NULL != (assocClass = wsman_epr_selector_by_name(epr, "AssociationClassName"))) |
| epr_delete_selector(epr, "AssociationClassName"); |
| if (NULL != (resultClass = wsman_epr_selector_by_name(epr, "ResultClassName"))) |
| epr_delete_selector(epr, "ResultClassName"); |
| if (NULL != (role = wsman_epr_selector_by_name(epr, "Role"))) |
| epr_delete_selector(epr, "Role"); |
| if (NULL != (resultRole = wsman_epr_selector_by_name(epr, "ResultRole"))) |
| epr_delete_selector(epr, "ResultRole"); |
| resultProperties = get_include_result_property(&propNum); |
| |
| filter = filter_create_assoc(epr, (op == WSMAN_ACTION_ASSOCIATORS )?0:1, |
| assocClass, resultClass, role, resultRole, resultProperties, propNum); |
| |
| free_include_result_property(resultProperties); |
| } |
| } else { |
| error("Filter Requied"); |
| } |
| } else if (wsm_dialect && strcmp(wsm_dialect, WSM_SELECTOR_FILTER_DIALECT) == 0 ) { |
| // fixme: Namespace |
| if (wsm_filter) { |
| hscan_t hs; |
| hnode_t *hn; |
| hash_t *selfilter = NULL; |
| hash_t *selectors_new = NULL; |
| selector_entry *entry; |
| selectors_new = hash_create2(HASHCOUNT_T_MAX, 0, 0); |
| selfilter = u_parse_query(wsm_filter); |
| if (!selfilter) { |
| error("Filter parse error"); |
| break; |
| } |
| hash_scan_begin(&hs, selfilter); |
| while ((hn = hash_scan_next(&hs))) { |
| entry = u_malloc(sizeof(selector_entry)); |
| entry->type = 0; |
| entry->entry.text = (char *)hnode_get(hn); |
| hash_alloc_insert(selectors_new, hnode_getkey(hn), entry); |
| } |
| |
| if (hash_count(selectors_new) > 0 ) |
| filter = filter_create_selector(selectors_new); |
| } |
| } else { |
| filter = filter_create_simple(wsm_dialect, wsm_filter); |
| } |
| enumeration_mode = enum_mode; |
| binding_enumeration_mode = binding_enum_mode; |
| |
| if (enumeration_mode) { |
| if (strcmp(enumeration_mode, "epr") == 0) |
| wsmc_set_action_option(options, |
| FLAG_ENUMERATION_ENUM_EPR); |
| else if (strcmp(enumeration_mode, "objepr") == 0) |
| wsmc_set_action_option(options, |
| FLAG_ENUMERATION_ENUM_OBJ_AND_EPR); |
| } |
| if (binding_enumeration_mode) { |
| if (strcmp(binding_enumeration_mode, "include") == |
| 0) |
| wsmc_set_action_option(options, |
| FLAG_IncludeSubClassProperties); |
| else if (strcmp |
| (binding_enumeration_mode, |
| "exclude") == 0) |
| wsmc_set_action_option(options, |
| FLAG_ExcludeSubClassProperties); |
| else if (strcmp(binding_enumeration_mode, "none") |
| == 0) |
| wsmc_set_action_option(options, |
| FLAG_POLYMORPHISM_NONE); |
| } |
| if (enum_optimize) { |
| wsmc_set_action_option(options, |
| FLAG_ENUMERATION_OPTIMIZATION); |
| } |
| options->max_elements = enum_max_elements; |
| |
| if (enum_estimate) { |
| wsmc_set_action_option(options, |
| FLAG_ENUMERATION_COUNT_ESTIMATION); |
| } |
| enum_response = wsmc_action_enumerate(cl, resource_uri, options, filter); |
| wsman_output(cl, enum_response); |
| if (enum_response) { |
| if (!(wsmc_get_response_code(cl) == 200 || |
| wsmc_get_response_code(cl) == 400 || |
| wsmc_get_response_code(cl) == 500)) { |
| break; |
| } |
| enumContext = wsmc_get_enum_context(enum_response); |
| ws_xml_destroy_doc(enum_response); |
| } else { |
| break; |
| } |
| |
| if (step) |
| break; |
| |
| int index = 0; |
| while (enumContext != NULL && enumContext[0] != 0) { |
| |
| doc = wsmc_action_pull(cl, resource_uri, options, filter, |
| enumContext); |
| wsman_output_pull(cl, doc, ++index); |
| |
| if (wsmc_get_response_code(cl) != 200 |
| && wsmc_get_response_code(cl) != 400 |
| && wsmc_get_response_code(cl) != 500) { |
| break; |
| } |
| u_free(enumContext); |
| enumContext = wsmc_get_enum_context(doc); |
| if (doc) { |
| ws_xml_destroy_doc(doc); |
| } |
| } |
| u_free(enumContext); |
| break; |
| case WSMAN_ACTION_SUBSCRIBE: |
| if(event_sendbookmark) |
| wsmc_set_action_option(options, FLAG_EVENT_SENDBOOKMARK); |
| if(event_delivery_mode) |
| options->delivery_mode = wsman_options_get_delivery_mode(); |
| if(event_delivery_sec_mode) |
| options->delivery_sec_mode = wsman_options_get_delivery_sec_mode(); |
| if(event_username) |
| options->delivery_username = event_username; |
| if(event_password) |
| options->delivery_password = event_password; |
| if(event_thumbprint) |
| options->delivery_certificatethumbprint = event_thumbprint; |
| if(event_delivery_uri) |
| options->delivery_uri = event_delivery_uri; |
| if(event_heartbeat) |
| options->heartbeat_interval = event_heartbeat; |
| if(event_subscription_expire) |
| options->expires = event_subscription_expire; |
| if(wsm_filter) |
| filter = filter_create_simple(wsm_dialect, wsm_filter); |
| |
| if(event_reference_properties) |
| options->reference = event_reference_properties; |
| rqstDoc = wsmc_action_subscribe(cl, resource_uri, options, filter); |
| wsman_output(cl, rqstDoc); |
| if (rqstDoc) { |
| ws_xml_destroy_doc(rqstDoc); |
| } |
| break; |
| case WSMAN_ACTION_UNSUBSCRIBE: |
| snprintf(subscontext, 512 , "<wsa:ReferenceParameters xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" \ |
| xmlns:wse=\"http://schemas.xmlsoap.org/ws/2004/08/eventing\"><wse:Identifier>%s</wse:Identifier> \ |
| </wsa:ReferenceParameters>", event_subscription_id); |
| rqstDoc = wsmc_action_unsubscribe(cl, resource_uri, options, subscontext); |
| wsman_output(cl, rqstDoc); |
| if (rqstDoc) { |
| ws_xml_destroy_doc(rqstDoc); |
| } |
| break; |
| case WSMAN_ACTION_RENEW: |
| if(event_subscription_expire) |
| options->expires = event_subscription_expire; |
| snprintf(subscontext, 512 , "<wsa:ReferenceParameters xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" \ |
| xmlns:wse=\"http://schemas.xmlsoap.org/ws/2004/08/eventing\"><wse:Identifier>%s</wse:Identifier> \ |
| </wsa:ReferenceParameters>", event_subscription_id); |
| rqstDoc = wsmc_action_renew(cl, resource_uri, options, subscontext); |
| wsman_output(cl, rqstDoc); |
| if (rqstDoc) { |
| ws_xml_destroy_doc(rqstDoc); |
| } |
| break; |
| default: |
| fprintf(stderr, "Action not supported\n"); |
| retVal = 1; |
| } |
| |
| |
| if (wsmc_get_response_code(cl) != 200) { |
| fprintf(stderr, "Connection failed. response code = %ld\n", |
| wsmc_get_response_code(cl)); |
| if (wsmc_get_fault_string(cl)) { |
| fprintf(stderr, "%s\n", |
| wsmc_get_fault_string(cl)); |
| } |
| retVal = 1; |
| } |
| wsmc_options_destroy(options); |
| filter_destroy(filter); |
| wsmc_transport_fini(cl); |
| wsmc_release(cl); |
| if (ini) { |
| iniparser_free(ini); |
| } |
| #ifdef DEBUG_VERBOSE |
| printf(" ****** Transfer Time = %ull usecs ******\n", |
| get_transfer_time()); |
| #endif |
| return retVal; |
| |
| } |