static const char * wps_er_find_wfadevice(const char *data) { const char *tag, *tagname, *end; char *val; int found = 0; while (!found) { /* Find next <device> */ for (;;) { if (xml_next_tag(data, &tag, &tagname, &end)) return NULL; data = end; if (!os_strncasecmp(tagname, "device", 6) && *tag != '/' && (tagname[6] == '>' || !isgraph(tagname[6]))) { break; } } /* Check whether deviceType is WFADevice */ val = xml_get_first_item(data, "deviceType"); if (val == NULL) return NULL; wpa_printf(MSG_DEBUG, "WPS ER: Found deviceType '%s'", val); found = os_strcasecmp(val, "urn:schemas-wifialliance-org:" "device:WFADevice:1") == 0; os_free(val); } return data; }
/* A POST body looks something like (per upnp spec): * <?xml version="1.0"?> * <s:Envelope * xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" * s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> * <s:Body> * <u:actionName xmlns:u="urn:schemas-upnp-org:service:serviceType:v"> * <argumentName>in arg value</argumentName> * other in args and their values go here, if any * </u:actionName> * </s:Body> * </s:Envelope> * * where : * s: might be some other namespace name followed by colon * u: might be some other namespace name followed by colon * actionName will be replaced according to action requested * schema following actionName will be WFA scheme instead * argumentName will be actual argument name * (in arg value) will be actual argument value */ char * xml_get_first_item(const char *doc, const char *item) { const char *match = item; int match_len = os_strlen(item); const char *tag, *tagname, *end; char *value; /* * This is crude: ignore any possible tag name conflicts and go right * to the first tag of this name. This should be ok for the limited * domain of UPnP messages. */ for (;;) { if (xml_next_tag(doc, &tag, &tagname, &end)) return NULL; doc = end; if (!os_strncasecmp(tagname, match, match_len) && *tag != '/' && (tagname[match_len] == '>' || !isgraph(tagname[match_len]))) { break; } } end = doc; while (*end && *end != '<') end++; value = os_zalloc(1 + (end - doc)); if (value == NULL) return NULL; os_memcpy(value, doc, end - doc); return value; }
/** * Start parsing an XML stream by checking the encoding and version. */ int _xml_parser_init(xmlTextReaderPtr reader, const char *top_name, int *idx_version, int min_version, int max_version) { const char *name, *encoding; char *value; int type, ver; if (xml_next_tag(reader, "", &name, &type) < 0) return -1; if (strcmp(name, top_name)) { ltfsmsg(LTFS_ERR, "17017E", name); return -1; } /* reject this XML file if it isn't UTF-8 */ encoding = (const char *)xmlTextReaderConstEncoding(reader); if (! encoding || strcmp(encoding, "UTF-8")) { ltfsmsg(LTFS_ERR, "17018E", encoding); return -1; } /* check the version attribute of the top-level tag */ value = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "version"); if (! value) { ltfsmsg(LTFS_ERR, "17019E"); return -1; } if (_xml_parse_version(value, &ver) < 0) { ltfsmsg(LTFS_ERR, "17020E", value); return -LTFS_UNSUPPORTED_INDEX_VERSION; } if (ver < min_version || ver > max_version) { ltfsmsg(LTFS_ERR, "17021E", top_name, value); free(value); return -LTFS_UNSUPPORTED_INDEX_VERSION; } *idx_version = ver; /* * OSR * * This allocation must be freed with xmlFree * */ #ifndef HP_mingw_BUILD free(value); #else xmlFree(value); #endif return 0; }