1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/* 2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Hotspot 2.0 SPP client 36cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt * Copyright (c) 2012-2014, Qualcomm Atheros, Inc. 4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * 5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license. 6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details. 7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h" 10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include <sys/stat.h> 11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h" 13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "browser.h" 14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wpa_ctrl.h" 15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wpa_helpers.h" 16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "xml-utils.h" 17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "http-utils.h" 18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "utils/base64.h" 19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "crypto/crypto.h" 20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "crypto/sha256.h" 21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "osu_client.h" 22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 24af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtextern const char *spp_xsd_fname; 25af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int hs20_spp_update_response(struct hs20_osu_client *ctx, 27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *spp_status, 29d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *error_code); 30d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void hs20_policy_update_complete( 31d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct hs20_osu_client *ctx, const char *pps_fname); 32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic char * get_spp_attr_value(struct xml_node_ctx *ctx, xml_node_t *node, 35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *attr_name) 36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return xml_node_get_attr_value_ns(ctx, node, SPP_NS_URI, attr_name); 38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int hs20_spp_validate(struct hs20_osu_client *ctx, xml_node_t *node, 42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *expected_name) 43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct xml_node_ctx *xctx = ctx->xml; 45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *name; 46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *err; 47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!xml_node_is_element(xctx, node)) 50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = xml_node_get_localname(xctx, node); 53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (name == NULL) 54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcmp(expected_name, name) != 0) { 57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unexpected SOAP method name '%s' (expected '%s')", 58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name, expected_name); 59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Unexpected SOAP method name '%s' (expected '%s')", 60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name, expected_name); 61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 64af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ret = xml_validate(xctx, node, spp_xsd_fname, &err); 65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret < 0) { 66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "XML schema validation error(s)\n%s", err); 67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "SPP XML schema validation failed"); 68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(err); 69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_mo_container(struct xml_node_ctx *ctx, xml_namespace_t *ns, 75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *parent, const char *urn, 76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *fname) 77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node; 79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *fnode, *tnds; 80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *str; 81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 82b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt errno = 0; 83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fnode = node_from_file(ctx, fname); 84b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt if (!fnode) { 85b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt wpa_printf(MSG_ERROR, 86b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt "Failed to create XML node from file: %s, possible error: %s", 87b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt fname, strerror(errno)); 88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 89b1e52102c211357f585e9ff6d54501e90254326eDmitry Shmidt } 90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tnds = mo_to_tnds(ctx, fnode, 0, urn, "syncml:dmddf1.2"); 91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx, fnode); 92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!tnds) 93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt str = xml_node_to_str(ctx, tnds); 96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx, tnds); 97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (str == NULL) 98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = xml_node_create_text(ctx, parent, ns, "moContainer", str); 101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node) 102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx, node, ns, "moURN", urn); 103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(str); 104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_spp_post_dev_data(struct hs20_osu_client *ctx, 108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_namespace_t **ret_ns, 109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *reason) 111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_namespace_t *ns; 113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *spp_node; 114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Building sppPostDevData requestReason='%s'", 116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt reason); 117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_node = xml_node_create_root(ctx->xml, SPP_NS_URI, "spp", &ns, 118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "sppPostDevData"); 119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (spp_node == NULL) 120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret_ns) 122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *ret_ns = ns; 123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, ns, "sppVersion", "1.0"); 125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, NULL, "requestReason", reason); 126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (session_id) 127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, ns, "sessionID", 128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt session_id); 129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, NULL, "redirectURI", 130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "http://localhost:12345/"); 131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_create_text(ctx->xml, spp_node, ns, "supportedSPPVersions", 133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "1.0"); 134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_create_text(ctx->xml, spp_node, ns, "supportedMOList", 135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt URN_HS20_PPS " " URN_OMA_DM_DEVINFO " " 136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt URN_OMA_DM_DEVDETAIL " " URN_HS20_DEVDETAIL_EXT); 137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_mo_container(ctx->xml, ns, spp_node, URN_OMA_DM_DEVINFO, 139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "devinfo.xml"); 140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_mo_container(ctx->xml, ns, spp_node, URN_OMA_DM_DEVDETAIL, 141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "devdetail.xml"); 142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return spp_node; 144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int process_update_node(struct hs20_osu_client *ctx, xml_node_t *pps, 148d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *update) 149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node, *parent, *tnds, *unode; 151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *str; 152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *name; 153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *uri, *pos; 154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *cdata, *cdata_end; 155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt size_t fqdn_len; 156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Processing updateNode"); 158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "updateNode", update); 159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = get_spp_attr_value(ctx->xml, update, "managementTreeURI"); 161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (uri == NULL) { 162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No managementTreeURI present"); 163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "managementTreeUri: '%s'", uri); 166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = os_strrchr(uri, '/'); 168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (name == NULL) { 169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unexpected URI"); 170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name++; 174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Update interior node: '%s'", name); 175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt str = xml_node_get_text(ctx->xml, update); 177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (str == NULL) { 178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not extract MO text"); 179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "[hs20] nodeContainer text: '%s'", str); 183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cdata = strstr(str, "<![CDATA["); 184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cdata_end = strstr(str, "]]>"); 185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (cdata && cdata_end && cdata_end > cdata && 186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cdata < strstr(str, "MgmtTree") && 187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cdata_end > strstr(str, "/MgmtTree")) { 188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *tmp; 189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "[hs20] Removing extra CDATA container"); 190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tmp = strdup(cdata + 9); 191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (tmp) { 192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cdata_end = strstr(tmp, "]]>"); 193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (cdata_end) 194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *cdata_end = '\0'; 195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_DEBUG, "[hs20] nodeContainer text with CDATA container removed: '%s'", 196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tmp); 197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tnds = xml_node_from_buf(ctx->xml, tmp); 198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(tmp); 199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else 200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tnds = NULL; 201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else 202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt tnds = xml_node_from_buf(ctx->xml, str); 203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_text_free(ctx->xml, str); 204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (tnds == NULL) { 205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] Could not parse nodeContainer text"); 206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unode = tnds_to_mo(ctx->xml, tnds); 211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, tnds); 212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (unode == NULL) { 213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] Could not parse nodeContainer TNDS text"); 214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "Parsed TNDS", unode); 219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (get_node_uri(ctx->xml, unode, name) == NULL) { 221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] %s node not found", name); 222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 225d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os_strncasecmp(uri, "./Wi-Fi/", 8) != 0) { 228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Do not allow update outside ./Wi-Fi"); 229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos = uri + 8; 234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->fqdn == NULL) { 236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "FQDN not known"); 237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt fqdn_len = os_strlen(ctx->fqdn); 242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os_strncasecmp(pos, ctx->fqdn, fqdn_len) != 0 || 243d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos[fqdn_len] != '/') { 244d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Do not allow update outside ./Wi-Fi/%s", 245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->fqdn); 246d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos += fqdn_len + 1; 251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (os_strncasecmp(pos, "PerProviderSubscription/", 24) != 0) { 253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Do not allow update outside ./Wi-Fi/%s/PerProviderSubscription", 254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->fqdn); 255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos += 24; 260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Update command for PPS node %s", pos); 262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 263d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = get_node(ctx->xml, pps, pos); 264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node) { 265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parent = xml_node_get_parent(ctx->xml, node); 266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_detach(ctx->xml, node); 267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Replace '%s' node", name); 268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *pos2; 270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pos2 = os_strrchr(pos, '/'); 271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (pos2 == NULL) { 272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parent = pps; 273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *pos2 = '\0'; 275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt parent = get_node(ctx->xml, pps, pos); 276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (parent == NULL) { 278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not find parent %s", pos); 279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, unode); 280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Add '%s' node", name); 284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_child(ctx->xml, parent, unode); 286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 291d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 293d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int update_pps(struct hs20_osu_client *ctx, xml_node_t *update, 294d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname, xml_node_t *pps) 295d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 296d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Updating PPS based on updateNode element(s)"); 297d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_sibling(ctx->xml, update) { 298d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_check(ctx->xml, update); 299d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (process_update_node(ctx, pps, update) < 0) 300d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 301d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 302d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 303d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return update_pps_file(ctx, pps_fname, pps); 304d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 305d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 306d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 307d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void hs20_sub_rem_complete(struct hs20_osu_client *ctx, 308d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname) 309d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 310d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* 311d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Update wpa_supplicant credentials and reconnect using updated 312d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * information. 313d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 314d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Updating wpa_supplicant credentials"); 315d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cmd_set_pps(ctx, pps_fname); 316d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 317d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ctx->no_reconnect) 318d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return; 319d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 320d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Requesting reconnection with updated configuration"); 321d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0) 322d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to request wpa_supplicant to reconnect"); 323d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 324d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 325d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 326d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * hs20_spp_upload_mo(struct hs20_osu_client *ctx, 327d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *cmd, 328d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 329d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname) 330d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 331d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_namespace_t *ns; 332d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node, *ret_node; 333d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *urn; 334d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 335d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt urn = get_spp_attr_value(ctx->xml, cmd, "moURN"); 336d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!urn) { 337d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No URN included"); 338d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 339d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 340d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Upload MO request - URN=%s", urn); 341d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(urn, URN_HS20_PPS) != 0) { 342d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unsupported moURN"); 343d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, urn); 344d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 345d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 346d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, urn); 347d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 348d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!pps_fname) { 349d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "PPS file name no known"); 350d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 351d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 352d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 353d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_post_dev_data(ctx, &ns, session_id, 354d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "MO upload"); 355d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 356d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 357d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_mo_container(ctx->xml, ns, node, URN_HS20_PPS, pps_fname); 358d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 359d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 360d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret_node == NULL) 361d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 362d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 363d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "Received response to MO upload", ret_node); 364d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 365d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_spp_validate(ctx, ret_node, "sppPostDevDataResponse") < 0) { 366d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP validation failed"); 367d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 368d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 369d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 370d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 371d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret_node; 372d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 373d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 374d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 375d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int hs20_add_mo(struct hs20_osu_client *ctx, xml_node_t *add_mo, 376d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *fname, size_t fname_len) 377d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 378d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *uri, *urn; 379d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 380d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 381d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "Received addMO", add_mo); 382d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 383d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt urn = get_spp_attr_value(ctx->xml, add_mo, "moURN"); 384d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (urn == NULL) { 385d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] No moURN in addMO"); 386d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 387d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 388d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "addMO - moURN: '%s'", urn); 389d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(urn, URN_HS20_PPS) != 0) { 390d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] Unsupported MO in addMO"); 391d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, urn); 392d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 393d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 394d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, urn); 395d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 396d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = get_spp_attr_value(ctx->xml, add_mo, "managementTreeURI"); 397d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (uri == NULL) { 398d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] No managementTreeURI in addMO"); 399d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 400d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 401d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "addMO - managementTreeURI: '%s'", uri); 402d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 403d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = hs20_add_pps_mo(ctx, uri, add_mo, fname, fname_len); 404d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, uri); 405d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 406d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 407d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 408d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 409d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int process_spp_user_input_response(struct hs20_osu_client *ctx, 410d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 411d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *add_mo) 412d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 413d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 414d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char fname[300]; 415d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 416d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "addMO", add_mo); 417d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 418d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Subscription registration completed"); 419d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 420d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_add_mo(ctx, add_mo, fname, sizeof(fname)) < 0) { 421d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not add MO"); 422d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = hs20_spp_update_response( 423d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx, session_id, 424d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Error occurred", 425d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "MO addition or update failed"); 426d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 427d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 428d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 429d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = hs20_spp_update_response(ctx, session_id, "OK", NULL); 430d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret == 0) 431d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hs20_sub_rem_complete(ctx, fname); 432d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 433d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 434d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 435d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 436d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 437d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * hs20_spp_user_input_completed(struct hs20_osu_client *ctx, 438d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id) 439d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 440d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node, *ret_node; 441d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 442d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_post_dev_data(ctx, NULL, session_id, 443d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "User input completed"); 444d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 445d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 446d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 447d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 448d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ret_node) { 449d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (soap_reinit_client(ctx->http) < 0) 450d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 451d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Try to finish with re-opened connection"); 452d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_post_dev_data(ctx, NULL, session_id, 453d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "User input completed"); 454d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 455d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 456d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 457d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret_node == NULL) 458d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 459d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Continue with new connection"); 460d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 461d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 462d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_spp_validate(ctx, ret_node, "sppPostDevDataResponse") < 0) { 463d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP validation failed"); 464d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 465d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 466d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 467d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 468d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret_node; 469d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 470d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 471d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 472d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * hs20_spp_get_certificate(struct hs20_osu_client *ctx, 473d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *cmd, 474d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 475d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname) 476d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 477d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_namespace_t *ns; 478d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node, *ret_node; 479d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 480d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 481d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Client certificate enrollment"); 482d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 483d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = osu_get_certificate(ctx, cmd); 484d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res < 0) 485d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "EST simpleEnroll failed"); 486d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 487d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_post_dev_data(ctx, &ns, session_id, 488d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res == 0 ? 489d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Certificate enrollment completed" : 490d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Certificate enrollment failed"); 491d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 492d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 493d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 494d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 495d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret_node == NULL) 496d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 497d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 498d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "Received response to certificate enrollment " 499d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "completed", ret_node); 500d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 501d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_spp_validate(ctx, ret_node, "sppPostDevDataResponse") < 0) { 502d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP validation failed"); 503d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 504d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 505d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 506d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 507d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret_node; 508d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 509d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 510d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 511d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int hs20_spp_exec(struct hs20_osu_client *ctx, xml_node_t *exec, 512d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, const char *pps_fname, 513d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *pps, xml_node_t **ret_node) 514d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 515d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *cmd; 516d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *name; 517d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *uri; 518d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *id = strdup(session_id); 519d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 520d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (id == NULL) 521d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 522d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 523d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *ret_node = NULL; 524d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 525d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "exec", exec); 526d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 527d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_child(ctx->xml, cmd, exec) { 528d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_check(ctx->xml, cmd); 529d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt break; 530d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 531d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!cmd) { 532d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "exec command element not found (cmd=%p)", 533d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cmd); 534d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 535d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 536d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 537d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 538d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = xml_node_get_localname(ctx->xml, cmd); 539d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 540d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(name, "launchBrowserToURI") == 0) { 541d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 542d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt uri = xml_node_get_text(ctx->xml, cmd); 543d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!uri) { 544d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No URI found"); 545d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 546d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 547d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 548d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Launch browser to URI '%s'", uri); 549d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Launch browser to URI '%s'", uri); 550d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = hs20_web_browser(uri); 551d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_text_free(ctx->xml, uri); 552d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res > 0) { 553d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "User response in browser completed successfully - sessionid='%s'", 554d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt id); 555d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "User response in browser completed successfully"); 556d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *ret_node = hs20_spp_user_input_completed(ctx, id); 557d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 558d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return *ret_node ? 0 : -1; 559d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 560d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Failed to receive user response"); 561d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Failed to receive user response"); 562d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hs20_spp_update_response( 563d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx, id, "Error occurred", "Other"); 564d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 565d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 566d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 567d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 568d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 569d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 570d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(name, "uploadMO") == 0) { 571d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (pps_fname == NULL) 572d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 573d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *ret_node = hs20_spp_upload_mo(ctx, cmd, id, 574d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pps_fname); 575d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 576d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return *ret_node ? 0 : -1; 577d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 578d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 579d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(name, "getCertificate") == 0) { 580d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *ret_node = hs20_spp_get_certificate(ctx, cmd, id, 581d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pps_fname); 582d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 583d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return *ret_node ? 0 : -1; 584d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 585d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 586d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unsupported exec command: '%s'", name); 587d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt free(id); 588d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 589d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 590d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 591d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 592d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtenum spp_post_dev_data_use { 593d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SPP_SUBSCRIPTION_REMEDIATION, 594d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SPP_POLICY_UPDATE, 595d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt SPP_SUBSCRIPTION_REGISTRATION, 596d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}; 597d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 598d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void process_spp_post_dev_data_response( 599d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt struct hs20_osu_client *ctx, 600d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt enum spp_post_dev_data_use use, xml_node_t *node, 601d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname, xml_node_t *pps) 602d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 603d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *child; 604d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *status = NULL; 605d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *update = NULL, *exec = NULL, *add_mo = NULL, *no_mo = NULL; 606d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *session_id = NULL; 607d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 608d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "sppPostDevDataResponse node", node); 609d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 610d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status = get_spp_attr_value(ctx->xml, node, "sppStatus"); 611d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (status == NULL) { 612d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No sppStatus attribute"); 613d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 614d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 615d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Received sppPostDevDataResponse sppStatus='%s'", 616d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status); 617d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 618d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt session_id = get_spp_attr_value(ctx->xml, node, "sessionID"); 619d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (session_id == NULL) { 620d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No sessionID attribute"); 621d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 622d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 623d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 624d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] sppPostDevDataResponse - sppStatus: '%s' sessionID: '%s'", 625d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status, session_id); 626d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 627d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_child(ctx->xml, child, node) { 628d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *name; 629d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_for_each_check(ctx->xml, child); 630d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "child", child); 631d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt name = xml_node_get_localname(ctx->xml, child); 632d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "localname: '%s'", name); 633d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!update && strcasecmp(name, "updateNode") == 0) 634d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt update = child; 635d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!exec && strcasecmp(name, "exec") == 0) 636d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt exec = child; 637d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!add_mo && strcasecmp(name, "addMO") == 0) 638d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt add_mo = child; 639d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!no_mo && strcasecmp(name, "noMOUpdate") == 0) 640d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt no_mo = child; 641d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 642d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 643d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (use == SPP_SUBSCRIPTION_REMEDIATION && 644d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt strcasecmp(status, 645d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Remediation complete, request sppUpdateResponse") == 0) 646d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt { 647d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res, ret; 648d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!update && !no_mo) { 649d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No updateNode or noMOUpdate element"); 650d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 651d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 652d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Subscription remediation completed"); 653d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = update_pps(ctx, update, pps_fname, pps); 654d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res < 0) 655d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Failed to update PPS MO"); 656d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = hs20_spp_update_response( 657d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx, session_id, 658d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res < 0 ? "Error occurred" : "OK", 659d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res < 0 ? "MO addition or update failed" : NULL); 660d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res == 0 && ret == 0) 661d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hs20_sub_rem_complete(ctx, pps_fname); 662d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 663d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 664d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 665d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (use == SPP_SUBSCRIPTION_REMEDIATION && 666d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt strcasecmp(status, "Exchange complete, release TLS connection") == 667d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 0) { 668d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!no_mo) { 669d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No noMOUpdate element"); 670d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 671d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 672d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Subscription remediation completed (no MO update)"); 673d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 674d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 675d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 676d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (use == SPP_POLICY_UPDATE && 677d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt strcasecmp(status, "Update complete, request sppUpdateResponse") == 678d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 0) { 679d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res, ret; 680d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Policy update received - update PPS"); 681d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = update_pps(ctx, update, pps_fname, pps); 682d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = hs20_spp_update_response( 683d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx, session_id, 684d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res < 0 ? "Error occurred" : "OK", 685d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res < 0 ? "MO addition or update failed" : NULL); 686d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res == 0 && ret == 0) 687d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt hs20_policy_update_complete(ctx, pps_fname); 688d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 689d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 690d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 691d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (use == SPP_SUBSCRIPTION_REGISTRATION && 692d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt strcasecmp(status, "Provisioning complete, request " 693d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "sppUpdateResponse") == 0) { 694d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!add_mo) { 695d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No addMO element - not sure what to do next"); 696d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 697d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 698d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt process_spp_user_input_response(ctx, session_id, add_mo); 699d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = NULL; 700d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 701d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 702d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 703d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(status, "No update available at this time") == 0) { 704d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No update available at this time"); 705d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 706d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 707d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 708d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(status, "OK") == 0) { 709d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int res; 710d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *ret; 711d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 712d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!exec) { 713d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No exec element - not sure what to do next"); 714d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 715d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 716d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt res = hs20_spp_exec(ctx, exec, session_id, 717d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pps_fname, pps, &ret); 718d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* xml_node_free(ctx->xml, node); */ 719d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = NULL; 720d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (res == 0 && ret) 721d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt process_spp_post_dev_data_response(ctx, use, 722d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret, pps_fname, pps); 723d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 724d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 725d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 726d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(status, "Error occurred") == 0) { 727d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *err; 728d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *code = NULL; 729d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt err = get_node(ctx->xml, node, "sppError"); 730d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (err) 731d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt code = xml_node_get_attr_value(ctx->xml, err, 732d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "errorCode"); 733d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Error occurred - errorCode=%s", 734d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt code ? code : "N/A"); 735d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, code); 736d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt goto out; 737d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 738d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 739d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, 740d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "[hs20] Unsupported sppPostDevDataResponse sppStatus '%s'", 741d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status); 742d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtout: 743d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, status); 744d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, session_id); 745d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, node); 746d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 747d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 748d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 749d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int spp_post_dev_data(struct hs20_osu_client *ctx, 750d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt enum spp_post_dev_data_use use, 751d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *reason, 752d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname, xml_node_t *pps) 753d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 754d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *payload; 755d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *ret_node; 756d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 757d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt payload = build_spp_post_dev_data(ctx, NULL, NULL, reason); 758d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (payload == NULL) 759d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 760d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 761d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, payload); 762d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ret_node) { 763d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *err = http_get_err(ctx->http); 764d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (err) { 765d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "HTTP error: %s", err); 766d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_result(ctx, "HTTP error: %s", err); 767d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } else { 768d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Failed to send SOAP message"); 769d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 770d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 771d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 772d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 773d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_spp_validate(ctx, ret_node, "sppPostDevDataResponse") < 0) { 774d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP validation failed"); 775d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 776d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 777d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 778d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 779d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt process_spp_post_dev_data_response(ctx, use, ret_node, 780d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pps_fname, pps); 781d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 782d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 783d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 784d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 785d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid spp_sub_rem(struct hs20_osu_client *ctx, const char *address, 7866cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt const char *pps_fname, 787d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_cert, const char *client_key, 788d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *cred_username, const char *cred_password, 789d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *pps) 790d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 791d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP subscription remediation"); 792d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "SPP subscription remediation"); 793d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 794d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->server_url); 795d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->server_url = os_strdup(address); 796d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 7976cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (soap_init_client(ctx->http, address, ctx->ca_fname, 798d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cred_username, cred_password, client_cert, 799d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt client_key) == 0) { 800d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REMEDIATION, 801d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Subscription remediation", pps_fname, pps); 802d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 803d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 804d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 805d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 806d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void hs20_policy_update_complete(struct hs20_osu_client *ctx, 807d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *pps_fname) 808d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 809d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Policy update completed"); 810d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 811d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt /* 812d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Update wpa_supplicant credentials and reconnect using updated 813d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * information. 814d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */ 815d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Updating wpa_supplicant credentials"); 816d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cmd_set_pps(ctx, pps_fname); 817d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 818d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Requesting reconnection with updated configuration"); 819d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0) 820d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to request wpa_supplicant to reconnect"); 821d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 822d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 823d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 824d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int process_spp_exchange_complete(struct hs20_osu_client *ctx, 825d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node) 826d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 827d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt char *status, *session_id; 828d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 829d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt debug_dump_node(ctx, "sppExchangeComplete", node); 830d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 831d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status = get_spp_attr_value(ctx->xml, node, "sppStatus"); 832d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (status == NULL) { 833d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No sppStatus attribute"); 834d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 835d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 836d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Received sppExchangeComplete sppStatus='%s'", 837d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status); 838d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 839d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt session_id = get_spp_attr_value(ctx->xml, node, "sessionID"); 840d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (session_id == NULL) { 841d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "No sessionID attribute"); 842d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, status); 843d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 844d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 845d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 846d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "[hs20] sppStatus: '%s' sessionID: '%s'", 847d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt status, session_id); 848d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, session_id); 849d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 850d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (strcasecmp(status, "Exchange complete, release TLS connection") == 851d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 0) { 852d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, status); 853d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return 0; 854d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 855d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 856d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Unexpected sppStatus '%s'", status); 857d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Unexpected sppStatus '%s'", status); 858d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_get_attr_value_free(ctx->xml, status); 859d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 860d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 861d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 862d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 863d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_spp_update_response(struct hs20_osu_client *ctx, 864d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 865d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *spp_status, 866d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *error_code) 867d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 868d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_namespace_t *ns; 869d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *spp_node, *node; 870d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 871d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_node = xml_node_create_root(ctx->xml, SPP_NS_URI, "spp", &ns, 872d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "sppUpdateResponse"); 873d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (spp_node == NULL) 874d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return NULL; 875d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 876d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, ns, "sppVersion", "1.0"); 877d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, ns, "sessionID", session_id); 878d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, spp_node, ns, "sppStatus", spp_status); 879d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 880d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (error_code) { 881d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = xml_node_create(ctx->xml, spp_node, ns, "sppError"); 882d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node) 883d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_add_attr(ctx->xml, node, NULL, "errorCode", 884d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt error_code); 885d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 886d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 887d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return spp_node; 888d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 889d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 890d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 891d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int hs20_spp_update_response(struct hs20_osu_client *ctx, 892d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *session_id, 893d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *spp_status, 894d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *error_code) 895d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 896d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *node, *ret_node; 897d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt int ret; 898d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 899d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "Building sppUpdateResponse sppStatus='%s' error_code='%s'", 900d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_status, error_code); 901d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_update_response(ctx, session_id, spp_status, 902d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt error_code); 903d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 904d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 905d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 906d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (!ret_node) { 907d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (soap_reinit_client(ctx->http) < 0) 908d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 909d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Try to finish with re-opened connection"); 910d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt node = build_spp_update_response(ctx, session_id, spp_status, 911d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt error_code); 912d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (node == NULL) 913d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 914d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret_node = soap_send_receive(ctx->http, node); 915d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (ret_node == NULL) 916d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 917d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Continue with new connection"); 918d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 919d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 920d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (hs20_spp_validate(ctx, ret_node, "sppExchangeComplete") < 0) { 921d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP validation failed"); 922d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 923d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 924d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 925d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 926d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ret = process_spp_exchange_complete(ctx, ret_node); 927d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_free(ctx->xml, ret_node); 928d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ret; 929d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 930d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 931d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 932d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid spp_pol_upd(struct hs20_osu_client *ctx, const char *address, 9336cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt const char *pps_fname, 934d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *client_cert, const char *client_key, 935d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt const char *cred_username, const char *cred_password, 936d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt xml_node_t *pps) 937d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 938d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SPP policy update"); 939d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt write_summary(ctx, "SPP policy update"); 940d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 941d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->server_url); 942d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->server_url = os_strdup(address); 943d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9446cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (soap_init_client(ctx->http, address, ctx->ca_fname, cred_username, 945d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt cred_password, client_cert, client_key) == 0) { 946d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_post_dev_data(ctx, SPP_POLICY_UPDATE, "Policy update", 947d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt pps_fname, pps); 948d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 949d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 950d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 951d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9526cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidtint cmd_prov(struct hs20_osu_client *ctx, const char *url) 953d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 954d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unlink("Cert/est_cert.der"); 955d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt unlink("Cert/est_cert.pem"); 956d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 957d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (url == NULL) { 958d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Invalid prov command (missing URL)"); 959d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 960d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 961d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 962af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt wpa_printf(MSG_INFO, 963af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt "Credential provisioning requested - URL: %s ca_fname: %s", 964af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt url, ctx->ca_fname ? ctx->ca_fname : "N/A"); 965d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 966d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->server_url); 967d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->server_url = os_strdup(url); 968d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9696cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (soap_init_client(ctx->http, url, ctx->ca_fname, NULL, NULL, NULL, 9706cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt NULL) < 0) 971d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 972d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REGISTRATION, 973d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Subscription registration", NULL, NULL); 974d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 975d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ctx->pps_cred_set ? 0 : -1; 976d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 977d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 978d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9796cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidtint cmd_sim_prov(struct hs20_osu_client *ctx, const char *url) 980d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{ 981d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (url == NULL) { 982d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Invalid prov command (missing URL)"); 983d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 984d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 985d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 986d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "SIM provisioning requested"); 987d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 988d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt os_free(ctx->server_url); 989d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt ctx->server_url = os_strdup(url); 990d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 991d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Wait for IP address before starting SIM provisioning"); 992d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 993d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt if (wait_ip_addr(ctx->ifname, 15) < 0) { 994d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt wpa_printf(MSG_INFO, "Could not get IP address for WLAN - try connection anyway"); 995d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt } 996d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 9976cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt if (soap_init_client(ctx->http, url, ctx->ca_fname, NULL, NULL, NULL, 9986cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt NULL) < 0) 999d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return -1; 1000d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REGISTRATION, 1001d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt "Subscription provisioning", NULL, NULL); 1002d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt 1003d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt return ctx->pps_cred_set ? 0 : -1; 1004d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt} 1005